]> granicus.if.org Git - llvm/commitdiff
Revert r350647: "[NewPM] Port tsan"
authorFlorian Hahn <flo@fhahn.com>
Wed, 9 Jan 2019 13:32:16 +0000 (13:32 +0000)
committerFlorian Hahn <flo@fhahn.com>
Wed, 9 Jan 2019 13:32:16 +0000 (13:32 +0000)
This patch breaks thread sanitizer on some macOS builders, e.g.
http://green.lab.llvm.org/green/job/clang-stage1-configure-RA/52725/

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

include/llvm/InitializePasses.h
include/llvm/Transforms/Instrumentation.h
include/llvm/Transforms/Instrumentation/ThreadSanitizer.h [deleted file]
lib/Passes/PassBuilder.cpp
lib/Passes/PassRegistry.def
lib/Transforms/Instrumentation/Instrumentation.cpp
lib/Transforms/Instrumentation/ThreadSanitizer.cpp
test/Instrumentation/ThreadSanitizer/tsan_basic.ll

index 24de5cb4b52620310adfbc135eb77da943191d3e..293f37ee40c24a8c7179510842ec41987f601832 100644 (file)
@@ -391,7 +391,7 @@ void initializeTailDuplicatePass(PassRegistry&);
 void initializeTargetLibraryInfoWrapperPassPass(PassRegistry&);
 void initializeTargetPassConfigPass(PassRegistry&);
 void initializeTargetTransformInfoWrapperPassPass(PassRegistry&);
-void initializeThreadSanitizerLegacyPassPass(PassRegistry&);
+void initializeThreadSanitizerPass(PassRegistry&);
 void initializeTwoAddressInstructionPassPass(PassRegistry&);
 void initializeTypeBasedAAWrapperPassPass(PassRegistry&);
 void initializeUnifyFunctionExitNodesPass(PassRegistry&);
