X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FPassSupport.h;h=ccc79345e0304e9410084aa35c1de60e80c89f99;hb=a249914462c7b8f0c25b21eca77df264455290ee;hp=37010ed0a66791a71efc20edd6cd07b40fdd9c02;hpb=ce665bd2e2b581ab0858d1afe359192bac96b868;p=oota-llvm.git diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h index 37010ed0a66..ccc79345e03 100644 --- a/include/llvm/PassSupport.h +++ b/include/llvm/PassSupport.h @@ -18,12 +18,14 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_PASS_SUPPORT_H -#define LLVM_PASS_SUPPORT_H +#ifndef LLVM_PASSSUPPORT_H +#define LLVM_PASSSUPPORT_H #include "Pass.h" -#include "llvm/PassRegistry.h" #include "llvm/InitializePasses.h" +#include "llvm/PassRegistry.h" +#include "llvm/Support/Atomic.h" +#include "llvm/Support/Valgrind.h" #include namespace llvm { @@ -124,18 +126,58 @@ public: } private: - void operator=(const PassInfo &); // do not implement - PassInfo(const PassInfo &); // do not implement + 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); \ + Registry.registerPass(*PI, true); \ + return PI; \ } \ - static RegisterPass passName ## _info(arg, name, cfg, analysis); - + void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ + CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \ + } template Pass *callDefaultCtor() { return new PassName(); } @@ -211,31 +253,59 @@ struct RegisterAnalysisGroup : public RegisterAGBase { } }; -#define INITIALIZE_ANALYSIS_GROUP(agName, name) \ - void llvm::initialize##agName##AnalysisGroup(PassRegistry &Registry) { \ +#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); \ + Registry.registerAnalysisGroup(& agName ::ID, 0, *AI, false, true); \ + return AI; \ } \ - static RegisterAnalysisGroup agName##_info (name); + void llvm::initialize##agName##AnalysisGroup(PassRegistry &Registry) { \ + CALL_ONCE_INITIALIZATION(initialize##agName##AnalysisGroupOnce) \ + } + #define INITIALIZE_AG_PASS(passName, agName, arg, name, cfg, analysis, def) \ - void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ + 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); \ + Registry.registerPass(*PI, true); \ \ PassInfo *AI = new PassInfo(name, & agName :: ID); \ - Registry.registerAnalysisGroup(& agName ::ID, & passName ::ID, *AI, def); \ + 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; \ } \ - static RegisterPass passName ## _info(arg, name, cfg, analysis); \ - static RegisterAnalysisGroup passName ## _ag(passName ## _info); + void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ + CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \ + } //===--------------------------------------------------------------------------- /// PassRegistrationListener class - This class is meant to be derived from by /// clients that are interested in which passes get registered and unregistered /// at runtime (which can be because of the RegisterPass constructors being run /// as the program starts up, or may be because a shared object just got -/// loaded). Deriving from the PassRegistationListener class automatically +/// loaded). Deriving from the PassRegistrationListener class automatically /// registers your object to receive callbacks indicating when passes are loaded /// and removed. ///