From: weiyu Date: Mon, 22 Jul 2019 22:54:13 +0000 (-0700) Subject: instrument volatile loads and stores X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11llvm.git;a=commitdiff_plain;h=cb1091fe29c2079becb1318f66019a9df1f9c4b7 instrument volatile loads and stores --- diff --git a/CDSPass.cpp b/CDSPass.cpp index c0bd244..dede6bc 100644 --- a/CDSPass.cpp +++ b/CDSPass.cpp @@ -89,6 +89,7 @@ Type * Int64PtrTy; Type * VoidTy; static const size_t kNumberOfAccessSizes = 4; +static const int volatile_order = 6; int getAtomicOrderIndex(AtomicOrdering order){ switch (order) { @@ -119,6 +120,7 @@ namespace { private: void initializeCallbacks(Module &M); bool instrumentLoadOrStore(Instruction *I, const DataLayout &DL); + bool instrumentVolatile(Instruction *I, const DataLayout &DL); bool isAtomicCall(Instruction *I); bool instrumentAtomic(Instruction *I, const DataLayout &DL); bool instrumentAtomicCall(CallInst *CI, const DataLayout &DL); @@ -134,6 +136,8 @@ namespace { Constant * CDSLoad[kNumberOfAccessSizes]; Constant * CDSStore[kNumberOfAccessSizes]; + Constant * CDSVolatileLoad[kNumberOfAccessSizes]; + Constant * CDSVolatileStore[kNumberOfAccessSizes]; Constant * CDSAtomicInit[kNumberOfAccessSizes]; Constant * CDSAtomicLoad[kNumberOfAccessSizes]; Constant * CDSAtomicStore[kNumberOfAccessSizes]; @@ -186,12 +190,18 @@ void CDSPass::initializeCallbacks(Module &M) { // void cds_atomic_store8 (void * obj, int atomic_index, uint8_t val) SmallString<32> LoadName("cds_load" + BitSizeStr); SmallString<32> StoreName("cds_store" + BitSizeStr); + SmallString<32> VolatileLoadName("cds_volatile_load" + BitSizeStr); + SmallString<32> VolatileStoreName("cds_volatile_store" + BitSizeStr); SmallString<32> AtomicInitName("cds_atomic_init" + BitSizeStr); SmallString<32> AtomicLoadName("cds_atomic_load" + BitSizeStr); SmallString<32> AtomicStoreName("cds_atomic_store" + BitSizeStr); CDSLoad[i] = M.getOrInsertFunction(LoadName, VoidTy, PtrTy); CDSStore[i] = M.getOrInsertFunction(StoreName, VoidTy, PtrTy); + CDSVolatileLoad[i] = M.getOrInsertFunction(VolatileLoadName, + Ty, PtrTy, OrdTy, Int8PtrTy); + CDSVolatileStore[i] = M.getOrInsertFunction(VolatileStoreName, + VoidTy, PtrTy, Ty, OrdTy, Int8PtrTy); CDSAtomicInit[i] = M.getOrInsertFunction(AtomicInitName, VoidTy, PtrTy, Ty, Int8PtrTy); CDSAtomicLoad[i] = M.getOrInsertFunction(AtomicLoadName, @@ -311,6 +321,7 @@ bool CDSPass::runOnFunction(Function &F) { SmallVector AllLoadsAndStores; SmallVector LocalLoadsAndStores; + SmallVector VolatileLoadsAndStores; SmallVector AtomicAccesses; std::vector worklist; @@ -327,7 +338,14 @@ bool CDSPass::runOnFunction(Function &F) { AtomicAccesses.push_back(&I); HasAtomic = true; } else if (isa(I) || isa(I)) { - LocalLoadsAndStores.push_back(&I); + LoadInst *LI = dyn_cast(&I); + StoreInst *SI = dyn_cast(&I); + bool isVolatile = ( LI ? LI->isVolatile() : SI->isVolatile() ); + + if (isVolatile) + VolatileLoadsAndStores.push_back(&I); + else + LocalLoadsAndStores.push_back(&I); } else if (isa(I) || isa(I)) { // not implemented yet } @@ -340,6 +358,10 @@ bool CDSPass::runOnFunction(Function &F) { Res |= instrumentLoadOrStore(Inst, DL); } + for (auto Inst : VolatileLoadsAndStores) { + Res |= instrumentVolatile(Inst, DL); + } + for (auto Inst : AtomicAccesses) { Res |= instrumentAtomic(Inst, DL); } @@ -363,6 +385,8 @@ bool CDSPass::runOnFunction(Function &F) { Res = true; } + + F.dump(); } return false; @@ -473,10 +497,42 @@ bool CDSPass::instrumentLoadOrStore(Instruction *I, return true; } -bool CDSPass::instrumentAtomic(Instruction * I, const DataLayout &DL) { +bool CDSPass::instrumentVolatile(Instruction * I, const DataLayout &DL) { IRBuilder<> IRB(I); + Value *position = getPosition(I, IRB); + + if (LoadInst *LI = dyn_cast(I)) { + assert( LI->isVolatile() ); + Value *Addr = LI->getPointerOperand(); + int Idx=getMemoryAccessFuncIndex(Addr, DL); + if (Idx < 0) + return false; + + Value *order = ConstantInt::get(OrdTy, volatile_order); + Value *args[] = {Addr, order, position}; + Instruction* funcInst=CallInst::Create(CDSVolatileLoad[Idx], args); + ReplaceInstWithInst(LI, funcInst); + } else if (StoreInst *SI = dyn_cast(I)) { + assert( SI->isVolatile() ); + Value *Addr = SI->getPointerOperand(); + int Idx=getMemoryAccessFuncIndex(Addr, DL); + if (Idx < 0) + return false; - // errs() << "instrumenting: " << *I << "\n"; + Value *val = SI->getValueOperand(); + Value *order = ConstantInt::get(OrdTy, volatile_order); + Value *args[] = {Addr, val, order, position}; + Instruction* funcInst=CallInst::Create(CDSVolatileStore[Idx], args); + ReplaceInstWithInst(SI, funcInst); + } else { + return false; + } + + return true; +} + +bool CDSPass::instrumentAtomic(Instruction * I, const DataLayout &DL) { + IRBuilder<> IRB(I); if (auto *CI = dyn_cast(I)) { return instrumentAtomicCall(CI, DL);