<div dir="ltr">Yes, sorry, patch incoming.</div><br><div class="gmail_quote"><div dir="ltr">On Tue, Jan 8, 2019 at 8:55 PM Teresa Johnson <<a href="mailto:tejohnson@google.com">tejohnson@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">Is there a clang side patch going in for this? Getting a build error:</div><div dir="ltr"><br><div><div>tools/clang/lib/CodeGen/BackendUtil.cpp:308:10: error: use of undeclared identifier 'createThreadSanitizerPass'; did you mean 'createHWAddressSanitizerPass'?</div><div>  PM.add(createThreadSanitizerPass());</div><div>         ^~~~~~~~~~~~~~~~~~~~~~~~~</div><div>         createHWAddressSanitizerPass</div></div><div><br></div><div><br></div><div>Thanks,</div><div>Teresa</div></div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Jan 8, 2019 at 11:25 AM Philip Pfaffe via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: pfaffe<br>
Date: Tue Jan  8 11:21:57 2019<br>
New Revision: 350647<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=350647&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=350647&view=rev</a><br>
Log:<br>
[NewPM] Port tsan<br>
<br>
A straightforward port of tsan to the new PM, following the same path<br>
as D55647.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D56433" rel="noreferrer" target="_blank">https://reviews.llvm.org/D56433</a><br>
<br>
Added:<br>
    llvm/trunk/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h<br>
Modified:<br>
    llvm/trunk/include/llvm/InitializePasses.h<br>
    llvm/trunk/include/llvm/Transforms/Instrumentation.h<br>
    llvm/trunk/lib/Passes/PassBuilder.cpp<br>
    llvm/trunk/lib/Passes/PassRegistry.def<br>
    llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp<br>
    llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp<br>
    llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll<br>
