diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
commit | 145449b1e420787bb99721a429341fa6be3adfb6 (patch) | |
tree | 1d56ae694a6de602e348dd80165cf881a36600ed /llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp | |
parent | ecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff) |
Diffstat (limited to 'llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp')
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp | 84 |
1 files changed, 17 insertions, 67 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp index 180012198c42..c33b1b3b1a5c 100644 --- a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -38,7 +38,6 @@ #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" -#include "llvm/InitializePasses.h" #include "llvm/ProfileData/InstrProf.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -174,19 +173,6 @@ private: FunctionCallee MemmoveFn, MemcpyFn, MemsetFn; }; -struct ThreadSanitizerLegacyPass : FunctionPass { - ThreadSanitizerLegacyPass() : FunctionPass(ID) { - initializeThreadSanitizerLegacyPassPass(*PassRegistry::getPassRegistry()); - } - 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; -}; - void insertModuleCtor(Module &M) { getOrCreateSanitizerCtorAndInitFunctions( M, kTsanModuleCtorName, kTsanInitName, /*InitArgTypes=*/{}, @@ -195,7 +181,6 @@ void insertModuleCtor(Module &M) { // time. Hook them into the global ctors list in that case: [&](Function *Ctor, FunctionCallee) { appendToGlobalCtors(M, Ctor, 0); }); } - } // namespace PreservedAnalyses ThreadSanitizerPass::run(Function &F, @@ -211,38 +196,6 @@ PreservedAnalyses ModuleThreadSanitizerPass::run(Module &M, insertModuleCtor(M); return PreservedAnalyses::none(); } - -char ThreadSanitizerLegacyPass::ID = 0; -INITIALIZE_PASS_BEGIN(ThreadSanitizerLegacyPass, "tsan", - "ThreadSanitizer: detects data races.", false, false) -INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_PASS_END(ThreadSanitizerLegacyPass, "tsan", - "ThreadSanitizer: detects data races.", false, false) - -StringRef ThreadSanitizerLegacyPass::getPassName() const { - return "ThreadSanitizerLegacyPass"; -} - -void ThreadSanitizerLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<TargetLibraryInfoWrapperPass>(); -} - -bool ThreadSanitizerLegacyPass::doInitialization(Module &M) { - insertModuleCtor(M); - TSan.emplace(); - return true; -} - -bool ThreadSanitizerLegacyPass::runOnFunction(Function &F) { - auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F); - TSan->sanitizeFunction(F, TLI); - return true; -} - -FunctionPass *llvm::createThreadSanitizerLegacyPassPass() { - return new ThreadSanitizerLegacyPass(); -} - void ThreadSanitizer::initialize(Module &M) { const DataLayout &DL = M.getDataLayout(); IntptrTy = DL.getIntPtrType(M.getContext()); @@ -527,26 +480,22 @@ void ThreadSanitizer::chooseInstructionsToInstrument( Local.clear(); } -static bool isAtomic(Instruction *I) { +static bool isTsanAtomic(const Instruction *I) { // TODO: Ask TTI whether synchronization scope is between threads. - if (LoadInst *LI = dyn_cast<LoadInst>(I)) - return LI->isAtomic() && LI->getSyncScopeID() != SyncScope::SingleThread; - if (StoreInst *SI = dyn_cast<StoreInst>(I)) - return SI->isAtomic() && SI->getSyncScopeID() != SyncScope::SingleThread; - if (isa<AtomicRMWInst>(I)) - return true; - if (isa<AtomicCmpXchgInst>(I)) - return true; - if (isa<FenceInst>(I)) - return true; - return false; + auto SSID = getAtomicSyncScopeID(I); + if (!SSID) + return false; + if (isa<LoadInst>(I) || isa<StoreInst>(I)) + return SSID.getValue() != SyncScope::SingleThread; + return true; } void ThreadSanitizer::InsertRuntimeIgnores(Function &F) { - IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI()); + InstrumentationIRBuilder IRB(F.getEntryBlock().getFirstNonPHI()); IRB.CreateCall(TsanIgnoreBegin); EscapeEnumerator EE(F, "tsan_ignore_cleanup", ClHandleCxxExceptions); while (IRBuilder<> *AtExit = EE.Next()) { + InstrumentationIRBuilder::ensureDebugInfo(*AtExit, F); AtExit->CreateCall(TsanIgnoreEnd); } } @@ -581,7 +530,7 @@ bool ThreadSanitizer::sanitizeFunction(Function &F, // Traverse all instructions, collect loads/stores/returns, check for calls. for (auto &BB : F) { for (auto &Inst : BB) { - if (isAtomic(&Inst)) + if (isTsanAtomic(&Inst)) AtomicAccesses.push_back(&Inst); else if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst)) LocalLoadsAndStores.push_back(&Inst); @@ -629,7 +578,7 @@ bool ThreadSanitizer::sanitizeFunction(Function &F, // Instrument function entry/exit points if there were instrumented accesses. if ((Res || HasCalls) && ClInstrumentFuncEntryExit) { - IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI()); + InstrumentationIRBuilder IRB(F.getEntryBlock().getFirstNonPHI()); Value *ReturnAddress = IRB.CreateCall( Intrinsic::getDeclaration(F.getParent(), Intrinsic::returnaddress), IRB.getInt32(0)); @@ -637,6 +586,7 @@ bool ThreadSanitizer::sanitizeFunction(Function &F, EscapeEnumerator EE(F, "tsan_cleanup", ClHandleCxxExceptions); while (IRBuilder<> *AtExit = EE.Next()) { + InstrumentationIRBuilder::ensureDebugInfo(*AtExit, F); AtExit->CreateCall(TsanFuncExit, {}); } Res = true; @@ -646,7 +596,7 @@ bool ThreadSanitizer::sanitizeFunction(Function &F, bool ThreadSanitizer::instrumentLoadOrStore(const InstructionInfo &II, const DataLayout &DL) { - IRBuilder<> IRB(II.Inst); + InstrumentationIRBuilder IRB(II.Inst); const bool IsWrite = isa<StoreInst>(*II.Inst); Value *Addr = IsWrite ? cast<StoreInst>(II.Inst)->getPointerOperand() : cast<LoadInst>(II.Inst)->getPointerOperand(); @@ -686,8 +636,8 @@ bool ThreadSanitizer::instrumentLoadOrStore(const InstructionInfo &II, return true; } - const unsigned Alignment = IsWrite ? cast<StoreInst>(II.Inst)->getAlignment() - : cast<LoadInst>(II.Inst)->getAlignment(); + const Align Alignment = IsWrite ? cast<StoreInst>(II.Inst)->getAlign() + : cast<LoadInst>(II.Inst)->getAlign(); const bool IsCompoundRW = ClCompoundReadBeforeWrite && (II.Flags & InstructionInfo::kCompoundRW); const bool IsVolatile = ClDistinguishVolatile && @@ -697,7 +647,7 @@ bool ThreadSanitizer::instrumentLoadOrStore(const InstructionInfo &II, const uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy); FunctionCallee OnAccessFunc = nullptr; - if (Alignment == 0 || Alignment >= 8 || (Alignment % (TypeSize / 8)) == 0) { + if (Alignment >= Align(8) || (Alignment.value() % (TypeSize / 8)) == 0) { if (IsCompoundRW) OnAccessFunc = TsanCompoundRW[Idx]; else if (IsVolatile) @@ -775,7 +725,7 @@ bool ThreadSanitizer::instrumentMemIntrinsic(Instruction *I) { // http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/ bool ThreadSanitizer::instrumentAtomic(Instruction *I, const DataLayout &DL) { - IRBuilder<> IRB(I); + InstrumentationIRBuilder IRB(I); if (LoadInst *LI = dyn_cast<LoadInst>(I)) { Value *Addr = LI->getPointerOperand(); Type *OrigTy = LI->getType(); |