llvm.org GIT mirror llvm / f1c11c6
[LPM] Replace the CALL_ONCE_... macro in the legacy pass manager with the new llvm::call_once facility. This facility matches the standard APIs and when the platform supports it actually directly uses the standard provided functionality. This is both more efficient on some platforms and much more TSan friendly. The only remaining user of the cas_flag and home-rolled atomics is the fallback implementation of call_once. I have a patch that removes them entirely, but it needs a Windows patch to land first. This alone substantially cleans up the macros for the legacy pass manager, and should subsume some of the work Mehdi was doing to clear the path for TSan testing of ThinLTO, a really important step to have reliable upstream testing of ThinLTO in all forms. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271652 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 4 years ago
2 changed file(s) with 24 addition(s) and 30 deletion(s). Raw diff Collapse all Expand all
376376 Registry.registerPass(*PI, true); \
377377 return PI; \
378378 } \
379 LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
379380 void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
380 CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
381 call_once(Initialize##passName##PassFlag, initialize##passName##PassOnce, \
382 std::ref(Registry)); \
381383 }
382384
383385 /// This initializer registers TargetMachine constructor, so the pass being
2525 #include "llvm/PassInfo.h"
2626 #include "llvm/PassRegistry.h"
2727 #include "llvm/Support/Atomic.h"
28 #include "llvm/Support/Threading.h"
29 #include
2830
2931 namespace llvm {
3032
3133 class TargetMachine;
32
33 #define CALL_ONCE_INITIALIZATION(function) \
34 static volatile sys::cas_flag initialized = 0; \
35 sys::cas_flag old_val = sys::CompareAndSwap(&initialized, 1, 0); \
36 if (old_val == 0) { \
37 function(Registry); \
38 sys::MemoryFence(); \
39 TsanIgnoreWritesBegin(); \
40 TsanHappensBefore(&initialized); \
41 initialized = 2; \
42 TsanIgnoreWritesEnd(); \
43 } else { \
44 sys::cas_flag tmp = initialized; \
45 sys::MemoryFence(); \
46 while (tmp != 2) { \
47 tmp = initialized; \
48 sys::MemoryFence(); \
49 } \
50 } \
51 TsanHappensAfter(&initialized);
5234
5335 #define INITIALIZE_PASS(passName, arg, name, cfg, analysis) \
5436 static void *initialize##passName##PassOnce(PassRegistry &Registry) { \
5840 Registry.registerPass(*PI, true); \
5941 return PI; \
6042 } \
61 void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
62 CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
43 LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
44 void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
45 call_once(Initialize##passName##PassFlag, initialize##passName##PassOnce, \
46 std::ref(Registry)); \
6347 }
6448
6549 #define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis) \
7660 Registry.registerPass(*PI, true); \
7761 return PI; \
7862 } \
79 void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
80 CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
63 LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
64 void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
65 call_once(Initialize##passName##PassFlag, initialize##passName##PassOnce, \
66 std::ref(Registry)); \
8167 }
8268
8369 #define INITIALIZE_PASS_WITH_OPTIONS(PassName, Arg, Name, Cfg, Analysis) \
165151 Registry.registerAnalysisGroup(&agName::ID, 0, *AI, false, true); \
166152 return AI; \
167153 } \
154 LLVM_DEFINE_ONCE_FLAG(Initialize##agName##AnalysisGroupFlag); \
168155 void llvm::initialize##agName##AnalysisGroup(PassRegistry &Registry) { \
169 CALL_ONCE_INITIALIZATION(initialize##agName##AnalysisGroupOnce) \
156 call_once(Initialize##agName##AnalysisGroupFlag, \
157 initialize##agName##AnalysisGroupOnce, std::ref(Registry)); \
170158 }
171159
172160 #define INITIALIZE_AG_PASS(passName, agName, arg, name, cfg, analysis, def) \
183171 true); \
184172 return AI; \
185173 } \
186 void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
187 CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
174 LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
175 void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
176 call_once(Initialize##passName##PassFlag, initialize##passName##PassOnce, \
177 std::ref(Registry)); \
188178 }
189179
190180 #define INITIALIZE_AG_PASS_BEGIN(passName, agName, arg, n, cfg, analysis, def) \
202192 Registry.registerAnalysisGroup(&agName::ID, &passName::ID, *AI, def, true); \
203193 return AI; \
204194 } \
205 void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
206 CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
195 LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
196 void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
197 call_once(Initialize##passName##PassFlag, initialize##passName##PassOnce, \
198 std::ref(Registry)); \
207199 }
208200
209201 //===---------------------------------------------------------------------------