mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-02 16:36:40 +00:00
[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. llvm-svn: 271652
This commit is contained in:
parent
f30fab0fe4
commit
4070a831c7
@ -377,8 +377,10 @@ namespace llvm {
|
||||
Registry.registerPass(*PI, true); \
|
||||
return PI; \
|
||||
} \
|
||||
LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
|
||||
void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
|
||||
CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
|
||||
call_once(Initialize##passName##PassFlag, initialize##passName##PassOnce, \
|
||||
std::ref(Registry)); \
|
||||
}
|
||||
|
||||
/// This initializer registers TargetMachine constructor, so the pass being
|
||||
|
@ -26,31 +26,13 @@
|
||||
#include "llvm/PassInfo.h"
|
||||
#include "llvm/PassRegistry.h"
|
||||
#include "llvm/Support/Atomic.h"
|
||||
#include "llvm/Support/Threading.h"
|
||||
#include <functional>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class TargetMachine;
|
||||
|
||||
#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( \
|
||||
@ -59,8 +41,10 @@ class TargetMachine;
|
||||
Registry.registerPass(*PI, true); \
|
||||
return PI; \
|
||||
} \
|
||||
LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
|
||||
void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
|
||||
CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
|
||||
call_once(Initialize##passName##PassFlag, initialize##passName##PassOnce, \
|
||||
std::ref(Registry)); \
|
||||
}
|
||||
|
||||
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis) \
|
||||
@ -77,8 +61,10 @@ class TargetMachine;
|
||||
Registry.registerPass(*PI, true); \
|
||||
return PI; \
|
||||
} \
|
||||
LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
|
||||
void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
|
||||
CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
|
||||
call_once(Initialize##passName##PassFlag, initialize##passName##PassOnce, \
|
||||
std::ref(Registry)); \
|
||||
}
|
||||
|
||||
#define INITIALIZE_PASS_WITH_OPTIONS(PassName, Arg, Name, Cfg, Analysis) \
|
||||
@ -166,8 +152,10 @@ struct RegisterAnalysisGroup : public RegisterAGBase {
|
||||
Registry.registerAnalysisGroup(&agName::ID, 0, *AI, false, true); \
|
||||
return AI; \
|
||||
} \
|
||||
LLVM_DEFINE_ONCE_FLAG(Initialize##agName##AnalysisGroupFlag); \
|
||||
void llvm::initialize##agName##AnalysisGroup(PassRegistry &Registry) { \
|
||||
CALL_ONCE_INITIALIZATION(initialize##agName##AnalysisGroupOnce) \
|
||||
call_once(Initialize##agName##AnalysisGroupFlag, \
|
||||
initialize##agName##AnalysisGroupOnce, std::ref(Registry)); \
|
||||
}
|
||||
|
||||
#define INITIALIZE_AG_PASS(passName, agName, arg, name, cfg, analysis, def) \
|
||||
@ -184,8 +172,10 @@ struct RegisterAnalysisGroup : public RegisterAGBase {
|
||||
true); \
|
||||
return AI; \
|
||||
} \
|
||||
LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
|
||||
void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
|
||||
CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
|
||||
call_once(Initialize##passName##PassFlag, initialize##passName##PassOnce, \
|
||||
std::ref(Registry)); \
|
||||
}
|
||||
|
||||
#define INITIALIZE_AG_PASS_BEGIN(passName, agName, arg, n, cfg, analysis, def) \
|
||||
@ -203,8 +193,10 @@ struct RegisterAnalysisGroup : public RegisterAGBase {
|
||||
Registry.registerAnalysisGroup(&agName::ID, &passName::ID, *AI, def, true); \
|
||||
return AI; \
|
||||
} \
|
||||
LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
|
||||
void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
|
||||
CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
|
||||
call_once(Initialize##passName##PassFlag, initialize##passName##PassOnce, \
|
||||
std::ref(Registry)); \
|
||||
}
|
||||
|
||||
//===---------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user