diff options
author | Stephen Hines <srhines@google.com> | 2014-04-23 16:57:46 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-04-24 15:53:16 -0700 |
commit | 36b56886974eae4f9c5ebc96befd3e7bfe5de338 (patch) | |
tree | e6cfb69fbbd937f450eeb83bfb83b9da3b01275a /lib/Transforms/Instrumentation/ThreadSanitizer.cpp | |
parent | 69a8640022b04415ae9fac62f8ab090601d8f889 (diff) | |
download | external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.gz external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.bz2 external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.zip |
Update to LLVM 3.5a.
Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617
Diffstat (limited to 'lib/Transforms/Instrumentation/ThreadSanitizer.cpp')
-rw-r--r-- | lib/Transforms/Instrumentation/ThreadSanitizer.cpp | 53 |
1 files changed, 22 insertions, 31 deletions
diff --git a/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/lib/Transforms/Instrumentation/ThreadSanitizer.cpp index 89fb746a5c..5ffb17cbf3 100644 --- a/lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ b/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -78,12 +78,12 @@ namespace { struct ThreadSanitizer : public FunctionPass { ThreadSanitizer(StringRef BlacklistFile = StringRef()) : FunctionPass(ID), - TD(0), + DL(0), BlacklistFile(BlacklistFile.empty() ? ClBlacklistFile : BlacklistFile) { } - const char *getPassName() const; - bool runOnFunction(Function &F); - bool doInitialization(Module &M); + const char *getPassName() const override; + bool runOnFunction(Function &F) override; + bool doInitialization(Module &M) override; static char ID; // Pass identification, replacement for typeid. private: @@ -96,10 +96,10 @@ struct ThreadSanitizer : public FunctionPass { bool addrPointsToConstantData(Value *Addr); int getMemoryAccessFuncIndex(Value *Addr); - DataLayout *TD; + const DataLayout *DL; Type *IntptrTy; SmallString<64> BlacklistFile; - OwningPtr<SpecialCaseList> BL; + std::unique_ptr<SpecialCaseList> BL; IntegerType *OrdTy; // Callbacks to run-time library are computed in doInitialization. Function *TsanFuncEntry; @@ -224,14 +224,15 @@ void ThreadSanitizer::initializeCallbacks(Module &M) { } bool ThreadSanitizer::doInitialization(Module &M) { - TD = getAnalysisIfAvailable<DataLayout>(); - if (!TD) + DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>(); + if (!DLP) return false; + DL = &DLP->getDataLayout(); BL.reset(SpecialCaseList::createOrDie(BlacklistFile)); // Always insert a call to __tsan_init into the module's CTORs. IRBuilder<> IRB(M.getContext()); - IntptrTy = IRB.getIntPtrTy(TD); + IntptrTy = IRB.getIntPtrTy(DL); Value *TsanInit = M.getOrInsertFunction("__tsan_init", IRB.getVoidTy(), NULL); appendToGlobalCtors(M, cast<Function>(TsanInit), 0); @@ -320,7 +321,7 @@ static bool isAtomic(Instruction *I) { } bool ThreadSanitizer::runOnFunction(Function &F) { - if (!TD) return false; + if (!DL) return false; if (BL->isIn(F)) return false; initializeCallbacks(*F.getParent()); SmallVector<Instruction*, 8> RetVec; @@ -402,8 +403,13 @@ bool ThreadSanitizer::instrumentLoadOrStore(Instruction *I) { if (IsWrite && isVtableAccess(I)) { DEBUG(dbgs() << " VPTR : " << *I << "\n"); Value *StoredValue = cast<StoreInst>(I)->getValueOperand(); - // StoredValue does not necessary have a pointer type. - if (isa<IntegerType>(StoredValue->getType())) + // StoredValue may be a vector type if we are storing several vptrs at once. + // In this case, just take the first element of the vector since this is + // enough to find vptr races. + if (isa<VectorType>(StoredValue->getType())) + StoredValue = IRB.CreateExtractElement( + StoredValue, ConstantInt::get(IRB.getInt32Ty(), 0)); + if (StoredValue->getType()->isIntegerTy()) StoredValue = IRB.CreateIntToPtr(StoredValue, IRB.getInt8PtrTy()); // Call TsanVptrUpdate. IRB.CreateCall2(TsanVptrUpdate, @@ -440,21 +446,6 @@ static ConstantInt *createOrdering(IRBuilder<> *IRB, AtomicOrdering ord) { return IRB->getInt32(v); } -static ConstantInt *createFailOrdering(IRBuilder<> *IRB, AtomicOrdering ord) { - uint32_t v = 0; - switch (ord) { - case NotAtomic: assert(false); - case Unordered: // Fall-through. - case Monotonic: v = 0; break; - // case Consume: v = 1; break; // Not specified yet. - case Acquire: v = 2; break; - case Release: v = 0; break; - case AcquireRelease: v = 2; break; - case SequentiallyConsistent: v = 5; break; - } - return IRB->getInt32(v); -} - // If a memset intrinsic gets inlined by the code gen, we will miss races on it. // So, we either need to ensure the intrinsic is not inlined, or instrument it. // We do not instrument memset/memmove/memcpy intrinsics (too complicated), @@ -482,7 +473,7 @@ bool ThreadSanitizer::instrumentMemIntrinsic(Instruction *I) { } // Both llvm and ThreadSanitizer atomic operations are based on C++11/C1x -// standards. For background see C++11 standard. A slightly older, publically +// standards. For background see C++11 standard. A slightly older, publicly // available draft of the standard (not entirely up-to-date, but close enough // for casual browsing) is available here: // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf @@ -550,8 +541,8 @@ bool ThreadSanitizer::instrumentAtomic(Instruction *I) { Value *Args[] = {IRB.CreatePointerCast(Addr, PtrTy), IRB.CreateIntCast(CASI->getCompareOperand(), Ty, false), IRB.CreateIntCast(CASI->getNewValOperand(), Ty, false), - createOrdering(&IRB, CASI->getOrdering()), - createFailOrdering(&IRB, CASI->getOrdering())}; + createOrdering(&IRB, CASI->getSuccessOrdering()), + createOrdering(&IRB, CASI->getFailureOrdering())}; CallInst *C = CallInst::Create(TsanAtomicCAS[Idx], ArrayRef<Value*>(Args)); ReplaceInstWithInst(I, C); } else if (FenceInst *FI = dyn_cast<FenceInst>(I)) { @@ -568,7 +559,7 @@ int ThreadSanitizer::getMemoryAccessFuncIndex(Value *Addr) { Type *OrigPtrTy = Addr->getType(); Type *OrigTy = cast<PointerType>(OrigPtrTy)->getElementType(); assert(OrigTy->isSized()); - uint32_t TypeSize = TD->getTypeStoreSizeInBits(OrigTy); + uint32_t TypeSize = DL->getTypeStoreSizeInBits(OrigTy); if (TypeSize != 8 && TypeSize != 16 && TypeSize != 32 && TypeSize != 64 && TypeSize != 128) { NumAccessesWithBadSize++; |