From 84b9cc1cf068b080db61e377d8cef369f09a4b51 Mon Sep 17 00:00:00 2001 From: weiyu Date: Thu, 20 Jun 2019 15:55:54 -0700 Subject: [PATCH 1/1] add support for libcds atomic function calls --- getPosition.hpp | 12 ++++++++ instrumentAtomicCall.hpp | 61 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/getPosition.hpp b/getPosition.hpp index f26d172..afc00c6 100644 --- a/getPosition.hpp +++ b/getPosition.hpp @@ -17,3 +17,15 @@ Value *getPosition( Instruction * I, IRBuilder <> IRB) return IRB . CreateGlobalStringPtr (position_string); } + +Value *getPositionPrint( Instruction * I, IRBuilder <> IRB) +{ + const DebugLoc & debug_location = I->getDebugLoc (); + std::string position_string; + { + llvm::raw_string_ostream position_stream (position_string); + debug_location . print (position_stream); + } + errs() << position_string << "\n"; + return IRB . CreateGlobalStringPtr (position_string); +} \ No newline at end of file diff --git a/instrumentAtomicCall.hpp b/instrumentAtomicCall.hpp index 9052013..4ee6d8d 100644 --- a/instrumentAtomicCall.hpp +++ b/instrumentAtomicCall.hpp @@ -1,3 +1,5 @@ +// todo: come up with better rules for function name checking + bool CDSPass::instrumentAtomicCall(CallInst *CI, const DataLayout &DL) { IRBuilder<> IRB(CI); Function *fun = CI->getCalledFunction(); @@ -53,6 +55,21 @@ bool CDSPass::instrumentAtomicCall(CallInst *CI, const DataLayout &DL) { Instruction* funcInst=CallInst::Create(CDSAtomicLoad[Idx], args); ReplaceInstWithInst(CI, funcInst); + return true; + } else if (funName.contains("atomic") && + funName.contains("load")) { + // does this version of call always have an atomic order as an argument? + Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy); + Value *order = IRB.CreateBitOrPointerCast(parameters[1], OrdTy); + Value *args[] = {ptr, order, position}; + + //Instruction* funcInst=CallInst::Create(CDSAtomicLoad[Idx], args); + CallInst *funcInst = IRB.CreateCall(CDSAtomicLoad[Idx], args); + Value *RetVal = IRB.CreateIntToPtr(funcInst, CI->getType()); + + CI->replaceAllUsesWith(RetVal); + CI->eraseFromParent(); + return true; } @@ -71,9 +88,23 @@ bool CDSPass::instrumentAtomicCall(CallInst *CI, const DataLayout &DL) { (int) AtomicOrderingCABI::seq_cst); Value *args[] = {ptr, val, order, position}; - Instruction* funcInst=CallInst::Create(CDSAtomicStore[Idx], args); + Instruction* funcInst = CallInst::Create(CDSAtomicStore[Idx], args); ReplaceInstWithInst(CI, funcInst); + return true; + } else if (funName.contains("atomic") && + funName.contains("store")) { + // does this version of call always have an atomic order as an argument? + Value *OrigVal = parameters[1]; + + Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy); + Value *val = IRB.CreatePointerCast(OrigVal, Ty); + Value *order = IRB.CreateBitOrPointerCast(parameters[1], OrdTy); + Value *args[] = {ptr, val, order, position}; + + Instruction* funcInst = CallInst::Create(CDSAtomicStore[Idx], args); + ReplaceInstWithInst(CI, funcInst); + return true; } @@ -115,7 +146,16 @@ bool CDSPass::instrumentAtomicCall(CallInst *CI, const DataLayout &DL) { ReplaceInstWithInst(CI, funcInst); return true; - } + } else if (funName.contains("fetch")) { + errs() << "atomic exchange captured. Not implemented yet. " + errs() << "See source file :"; + getPositionPrint(CI, IRB); + } else if (funName.contains("exchange") && + !funName.contains("compare_exchange") ) { + errs() << "atomic exchange captured. Not implemented yet. " + errs() << "See source file :"; + getPositionPrint(CI, IRB); + } /* atomic_compare_exchange_*; args = {obj, expected, new value, order1, order2} @@ -144,6 +184,23 @@ bool CDSPass::instrumentAtomicCall(CallInst *CI, const DataLayout &DL) { Instruction* funcInst=CallInst::Create(CDSAtomicCAS_V2[Idx], args); ReplaceInstWithInst(CI, funcInst); + return true; + } else if ( funName.contains("compare_exchange_strong") || + funName.contains("compare_exchange_wesk") ) { + + Value *Addr = IRB.CreatePointerCast(OrigPtr, PtrTy); + Value *CmpOperand = IRB.CreatePointerCast(parameters[1], PtrTy); + Value *NewOperand = IRB.CreateBitOrPointerCast(parameters[2], Ty); + + Value *order_succ, *order_fail; + order_succ = IRB.CreateBitOrPointerCast(parameters[3], OrdTy); + order_fail = IRB.CreateBitOrPointerCast(parameters[4], OrdTy); + + Value *args[] = {Addr, CmpOperand, NewOperand, + order_succ, order_fail, position}; + Instruction* funcInst=CallInst::Create(CDSAtomicCAS_V2[Idx], args); + ReplaceInstWithInst(CI, funcInst); + return true; } -- 2.34.1