index 017cab0a7750df0692e4169bc7a281cc270ad2af..34b520720125a0f62635ff30cbf92f87d4a677cc 100644 (file)
@@ -155,6 +155,9 @@ ModulePass *createAddressSanitizerModulePass(bool CompileKernel = false,
 FunctionPass *createHWAddressSanitizerPass(bool CompileKernel = false,
                                            bool Recover = false);
 
+// Insert ThreadSanitizer (race detection) instrumentation
+FunctionPass *createThreadSanitizerPass();
+
 // Insert DataFlowSanitizer (dynamic data flow analysis) instrumentation
 ModulePass *createDataFlowSanitizerPass(
     const std::vector<std::string> &ABIListFiles = std::vector<std::string>(),
diff --git a/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h b/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h
deleted file mode 100644 (file)
index 56874e3..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_THREADSANITIZER_H
-#define LLVM_TRANSFORMS_INSTRUMENTATION_THREADSANITIZER_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-// Insert ThreadSanitizer (race detection) instrumentation
-FunctionPass *createThreadSanitizerLegacyPassPass();
-
-/// A function pass for tsan instrumentation.
-///
-/// Instruments functions to detect race conditions reads. This function pass
-/// inserts calls to runtime library functions. If the functions aren't declared
-/// yet, the pass inserts the declarations. Otherwise the existing globals are
-struct ThreadSanitizerPass : public PassInfoMixin<ThreadSanitizerPass> {
-  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
-};
-}
-#endif /* LLVM_TRANSFORMS_INSTRUMENTATION_THREADSANITIZER_H */
index 61b16f1d6b91a78921833a6b9c6158c291d0e601..e1d0a47fb6d185a20ee9e810751a7bbb5aef45a2 100644 (file)
@@ -95,7 +95,6 @@
 #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
 #include "llvm/Transforms/Instrumentation/InstrProfiling.h"
 #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
-#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
 #include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"
 #include "llvm/Transforms/Scalar/ADCE.h"
 #include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h"
index b1b7abe16c7f72a6e36462fd6d2f986b9e3f08ef..a8c03ad05968f9e924193e83d46f5a15d607d403 100644 (file)
@@ -234,7 +234,6 @@ FUNCTION_PASS("view-cfg", CFGViewerPass())
 FUNCTION_PASS("view-cfg-only", CFGOnlyViewerPass())
 FUNCTION_PASS("transform-warning", WarnMissedTransformationsPass())
 FUNCTION_PASS("msan", MemorySanitizerPass())
-FUNCTION_PASS("tsan", ThreadSanitizerPass())
 #undef FUNCTION_PASS
 
 #ifndef LOOP_ANALYSIS
index c3e323613c707970f96bb80891d41068edf02199..5828019a03a30974808759f35b4627e49ba4dd2c 100644 (file)
@@ -113,7 +113,7 @@ void llvm::initializeInstrumentation(PassRegistry &Registry) {
   initializeInstrProfilingLegacyPassPass(Registry);
   initializeMemorySanitizerLegacyPassPass(Registry);
   initializeHWAddressSanitizerPass(Registry);
-  initializeThreadSanitizerLegacyPassPass(Registry);
+  initializeThreadSanitizerPass(Registry);
   initializeSanitizerCoverageModulePass(Registry);
   initializeDataFlowSanitizerPass(Registry);
   initializeEfficiencySanitizerPass(Registry);
index 7d535db9d6a60c0c71704b7b16910b9b79fd5e7e..fa1e5a157a0fc39777b72a39042ea091f6ec230c 100644 (file)
@@ -19,7 +19,6 @@
 // The rest is handled by the run-time library.
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
@@ -81,21 +80,21 @@ 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.
-///
-/// Instantiating ThreadSanitizer inserts the msan runtime library API function
-/// declarations into the module if they don't exist already. Instantiating
-/// ensures the __tsan_init function is in the list of global constructors for
-/// the module.
-struct ThreadSanitizer {
-  ThreadSanitizer(Module &M);
-  bool sanitizeFunction(Function &F, const TargetLibraryInfo &TLI);
-
-private:
+struct ThreadSanitizer : public FunctionPass {
+  ThreadSanitizer() : FunctionPass(ID) {}
+  StringRef getPassName() const override;
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  bool runOnFunction(Function &F) override;
+  bool doInitialization(Module &M) override;
+  static char ID;  // Pass identification, replacement for typeid.
+
+ private:
   void initializeCallbacks(Module &M);
   bool instrumentLoadOrStore(Instruction *I, const DataLayout &DL);
   bool instrumentAtomic(Instruction *I, const DataLayout &DL);
@@ -129,56 +128,29 @@ private:
   Function *TsanVptrUpdate;
   Function *TsanVptrLoad;
   Function *MemmoveFn, *MemcpyFn, *MemsetFn;
-};
-
-struct ThreadSanitizerLegacyPass : FunctionPass {
-  ThreadSanitizerLegacyPass() : FunctionPass(ID) {}
-  StringRef getPassName() const override;
-  void getAnalysisUsage(AnalysisUsage &AU) const override;
-  bool runOnFunction(Function &F) override;
-  bool doInitialization(Module &M) override;
-  static char ID; // Pass identification, replacement for typeid.
-private:
-  Optional<ThreadSanitizer> TSan;
+  Function *TsanCtorFunction;
 };
 }  // namespace
 
-PreservedAnalyses ThreadSanitizerPass::run(Function &F,
-                                           FunctionAnalysisManager &FAM) {
-  ThreadSanitizer TSan(*F.getParent());
-  if (TSan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F)))
-    return PreservedAnalyses::none();
-  return PreservedAnalyses::all();
-}
-
-char ThreadSanitizerLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(ThreadSanitizerLegacyPass, "tsan",
-                      "ThreadSanitizer: detects data races.", false, false)
+char ThreadSanitizer::ID = 0;
+INITIALIZE_PASS_BEGIN(
+    ThreadSanitizer, "tsan",
+    "ThreadSanitizer: detects data races.",
+    false, false)
 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
-INITIALIZE_PASS_END(ThreadSanitizerLegacyPass, "tsan",
-                    "ThreadSanitizer: detects data races.", false, false)
+INITIALIZE_PASS_END(
+    ThreadSanitizer, "tsan",
+    "ThreadSanitizer: detects data races.",
+    false, false)
 
