X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FPassSupport.h;h=c6ad44f5f4ec90415030b8d310888e3eeae0ecbf;hb=a5c699d5f7de7eb88b7f549539b6550653dea74e;hp=e0e4e8a6133eaabbfdb3d91a46e11a81161c6424;hpb=139788fe6f606075507f7cbb66cdbac57d8fabcd;p=oota-llvm.git diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h index e0e4e8a6133..c6ad44f5f4e 100644 --- a/include/llvm/PassSupport.h +++ b/include/llvm/PassSupport.h @@ -24,7 +24,8 @@ #include "Pass.h" #include "llvm/PassRegistry.h" #include "llvm/InitializePasses.h" -#include "llvm/Support/Compiler.h" +#include "llvm/Support/Atomic.h" +#include "llvm/Support/Valgrind.h" #include namespace llvm { @@ -125,22 +126,40 @@ 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); \ + Registry.registerPass(*PI, true); \ return PI; \ } \ void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ - ATTRIBUTE_USED \ - static void* initialized = initialize##passName##PassOnce(Registry); \ - } \ - static RegisterPass passName ## _info(arg, name, cfg, analysis); + CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \ + } #define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis) \ static void* initialize##passName##PassOnce(PassRegistry &Registry) { @@ -153,14 +172,12 @@ private: #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; \ } \ void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ - ATTRIBUTE_USED \ - static void* initialized = initialize##passName##PassOnce(Registry); \ - } \ - static RegisterPass passName ## _info(arg, name, cfg, analysis); + CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \ + } template Pass *callDefaultCtor() { return new PassName(); } @@ -240,50 +257,48 @@ struct RegisterAnalysisGroup : public RegisterAGBase { 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; \ } \ void llvm::initialize##agName##AnalysisGroup(PassRegistry &Registry) { \ - ATTRIBUTE_USED static void* initialized = \ - initialize##agName##AnalysisGroupOnce(Registry); \ - } \ - static RegisterAnalysisGroup agName##_info (name); + 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); \ + 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) { \ - ATTRIBUTE_USED \ - static void* initialized = initialize##passName##PassOnce(Registry); \ - } \ - static RegisterPass passName ## _info(arg, name, cfg, analysis); \ - static RegisterAnalysisGroup passName ## _ag(passName ## _info); + 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) { + 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); \ + Registry.registerPass(*PI, true); \ \ PassInfo *AI = new PassInfo(n, & 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) { \ - ATTRIBUTE_USED \ - static void* initialized = initialize##passName##PassOnce(Registry); \ - } \ - static RegisterPass passName ## _info(arg, n, cfg, analysis); \ - static RegisterAnalysisGroup passName ## _ag(passName ## _info); + CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \ + } //===--------------------------------------------------------------------------- /// PassRegistrationListener class - This class is meant to be derived from by