#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/CFG.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/IR/DebugLoc.h"
#include "llvm/Pass.h"
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Support/raw_ostream.h"
#define DEBUG_TYPE "CDS"
using namespace llvm;
+#include "getPosition.hpp"
+
#define FUNCARRAYSIZE 4
STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
for (auto &I : B) {
if ( (&I)->isAtomic() || isAtomicCall(&I) ) {
AtomicAccesses.push_back(&I);
-
- const llvm::DebugLoc & debug_location = I.getDebugLoc();
- std::string position_string;
- {
- llvm::raw_string_ostream position_stream (position_string);
- debug_location . print (position_stream);
- }
-
- errs() << I << "\n" << (position_string) << "\n\n";
} else if (isa<LoadInst>(I) || isa<StoreInst>(I)) {
LocalLoadsAndStores.push_back(&I);
} else if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
return instrumentAtomicCall(CI, DL);
}
+ Value *position = getPosition(I, IRB);
+
if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
int atomic_order_index = getAtomicOrderIndex(SI->getOrdering());
Value *val = SI->getValueOperand();
Value *ptr = SI->getPointerOperand();
Value *order = ConstantInt::get(OrdTy, atomic_order_index);
- Value *args[] = {ptr, val, order};
+ Value *args[] = {ptr, val, order, position};
int size=getTypeSize(ptr->getType());
int index=sizetoindex(size);
- Instruction* funcInst=CallInst::Create(CDSAtomicStore[index], args,"");
+ Instruction* funcInst=CallInst::Create(CDSAtomicStore[index], args);
ReplaceInstWithInst(SI, funcInst);
// errs() << "Store replaced\n";
} else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
Value *ptr = LI->getPointerOperand();
Value *order = ConstantInt::get(OrdTy, atomic_order_index);
- Value *args[] = {ptr, order};
+ Value *args[] = {ptr, order, position};
int size=getTypeSize(ptr->getType());
int index=sizetoindex(size);
- Instruction* funcInst=CallInst::Create(CDSAtomicLoad[index], args, "");
+ Instruction* funcInst=CallInst::Create(CDSAtomicLoad[index], args);
ReplaceInstWithInst(LI, funcInst);
// errs() << "Load Replaced\n";
} else if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(I)) {
Value *val = RMWI->getValOperand();
Value *ptr = RMWI->getPointerOperand();
Value *order = ConstantInt::get(OrdTy, atomic_order_index);
- Value *args[] = {ptr, val, order};
+ Value *args[] = {ptr, val, order, position};
int size = getTypeSize(ptr->getType());
int index = sizetoindex(size);
- Instruction* funcInst = CallInst::Create(CDSAtomicRMW[RMWI->getOperation()][index], args, "");
+ Instruction* funcInst = CallInst::Create(CDSAtomicRMW[RMWI->getOperation()][index], args);
ReplaceInstWithInst(RMWI, funcInst);
// errs() << RMWI->getOperationName(RMWI->getOperation());
// errs() << " replaced\n";
Value *Args[] = {IRB.CreatePointerCast(Addr, PtrTy),
CmpOperand, NewOperand,
- order_succ, order_fail};
+ order_succ, order_fail, position};
CallInst *funcInst = IRB.CreateCall(CDSAtomicCAS_V1[index], Args);
Value *Success = IRB.CreateICmpEQ(funcInst, CmpOperand);
} else if (FenceInst *FI = dyn_cast<FenceInst>(I)) {
int atomic_order_index = getAtomicOrderIndex(FI->getOrdering());
Value *order = ConstantInt::get(OrdTy, atomic_order_index);
- Value *Args[] = {order};
+ Value *Args[] = {order, position};
CallInst *funcInst = CallInst::Create(CDSAtomicThreadFence, Args);
ReplaceInstWithInst(FI, funcInst);
CDSLoad[i] = M.getOrInsertFunction(LoadName, VoidTy, PtrTy);
CDSStore[i] = M.getOrInsertFunction(StoreName, VoidTy, PtrTy);
- CDSAtomicInit[i] = M.getOrInsertFunction(AtomicInitName, VoidTy, PtrTy, Ty);
- CDSAtomicLoad[i] = M.getOrInsertFunction(AtomicLoadName, Ty, PtrTy, OrdTy);
- CDSAtomicStore[i] = M.getOrInsertFunction(AtomicStoreName, VoidTy, PtrTy, Ty, OrdTy);
+ CDSAtomicInit[i] = M.getOrInsertFunction(AtomicInitName,
+ VoidTy, PtrTy, Ty, Int8PtrTy);
+ CDSAtomicLoad[i] = M.getOrInsertFunction(AtomicLoadName,
+ Ty, PtrTy, OrdTy, Int8PtrTy);
+ CDSAtomicStore[i] = M.getOrInsertFunction(AtomicStoreName,
+ VoidTy, PtrTy, Ty, OrdTy, Int8PtrTy);
for (int op = AtomicRMWInst::FIRST_BINOP;
op <= AtomicRMWInst::LAST_BINOP; ++op) {
continue;
SmallString<32> AtomicRMWName("cds_atomic" + NamePart + BitSizeStr);
- CDSAtomicRMW[op][i] = M.getOrInsertFunction(AtomicRMWName, Ty, PtrTy, Ty, OrdTy);
+ CDSAtomicRMW[op][i] = M.getOrInsertFunction(AtomicRMWName,
+ Ty, PtrTy, Ty, OrdTy, Int8PtrTy);
}
// only supportes strong version
SmallString<32> AtomicCASName_V1("cds_atomic_compare_exchange" + BitSizeStr + "_v1");
SmallString<32> AtomicCASName_V2("cds_atomic_compare_exchange" + BitSizeStr + "_v2");
CDSAtomicCAS_V1[i] = M.getOrInsertFunction(AtomicCASName_V1,
- Ty, PtrTy, Ty, Ty, OrdTy, OrdTy);
+ Ty, PtrTy, Ty, Ty, OrdTy, OrdTy, Int8PtrTy);
CDSAtomicCAS_V2[i] = M.getOrInsertFunction(AtomicCASName_V2,
- Int1Ty, PtrTy, PtrTy, Ty, OrdTy, OrdTy);
+ Int1Ty, PtrTy, PtrTy, Ty, OrdTy, OrdTy, Int8PtrTy);
}
- CDSAtomicThreadFence = M.getOrInsertFunction("cds_atomic_thread_fence", VoidTy, OrdTy);
+ CDSAtomicThreadFence = M.getOrInsertFunction("cds_atomic_thread_fence",
+ VoidTy, OrdTy, Int8PtrTy);
}
\ No newline at end of file
-bool containsStr() {
-
-}
-
bool CDSPass::instrumentAtomicCall(CallInst *CI, const DataLayout &DL) {
IRBuilder<> IRB(CI);
Function *fun = CI->getCalledFunction();
parameters.push_back(param);
}
+ // obtain source line number of the CallInst
+ Value *position = getPosition(CI, IRB);
+
// the pointer to the address is always the first argument
Value *OrigPtr = parameters[0];
int Idx = getMemoryAccessFuncIndex(OrigPtr, DL);
if (funName.contains("atomic_init")) {
Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
Value *val = IRB.CreateBitOrPointerCast(parameters[1], Ty);
- Value *args[] = {ptr, val};
+ Value *args[] = {ptr, val, position};
- Instruction* funcInst=CallInst::Create(CDSAtomicInit[Idx], args,"");
+ Instruction* funcInst=CallInst::Create(CDSAtomicInit[Idx], args);
ReplaceInstWithInst(CI, funcInst);
return true;
else
order = ConstantInt::get(OrdTy,
(int) AtomicOrderingCABI::seq_cst);
- Value *args[] = {ptr, order};
+ Value *args[] = {ptr, order, position};
- Instruction* funcInst=CallInst::Create(CDSAtomicLoad[Idx], args,"");
+ Instruction* funcInst=CallInst::Create(CDSAtomicLoad[Idx], args);
ReplaceInstWithInst(CI, funcInst);
return true;
else
order = ConstantInt::get(OrdTy,
(int) AtomicOrderingCABI::seq_cst);
- Value *args[] = {ptr, val, order};
+ 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
order = ConstantInt::get(OrdTy,
(int) AtomicOrderingCABI::seq_cst);
- Value *args[] = {ptr, val, order};
+ Value *args[] = {ptr, val, order, position};
- Instruction* funcInst=CallInst::Create(CDSAtomicRMW[op][Idx], args,"");
+ Instruction* funcInst=CallInst::Create(CDSAtomicRMW[op][Idx], args);
ReplaceInstWithInst(CI, funcInst);
return true;
}
Value *args[] = {Addr, CmpOperand, NewOperand,
- order_succ, order_fail};
+ order_succ, order_fail, position};
- Instruction* funcInst=CallInst::Create(CDSAtomicCAS_V2[Idx], args,"");
+ Instruction* funcInst=CallInst::Create(CDSAtomicCAS_V2[Idx], args);
ReplaceInstWithInst(CI, funcInst);
return true;
if ( (CI->isTailCall() && funName.contains("atomic_")) ||
funName.contains("atomic_compare_exchange_") ) {
- printArgs(CI);
+ // printArgs(CI);
return true;
}
}
User::op_iterator begin = CI->arg_begin();
User::op_iterator end = CI->arg_end();
- if (funName.find("atomic_") != -1) {
+ if ( funName.contains("atomic_") ) {
std::vector<Value *> parameters;
for (User::op_iterator it = begin; it != end; ++it) {