-StringRef ThreadSanitizerLegacyPass::getPassName() const {
-  return "ThreadSanitizerLegacyPass";
-}
+StringRef ThreadSanitizer::getPassName() const { return "ThreadSanitizer"; }
 
-void ThreadSanitizerLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
+void ThreadSanitizer::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<TargetLibraryInfoWrapperPass>();
 }
 
-bool ThreadSanitizerLegacyPass::doInitialization(Module &M) {
-  TSan.emplace(M);
-  return true;
-}
-
-bool ThreadSanitizerLegacyPass::runOnFunction(Function &F) {
-  auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
-  TSan->sanitizeFunction(F, TLI);
-  return true;
-}
-
-FunctionPass *llvm::createThreadSanitizerLegacyPassPass() {
-  return new ThreadSanitizerLegacyPass();
+FunctionPass *llvm::createThreadSanitizerPass() {
+  return new ThreadSanitizer();
 }
 
 void ThreadSanitizer::initializeCallbacks(Module &M) {
@@ -280,10 +252,16 @@ void ThreadSanitizer::initializeCallbacks(Module &M) {
                             IRB.getInt32Ty(), IntptrTy));
 }
 
-ThreadSanitizer::ThreadSanitizer(Module &M) {
+bool ThreadSanitizer::doInitialization(Module &M) {
   const DataLayout &DL = M.getDataLayout();
   IntptrTy = DL.getIntPtrType(M.getContext());
-  getOrCreateInitFunction(M, kTsanInitName);
+  std::tie(TsanCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions(
+      M, kTsanModuleCtorName, kTsanInitName, /*InitArgTypes=*/{},
+      /*InitArgs=*/{});
+
+  appendToGlobalCtors(M, TsanCtorFunction, 0);
+
+  return true;
 }
 
 static bool isVtableAccess(Instruction *I) {
@@ -424,8 +402,11 @@ void ThreadSanitizer::InsertRuntimeIgnores(Function &F) {
   }
 }
 
-bool ThreadSanitizer::sanitizeFunction(Function &F,
-                                       const TargetLibraryInfo &TLI) {
+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> AllLoadsAndStores;
   SmallVector<Instruction*, 8> LocalLoadsAndStores;
@@ -435,6 +416,8 @@ bool ThreadSanitizer::sanitizeFunction(Function &F,
   bool HasCalls = false;
   bool SanitizeFunction = F.hasFnAttribute(Attribute::SanitizeThread);
   const DataLayout &DL = F.getParent()->getDataLayout();
+  const TargetLibraryInfo *TLI =
+      &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
 
   // Traverse all instructions, collect loads/stores/returns, check for calls.
   for (auto &BB : F) {
@@ -445,7 +428,7 @@ bool ThreadSanitizer::sanitizeFunction(Function &F,
         LocalLoadsAndStores.push_back(&Inst);
       else if (isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) {
         if (CallInst *CI = dyn_cast<CallInst>(&Inst))
-          maybeMarkSanitizerLibraryCallNoBuiltin(CI, &TLI);
+          maybeMarkSanitizerLibraryCallNoBuiltin(CI, TLI);
         if (isa<MemIntrinsic>(Inst))
           MemIntrinCalls.push_back(&Inst);
         HasCalls = true;
index cce7f467f4109a161bdcfa7d1e9d46dbc4953107..69d4117399b754e281a1f4f9c54c3636f21db02e 100644 (file)
@@ -1,5 +1,4 @@
 ; RUN: opt < %s -tsan -S | FileCheck %s
-; RUN: opt < %s -passes=tsan -S | FileCheck %s
 
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
 target triple = "x86_64-unknown-linux-gnu"
@@ -10,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)
@@ -78,3 +77,6 @@ define void @SwiftErrorCall(i8** swifterror) sanitize_thread {
   call void @SwiftError(i8** %0)
   ret void
 }
+
+; CHECK: define internal void @tsan.module_ctor()
+; CHECK: call void @__tsan_init()