<br>
Modified: llvm/trunk/include/llvm/InitializePasses.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=350647&r1=350646&r2=350647&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=350647&r1=350646&r2=350647&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/InitializePasses.h (original)<br>
+++ llvm/trunk/include/llvm/InitializePasses.h Tue Jan  8 11:21:57 2019<br>
@@ -391,7 +391,7 @@ void initializeTailDuplicatePass(PassReg<br>
 void initializeTargetLibraryInfoWrapperPassPass(PassRegistry&);<br>
 void initializeTargetPassConfigPass(PassRegistry&);<br>
 void initializeTargetTransformInfoWrapperPassPass(PassRegistry&);<br>
-void initializeThreadSanitizerPass(PassRegistry&);<br>
+void initializeThreadSanitizerLegacyPassPass(PassRegistry&);<br>
 void initializeTwoAddressInstructionPassPass(PassRegistry&);<br>
 void initializeTypeBasedAAWrapperPassPass(PassRegistry&);<br>
 void initializeUnifyFunctionExitNodesPass(PassRegistry&);<br>
<br>
Modified: llvm/trunk/include/llvm/Transforms/Instrumentation.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation.h?rev=350647&r1=350646&r2=350647&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation.h?rev=350647&r1=350646&r2=350647&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Transforms/Instrumentation.h (original)<br>
+++ llvm/trunk/include/llvm/Transforms/Instrumentation.h Tue Jan  8 11:21:57 2019<br>
@@ -155,9 +155,6 @@ ModulePass *createAddressSanitizerModule<br>
 FunctionPass *createHWAddressSanitizerPass(bool CompileKernel = false,<br>
                                            bool Recover = false);<br>
<br>
-// Insert ThreadSanitizer (race detection) instrumentation<br>
-FunctionPass *createThreadSanitizerPass();<br>
-<br>
 // Insert DataFlowSanitizer (dynamic data flow analysis) instrumentation<br>
 ModulePass *createDataFlowSanitizerPass(<br>
     const std::vector<std::string> &ABIListFiles = std::vector<std::string>(),<br>
<br>
Added: llvm/trunk/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h?rev=350647&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h?rev=350647&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h (added)<br>
+++ llvm/trunk/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h Tue Jan  8 11:21:57 2019<br>
@@ -0,0 +1,19 @@<br>
+#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_THREADSANITIZER_H<br>
+#define LLVM_TRANSFORMS_INSTRUMENTATION_THREADSANITIZER_H<br>
+<br>
+#include "llvm/IR/PassManager.h"<br>
+<br>
+namespace llvm {<br>
+// Insert ThreadSanitizer (race detection) instrumentation<br>
+FunctionPass *createThreadSanitizerLegacyPassPass();<br>
+<br>
+/// A function pass for tsan instrumentation.<br>
+///<br>
+/// Instruments functions to detect race conditions reads. This function pass<br>
+/// inserts calls to runtime library functions. If the functions aren't declared<br>
+/// yet, the pass inserts the declarations. Otherwise the existing globals are<br>
+struct ThreadSanitizerPass : public PassInfoMixin<ThreadSanitizerPass> {<br>
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);<br>
+};<br>
+}<br>
+#endif /* LLVM_TRANSFORMS_INSTRUMENTATION_THREADSANITIZER_H */<br>
<br>
Modified: llvm/trunk/lib/Passes/PassBuilder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=350647&r1=350646&r2=350647&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=350647&r1=350646&r2=350647&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Passes/PassBuilder.cpp (original)<br>
+++ llvm/trunk/lib/Passes/PassBuilder.cpp Tue Jan  8 11:21:57 2019<br>
@@ -95,6 +95,7 @@<br>
 #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"<br>
 #include "llvm/Transforms/Instrumentation/InstrProfiling.h"<br>
 #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"<br>
+#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"<br>
 #include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"<br>
 #include "llvm/Transforms/Scalar/ADCE.h"<br>
 #include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h"<br>
<br>
Modified: llvm/trunk/lib/Passes/PassRegistry.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassRegistry.def?rev=350647&r1=350646&r2=350647&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassRegistry.def?rev=350647&r1=350646&r2=350647&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Passes/PassRegistry.def (original)<br>
+++ llvm/trunk/lib/Passes/PassRegistry.def Tue Jan  8 11:21:57 2019<br>
@@ -234,6 +234,7 @@ FUNCTION_PASS("view-cfg", CFGViewerPass(<br>
 FUNCTION_PASS("view-cfg-only", CFGOnlyViewerPass())<br>
 FUNCTION_PASS("transform-warning", WarnMissedTransformationsPass())<br>
 FUNCTION_PASS("msan", MemorySanitizerPass())<br>
+FUNCTION_PASS("tsan", ThreadSanitizerPass())<br>
 #undef FUNCTION_PASS<br>
<br>
 #ifndef LOOP_ANALYSIS<br>
<br>
Modified: llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp?rev=350647&r1=350646&r2=350647&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp?rev=350647&r1=350646&r2=350647&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp Tue Jan  8 11:21:57 2019<br>
@@ -113,7 +113,7 @@ void llvm::initializeInstrumentation(Pas<br>
   initializeInstrProfilingLegacyPassPass(Registry);<br>
   initializeMemorySanitizerLegacyPassPass(Registry);<br>
   initializeHWAddressSanitizerPass(Registry);<br>
-  initializeThreadSanitizerPass(Registry);<br>
+  initializeThreadSanitizerLegacyPassPass(Registry);<br>
   initializeSanitizerCoverageModulePass(Registry);<br>
   initializeDataFlowSanitizerPass(Registry);<br>
   initializeEfficiencySanitizerPass(Registry);<br>
<br>
Modified: llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp?rev=350647&r1=350646&r2=350647&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp?rev=350647&r1=350646&r2=350647&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp Tue Jan  8 11:21:57 2019<br>
@@ -19,6 +19,7 @@<br>
 // The rest is handled by the run-time library.<br>
 //===----------------------------------------------------------------------===//<br>
<br>
+#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"<br>
 #include "llvm/ADT/SmallPtrSet.h"<br>
 #include "llvm/ADT/SmallString.h"<br>
 #include "llvm/ADT/SmallVector.h"<br>
@@ -80,21 +81,21 @@ STATISTIC(NumOmittedReadsFromConstantGlo<br>
 STATISTIC(NumOmittedReadsFromVtable, "Number of vtable reads");<br>
 STATISTIC(NumOmittedNonCaptured, "Number of accesses ignored due to capturing");<br>
<br>
-static const char *const kTsanModuleCtorName = "tsan.module_ctor";<br>
 static const char *const kTsanInitName = "__tsan_init";<br>
<br>
 namespace {<br>
<br>
 /// ThreadSanitizer: instrument the code in module to find races.<br>
-struct ThreadSanitizer : public FunctionPass {<br>
-  ThreadSanitizer() : FunctionPass(ID) {}<br>
-  StringRef getPassName() const override;<br>
-  void getAnalysisUsage(AnalysisUsage &AU) const override;<br>
-  bool runOnFunction(Function &F) override;<br>
-  bool doInitialization(Module &M) override;<br>
-  static char ID;  // Pass identification, replacement for typeid.<br>
+///<br>
+/// Instantiating ThreadSanitizer inserts the msan runtime library API function<br>
+/// declarations into the module if they don't exist already. Instantiating<br>
+/// ensures the __tsan_init function is in the list of global constructors for<br>
+/// the module.<br>
+struct ThreadSanitizer {<br>
+  ThreadSanitizer(Module &M);<br>
+  bool sanitizeFunction(Function &F, const TargetLibraryInfo &TLI);<br>
<br>
- private:<br>
+private:<br>
   void initializeCallbacks(Module &M);<br>
   bool instrumentLoadOrStore(Instruction *I, const DataLayout &DL);<br>
   bool instrumentAtomic(Instruction *I, const DataLayout &DL);<br>
@@ -128,29 +129,56 @@ struct ThreadSanitizer : public Function<br>
   Function *TsanVptrUpdate;<br>
   Function *TsanVptrLoad;<br>
   Function *MemmoveFn, *MemcpyFn, *MemsetFn;<br>
-  Function *TsanCtorFunction;<br>
+};<br>
+<br>
+struct ThreadSanitizerLegacyPass : FunctionPass {<br>
+  ThreadSanitizerLegacyPass() : FunctionPass(ID) {}<br>
+  StringRef getPassName() const override;<br>
+  void getAnalysisUsage(AnalysisUsage &AU) const override;<br>
+  bool runOnFunction(Function &F) override;<br>
+  bool doInitialization(Module &M) override;<br>
+  static char ID; // Pass identification, replacement for typeid.<br>
+private:<br>
+  Optional<ThreadSanitizer> TSan;<br>
 };<br>
 }  // namespace<br>
<br>
-char ThreadSanitizer::ID = 0;<br>
-INITIALIZE_PASS_BEGIN(<br>
-    ThreadSanitizer, "tsan",<br>
-    "ThreadSanitizer: detects data races.",<br>
-    false, false)<br>
+PreservedAnalyses ThreadSanitizerPass::run(Function &F,<br>
+                                           FunctionAnalysisManager &FAM) {<br>
+  ThreadSanitizer TSan(*F.getParent());<br>
+  if (TSan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F)))<br>
+    return PreservedAnalyses::none();<br>
+  return PreservedAnalyses::all();<br>
+}<br>
+<br>
+char ThreadSanitizerLegacyPass::ID = 0;<br>
+INITIALIZE_PASS_BEGIN(ThreadSanitizerLegacyPass, "tsan",<br>
+                      "ThreadSanitizer: detects data races.", false, false)<br>
 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)<br>
-INITIALIZE_PASS_END(<br>
-    ThreadSanitizer, "tsan",<br>
-    "ThreadSanitizer: detects data races.",<br>
-    false, false)<br>
+INITIALIZE_PASS_END(ThreadSanitizerLegacyPass, "tsan",<br>
+                    "ThreadSanitizer: detects data races.", false, false)<br>
<br>
-StringRef ThreadSanitizer::getPassName() const { return "ThreadSanitizer"; }<br>
+StringRef ThreadSanitizerLegacyPass::getPassName() const {<br>
+  return "ThreadSanitizerLegacyPass";<br>
+}<br>
<br>
-void ThreadSanitizer::getAnalysisUsage(AnalysisUsage &AU) const {<br>
+void ThreadSanitizerLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {<br>
   AU.addRequired<TargetLibraryInfoWrapperPass>();<br>
 }<br>
<br>
-FunctionPass *llvm::createThreadSanitizerPass() {<br>
-  return new ThreadSanitizer();<br>
+bool ThreadSanitizerLegacyPass::doInitialization(Module &M) {<br>
+  TSan.emplace(M);<br>
+  return true;<br>
+}<br>
+<br>
+bool ThreadSanitizerLegacyPass::runOnFunction(Function &F) {<br>
+  auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();<br>
+  TSan->sanitizeFunction(F, TLI);<br>
+  return true;<br>
+}<br>
+<br>
+FunctionPass *llvm::createThreadSanitizerLegacyPassPass() {<br>
+  return new ThreadSanitizerLegacyPass();<br>
 }<br>
<br>
 void ThreadSanitizer::initializeCallbacks(Module &M) {<br>
@@ -252,16 +280,10 @@ void ThreadSanitizer::initializeCallback<br>
                             IRB.getInt32Ty(), IntptrTy));<br>
 }<br>
<br>
-bool ThreadSanitizer::doInitialization(Module &M) {<br>
+ThreadSanitizer::ThreadSanitizer(Module &M) {<br>
   const DataLayout &DL = M.getDataLayout();<br>
   IntptrTy = DL.getIntPtrType(M.getContext());<br>
-  std::tie(TsanCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions(<br>
-      M, kTsanModuleCtorName, kTsanInitName, /*InitArgTypes=*/{},<br>
-      /*InitArgs=*/{});<br>
-<br>
-  appendToGlobalCtors(M, TsanCtorFunction, 0);<br>
-<br>
-  return true;<br>
+  getOrCreateInitFunction(M, kTsanInitName);<br>
 }<br>
<br>
 static bool isVtableAccess(Instruction *I) {<br>
@@ -402,11 +424,8 @@ void ThreadSanitizer::InsertRuntimeIgnor<br>
   }<br>
 }<br>
<br>
-bool ThreadSanitizer::runOnFunction(Function &F) {<br>
-  // This is required to prevent instrumenting call to __tsan_init from within<br>
-  // the module constructor.<br>
-  if (&F == TsanCtorFunction)<br>
-    return false;<br>
+bool ThreadSanitizer::sanitizeFunction(Function &F,<br>
+                                       const TargetLibraryInfo &TLI) {<br>
   initializeCallbacks(*F.getParent());<br>
   SmallVector<Instruction*, 8> AllLoadsAndStores;<br>
   SmallVector<Instruction*, 8> LocalLoadsAndStores;<br>
@@ -416,8 +435,6 @@ bool ThreadSanitizer::runOnFunction(Func<br>
   bool HasCalls = false;<br>
   bool SanitizeFunction = F.hasFnAttribute(Attribute::SanitizeThread);<br>
   const DataLayout &DL = F.getParent()->getDataLayout();<br>
-  const TargetLibraryInfo *TLI =<br>
-      &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();<br>
<br>
   // Traverse all instructions, collect loads/stores/returns, check for calls.<br>
   for (auto &BB : F) {<br>
@@ -428,7 +445,7 @@ bool ThreadSanitizer::runOnFunction(Func<br>
         LocalLoadsAndStores.push_back(&Inst);<br>
       else if (isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) {<br>
         if (CallInst *CI = dyn_cast<CallInst>(&Inst))<br>
-          maybeMarkSanitizerLibraryCallNoBuiltin(CI, TLI);<br>
+          maybeMarkSanitizerLibraryCallNoBuiltin(CI, &TLI);<br>
         if (isa<MemIntrinsic>(Inst))<br>
           MemIntrinCalls.push_back(&Inst);<br>
         HasCalls = true;<br>
<br>
Modified: llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll?rev=350647&r1=350646&r2=350647&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll?rev=350647&r1=350646&r2=350647&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll (original)<br>
+++ llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll Tue Jan  8 11:21:57 2019<br>
@@ -1,4 +1,5 @@<br>
 ; RUN: opt < %s -tsan -S | FileCheck %s<br>
+; RUN: opt < %s -passes=tsan -S | FileCheck %s<br>
<br>
 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"<br>
 target triple = "x86_64-unknown-linux-gnu"<br>
@@ -9,7 +10,7 @@ entry:<br>
   ret i32 %tmp1<br>
 }<br>
<br>
-; CHECK: @llvm.global_ctors = {{.*}}@tsan.module_ctor<br>
+; CHECK: @llvm.global_ctors = {{.*}}@__tsan_init<br>
<br>
 ; CHECK: define i32 @read_4_bytes(i32* %a)<br>
 ; CHECK:        call void @__tsan_func_entry(i8* %0)<br>
@@ -77,6 +78,3 @@ define void @SwiftErrorCall(i8** swifter<br>
   call void @SwiftError(i8** %0)<br>
   ret void<br>
 }<br>
-<br>
-; CHECK: define internal void @tsan.module_ctor()<br>
-; CHECK: call void @__tsan_init()<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail-m_-11802972541789845gmail-m_-8651859868626090476gmail_signature"><div dir="ltr"><div><span style="font-family:Times;font-size:medium"><table cellspacing="0" cellpadding="0"><tbody><tr style="color:rgb(85,85,85);font-family:sans-serif;font-size:small"><td nowrap style="border-top:2px solid rgb(213,15,37)">Teresa Johnson |</td><td nowrap style="border-top:2px solid rgb(51,105,232)"> Software Engineer |</td><td nowrap style="border-top:2px solid rgb(0,153,57)"> <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |</td><td nowrap style="border-top:2px solid rgb(238,178,17)"><br></td></tr></tbody></table></span></div></div></div>
</blockquote></div>