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 InstrumentMemoryAccess = true, + bool InstrumentFuncEntryExit = true, + bool InstrumentAtomics = 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,18 @@ /// ThreadSanitizer: instrument the code in module to find races. struct ThreadSanitizer : public FunctionPass { - ThreadSanitizer() : FunctionPass(ID) {} + ThreadSanitizer(bool InstrumentMemoryAccess = true, + bool InstrumentFuncEntryExit = true, + bool InstrumentAtomics = true) + : FunctionPass(ID), + InstrumentMemoryAccess( + InstrumentMemoryAccess && ClInstrumentMemoryAccesses), + InstrumentFuncEntryExit( + InstrumentFuncEntryExit && ClInstrumentFuncEntryExit), + InstrumentAtomics( + InstrumentAtomics && ClInstrumentAtomics), + InstrumentMemIntrinsics( + InstrumentMemoryAccess && ClInstrumentMemIntrinsics) {} StringRef getPassName() const override; void getAnalysisUsage(AnalysisUsage &AU) const override; bool runOnFunction(Function &F) override; @@ -100,6 +111,10 @@ bool addrPointsToConstantData(Value *Addr); int getMemoryAccessFuncIndex(Value *Addr, const DataLayout &DL); + const bool InstrumentMemoryAccess; + const bool InstrumentFuncEntryExit; + const bool InstrumentAtomics; + const bool InstrumentMemIntrinsics; Type *IntptrTy; IntegerType *OrdTy; // Callbacks to run-time library are computed in doInitialization. @@ -141,8 +156,11 @@ AU.addRequired(); } -FunctionPass *llvm::createThreadSanitizerPass() { - return new ThreadSanitizer(); +FunctionPass *llvm::createThreadSanitizerPass( + bool InstrumentMemoryAccess, bool InstrumentFuncEntryExit, + bool InstrumentAtomics) { + return new ThreadSanitizer( + InstrumentMemoryAccess, InstrumentFuncEntryExit, InstrumentAtomics); } void ThreadSanitizer::initializeCallbacks(Module &M) { @@ -421,25 +439,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),