#ifndef LLVM_PASSSUPPORT_H
#define LLVM_PASSSUPPORT_H
#include "Pass.h"
#include "llvm/InitializePasses.h"
#include "llvm/PassRegistry.h"
#include "llvm/Support/Atomic.h"
#include "llvm/Support/Valgrind.h"
#include <vector>
namespace llvm {
class TargetMachine;
class PassInfo {
public:
typedef Pass* (*NormalCtor_t)();
typedef Pass *(*TargetMachineCtor_t)(TargetMachine *);
private:
const char *const PassName; const char *const PassArgument; const void *PassID;
const bool IsCFGOnlyPass; const bool IsAnalysis; const bool IsAnalysisGroup; std::vector<const PassInfo*> ItfImpl;
NormalCtor_t NormalCtor;
TargetMachineCtor_t TargetMachineCtor;
public:
PassInfo(const char *name, const char *arg, const void *pi,
NormalCtor_t normal, bool isCFGOnly, bool is_analysis,
TargetMachineCtor_t machine = NULL)
: PassName(name), PassArgument(arg), PassID(pi),
IsCFGOnlyPass(isCFGOnly),
IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal),
TargetMachineCtor(machine) {}
PassInfo(const char *name, const void *pi)
: PassName(name), PassArgument(""), PassID(pi),
IsCFGOnlyPass(false),
IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(0),
TargetMachineCtor(0) {}
const char *getPassName() const { return PassName; }
const char *getPassArgument() const { return PassArgument; }
const void *getTypeInfo() const { return PassID; }
bool isPassID(const void *IDPtr) const {
return PassID == IDPtr;
}
bool isAnalysisGroup() const { return IsAnalysisGroup; }
bool isAnalysis() const { return IsAnalysis; }
bool isCFGOnlyPass() const { return IsCFGOnlyPass; }
NormalCtor_t getNormalCtor() const {
return NormalCtor;
}
void setNormalCtor(NormalCtor_t Ctor) {
NormalCtor = Ctor;
}
TargetMachineCtor_t getTargetMachineCtor() const { return TargetMachineCtor; }
void setTargetMachineCtor(TargetMachineCtor_t Ctor) {
TargetMachineCtor = Ctor;
}
Pass *createPass() const;
void addInterfaceImplemented(const PassInfo *ItfPI) {
ItfImpl.push_back(ItfPI);
}
const std::vector<const PassInfo*> &getInterfacesImplemented() const {
return ItfImpl;
}
private:
void operator=(const PassInfo &) LLVM_DELETED_FUNCTION;
PassInfo(const PassInfo &) LLVM_DELETED_FUNCTION;
};
#define CALL_ONCE_INITIALIZATION(function) \
static volatile sys::cas_flag initialized = 0; \
sys::cas_flag old_val = sys::CompareAndSwap(&initialized, 1, 0); \
if (old_val == 0) { \
function(Registry); \
sys::MemoryFence(); \
TsanIgnoreWritesBegin(); \
TsanHappensBefore(&initialized); \
initialized = 2; \
TsanIgnoreWritesEnd(); \
} else { \
sys::cas_flag tmp = initialized; \
sys::MemoryFence(); \
while (tmp != 2) { \
tmp = initialized; \
sys::MemoryFence(); \
} \
} \
TsanHappensAfter(&initialized);
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis) \
static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
Registry.registerPass(*PI, true); \
return PI; \
} \
void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
}
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis) \
static void* initialize##passName##PassOnce(PassRegistry &Registry) {
#define INITIALIZE_PASS_DEPENDENCY(depName) \
initialize##depName##Pass(Registry);
#define INITIALIZE_AG_DEPENDENCY(depName) \
initialize##depName##AnalysisGroup(Registry);
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis) \
PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
Registry.registerPass(*PI, true); \
return PI; \
} \
void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
}
template<typename PassName>
Pass *callDefaultCtor() { return new PassName(); }
template <typename PassName> Pass *callTargetMachineCtor(TargetMachine *TM) {
return new PassName(TM);
}
template<typename passName>
struct RegisterPass : public PassInfo {
RegisterPass(const char *PassArg, const char *Name, bool CFGOnly = false,
bool is_analysis = false)
: PassInfo(Name, PassArg, &passName::ID,
PassInfo::NormalCtor_t(callDefaultCtor<passName>),
CFGOnly, is_analysis) {
PassRegistry::getPassRegistry()->registerPass(*this);
}
};
class RegisterAGBase : public PassInfo {
public:
RegisterAGBase(const char *Name,
const void *InterfaceID,
const void *PassID = 0,
bool isDefault = false);
};
template<typename Interface, bool Default = false>
struct RegisterAnalysisGroup : public RegisterAGBase {
explicit RegisterAnalysisGroup(PassInfo &RPB)
: RegisterAGBase(RPB.getPassName(),
&Interface::ID, RPB.getTypeInfo(),
Default) {
}
explicit RegisterAnalysisGroup(const char *Name)
: RegisterAGBase(Name, &Interface::ID) {
}
};
#define INITIALIZE_ANALYSIS_GROUP(agName, name, defaultPass) \
static void* initialize##agName##AnalysisGroupOnce(PassRegistry &Registry) { \
initialize##defaultPass##Pass(Registry); \
PassInfo *AI = new PassInfo(name, & agName :: ID); \
Registry.registerAnalysisGroup(& agName ::ID, 0, *AI, false, true); \
return AI; \
} \
void llvm::initialize##agName##AnalysisGroup(PassRegistry &Registry) { \
CALL_ONCE_INITIALIZATION(initialize##agName##AnalysisGroupOnce) \
}
#define INITIALIZE_AG_PASS(passName, agName, arg, name, cfg, analysis, def) \
static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
if (!def) initialize##agName##AnalysisGroup(Registry); \
PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
Registry.registerPass(*PI, true); \
\
PassInfo *AI = new PassInfo(name, & agName :: ID); \
Registry.registerAnalysisGroup(& agName ::ID, & passName ::ID, \
*AI, def, true); \
return AI; \
} \
void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
}
#define INITIALIZE_AG_PASS_BEGIN(passName, agName, arg, n, cfg, analysis, def) \
static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
if (!def) initialize##agName##AnalysisGroup(Registry);
#define INITIALIZE_AG_PASS_END(passName, agName, arg, n, cfg, analysis, def) \
PassInfo *PI = new PassInfo(n, arg, & passName ::ID, \
PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
Registry.registerPass(*PI, true); \
\
PassInfo *AI = new PassInfo(n, & agName :: ID); \
Registry.registerAnalysisGroup(& agName ::ID, & passName ::ID, \
*AI, def, true); \
return AI; \
} \
void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
}
struct PassRegistrationListener {
PassRegistrationListener();
virtual ~PassRegistrationListener();
virtual void passRegistered(const PassInfo *) {}
void enumeratePasses();
virtual void passEnumerate(const PassInfo *) {}
};
}
#endif