TSan: Use `createSanitizerCtor` to create ctor, and call `__tsan_init`
authorIsmail Pazarbasi <ismail.pazarbasi@gmail.com>
Thu, 7 May 2015 21:41:23 +0000 (21:41 +0000)
committerIsmail Pazarbasi <ismail.pazarbasi@gmail.com>
Thu, 7 May 2015 21:41:23 +0000 (21:41 +0000)
Reviewers: kcc, dvyukov

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D8779

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236778 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Instrumentation/ThreadSanitizer.cpp
test/Instrumentation/ThreadSanitizer/tsan_basic.ll

index aa8ee5aab7dfcb5aea59a1a26052470b26343b0a..b23dacc5638f11374d647715c34020e03fb8c9dd 100644 (file)
@@ -72,6 +72,9 @@ STATISTIC(NumOmittedReadsFromConstantGlobals,
 STATISTIC(NumOmittedReadsFromVtable, "Number of vtable reads");
 STATISTIC(NumOmittedNonCaptured, "Number of accesses ignored due to capturing");
 
+static const char *const kTsanModuleCtorName = "tsan.module_ctor";
+static const char *const kTsanInitName = "__tsan_init";
+
 namespace {
 
 /// ThreadSanitizer: instrument the code in module to find races.
@@ -113,6 +116,7 @@ struct ThreadSanitizer : public FunctionPass {
   Function *TsanVptrUpdate;
   Function *TsanVptrLoad;
   Function *MemmoveFn, *MemcpyFn, *MemsetFn;
+  Function *TsanCtorFunction;
 };
 }  // namespace
 
@@ -225,13 +229,12 @@ void ThreadSanitizer::initializeCallbacks(Module &M) {
 
 bool ThreadSanitizer::doInitialization(Module &M) {
   const DataLayout &DL = M.getDataLayout();
+  IntptrTy = DL.getIntPtrType(M.getContext());
+  std::tie(TsanCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions(
+      M, kTsanModuleCtorName, kTsanInitName, /*InitArgTypes=*/{},
+      /*InitArgs=*/{});
 
-  // Always insert a call to __tsan_init into the module's CTORs.
-  IRBuilder<> IRB(M.getContext());
-  IntptrTy = IRB.getIntPtrTy(DL);
-  Value *TsanInit = M.getOrInsertFunction("__tsan_init",
-                                          IRB.getVoidTy(), nullptr);
-  appendToGlobalCtors(M, cast<Function>(TsanInit), 0);
+  appendToGlobalCtors(M, TsanCtorFunction, 0);
 
   return true;
 }
@@ -329,6 +332,10 @@ static bool isAtomic(Instruction *I) {
 }
 
 bool ThreadSanitizer::runOnFunction(Function &F) {
+  // This is required to prevent instrumenting call to __tsan_init from within
+  // the module constructor.
+  if (&F == TsanCtorFunction)
+    return false;
   initializeCallbacks(*F.getParent());
   SmallVector<Instruction*, 8> RetVec;
   SmallVector<Instruction*, 8> AllLoadsAndStores;
index 22582ebda73af05a8b9078b750fbdb3d03c3e9e8..7e049c548f2232309726d6a6908941d1c5697e73 100644 (file)
@@ -9,7 +9,7 @@ entry:
   ret i32 %tmp1
 }
 
-; CHECK: @llvm.global_ctors = {{.*}}@__tsan_init
+; CHECK: @llvm.global_ctors = {{.*}}@tsan.module_ctor
 
 ; CHECK: define i32 @read_4_bytes(i32* %a)
 ; CHECK:        call void @__tsan_func_entry(i8* %0)
@@ -53,3 +53,6 @@ entry:
 ; CHECK: call i8* @memset
 ; CHECK: ret void
 }
+
+; CHECK: define internal void @tsan.module_ctor()
+; CHECK: call void @__tsan_init()