Index: include/llvm/Transforms/Instrumentation.h =================================================================== --- include/llvm/Transforms/Instrumentation.h +++ include/llvm/Transforms/Instrumentation.h @@ -112,7 +112,9 @@ bool Recover = false); // Insert ThreadSanitizer (race detection) instrumentation -FunctionPass *createThreadSanitizerPass(); +FunctionPass *createThreadSanitizerPass(bool DetectDataRaces = true, + bool StackTraces = true, + bool AnalyzeAtomics = true); // Insert DataFlowSanitizer (dynamic data flow analysis) instrumentation ModulePass *createDataFlowSanitizerPass( Index: lib/Transforms/Instrumentation/ThreadSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -82,7 +82,14 @@ /// ThreadSanitizer: instrument the code in module to find races. struct ThreadSanitizer : public FunctionPass { - ThreadSanitizer() : FunctionPass(ID) {} + ThreadSanitizer(bool DetectDataRaces = true, + bool StackTraces = true, + bool AnalyzeAtomics = true) + : FunctionPass(ID), + InstrumentMemoryAccess(DetectDataRaces && ClInstrumentMemoryAccesses), + InstrumentFuncEntryExit(StackTraces && ClInstrumentFuncEntryExit), + InstrumentAtomics(AnalyzeAtomics && ClInstrumentAtomics), + InstrumentMemIntrinsics(DetectDataRaces && ClInstrumentMemIntrinsics) {} StringRef getPassName() const override; void getAnalysisUsage(AnalysisUsage &AU) const override; bool runOnFunction(Function &F) override; @@ -100,6 +107,10 @@ bool addrPointsToConstantData(Value *Addr); int getMemoryAccessFuncIndex(Value *Addr, const DataLayout &DL); + bool InstrumentMemoryAccess; + bool InstrumentFuncEntryExit; + bool InstrumentAtomics; + bool InstrumentMemIntrinsics; Type *IntptrTy; IntegerType *OrdTy; // Callbacks to run-time library are computed in doInitialization. @@ -141,8 +152,9 @@ AU.addRequired(); } -FunctionPass *llvm::createThreadSanitizerPass() { - return new ThreadSanitizer(); +FunctionPass *llvm::createThreadSanitizerPass( + bool DetectDataRaces, bool StackTraces, bool AnalyzeAtomics) { + return new ThreadSanitizer(DetectDataRaces, StackTraces, AnalyzeAtomics); } void ThreadSanitizer::initializeCallbacks(Module &M) { @@ -421,25 +433,25 @@ // (e.g. variables that do not escape, etc). // Instrument memory accesses only if we want to report bugs in the function. - if (ClInstrumentMemoryAccesses && SanitizeFunction) + if (InstrumentMemoryAccess && SanitizeFunction) for (auto Inst : AllLoadsAndStores) { Res |= instrumentLoadOrStore(Inst, DL); } // Instrument atomic memory accesses in any case (they can be used to // implement synchronization). - if (ClInstrumentAtomics) + if (InstrumentAtomics) for (auto Inst : AtomicAccesses) { Res |= instrumentAtomic(Inst, DL); } - if (ClInstrumentMemIntrinsics && SanitizeFunction) + if (InstrumentMemIntrinsics && SanitizeFunction) for (auto Inst : MemIntrinCalls) { Res |= instrumentMemIntrinsic(Inst); } // Instrument function entry/exit points if there were instrumented accesses. - if ((Res || HasCalls) && ClInstrumentFuncEntryExit) { + if ((Res || HasCalls) && InstrumentFuncEntryExit) { IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI()); Value *ReturnAddress = IRB.CreateCall( Intrinsic::getDeclaration(F.getParent(), Intrinsic::returnaddress),