5 bool CDSPass::instrumentAtomicCall(CallInst *CI, const DataLayout &DL) {
7 Function *fun = CI->getCalledFunction();
8 StringRef funName = fun->getName();
9 std::vector<Value *> parameters;
11 User::op_iterator begin = CI->arg_begin();
12 User::op_iterator end = CI->arg_end();
13 for (User::op_iterator it = begin; it != end; ++it) {
15 parameters.push_back(param);
18 // the pointer to the address is always the first argument
19 Value *OrigPtr = parameters[0];
20 int Idx = getMemoryAccessFuncIndex(OrigPtr, DL);
24 const unsigned ByteSize = 1U << Idx;
25 const unsigned BitSize = ByteSize * 8;
26 Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
27 Type *PtrTy = Ty->getPointerTo();
29 // atomic_init; args = {obj, order}
30 if (funName.contains("atomic_init")) {
31 Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
32 Value *val = IRB.CreateBitOrPointerCast(parameters[1], Ty);
33 Value *args[] = {ptr, val};
35 Instruction* funcInst=CallInst::Create(CDSAtomicInit[Idx], args,"");
36 ReplaceInstWithInst(CI, funcInst);
41 // atomic_load; args = {obj, order}
42 if (funName.contains("atomic_load")) {
43 bool isExplicit = funName.contains("atomic_load_explicit");
45 Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
48 order = IRB.CreateBitOrPointerCast(parameters[1], OrdTy);
50 order = ConstantInt::get(OrdTy,
51 (int) AtomicOrderingCABI::seq_cst);
52 Value *args[] = {ptr, order};
54 Instruction* funcInst=CallInst::Create(CDSAtomicLoad[Idx], args,"");
55 ReplaceInstWithInst(CI, funcInst);
60 // atomic_store; args = {obj, val, order}
61 if (funName.contains("atomic_store")) {
62 bool isExplicit = funName.contains("atomic_store_explicit");
63 Value *OrigVal = parameters[1];
65 Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
66 Value *val = IRB.CreatePointerCast(OrigVal, Ty);
69 order = IRB.CreateBitOrPointerCast(parameters[2], OrdTy);
71 order = ConstantInt::get(OrdTy,
72 (int) AtomicOrderingCABI::seq_cst);
73 Value *args[] = {ptr, val, order};
75 Instruction* funcInst=CallInst::Create(CDSAtomicStore[Idx], args,"");
76 ReplaceInstWithInst(CI, funcInst);
81 // atomic_fetch_*; args = {obj, val, order}
82 if (funName.contains("atomic_fetch_") ||
83 funName.contains("atomic_exchange") ) {
84 bool isExplicit = funName.contains("_explicit");
85 Value *OrigVal = parameters[1];
88 if ( funName.contains("_fetch_add") )
89 op = AtomicRMWInst::Add;
90 else if ( funName.contains("_fetch_sub") )
91 op = AtomicRMWInst::Sub;
92 else if ( funName.contains("_fetch_and") )
93 op = AtomicRMWInst::And;
94 else if ( funName.contains("_fetch_or") )
95 op = AtomicRMWInst::Or;
96 else if ( funName.contains("_fetch_xor") )
97 op = AtomicRMWInst::Xor;
98 else if ( funName.contains("atomic_exchange") )
99 op = AtomicRMWInst::Xchg;
101 errs() << "Unknown atomic read modify write operation\n";
105 Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
106 Value *val = IRB.CreatePointerCast(OrigVal, Ty);
109 order = IRB.CreateBitOrPointerCast(parameters[2], OrdTy);
111 order = ConstantInt::get(OrdTy,
112 (int) AtomicOrderingCABI::seq_cst);
113 Value *args[] = {ptr, val, order};
115 Instruction* funcInst=CallInst::Create(CDSAtomicRMW[op][Idx], args,"");
116 ReplaceInstWithInst(CI, funcInst);
121 /* atomic_compare_exchange_*;
122 args = {obj, expected, new value, order1, order2}
124 if ( funName.contains("atomic_compare_exchange_") ) {
125 bool isExplicit = funName.contains("_explicit");
127 Value *Addr = IRB.CreatePointerCast(OrigPtr, PtrTy);
128 Value *CmpOperand = IRB.CreatePointerCast(parameters[1], PtrTy);
129 Value *NewOperand = IRB.CreateBitOrPointerCast(parameters[2], Ty);
131 Value *order_succ, *order_fail;
133 order_succ = IRB.CreateBitOrPointerCast(parameters[3], OrdTy);
134 order_fail = IRB.CreateBitOrPointerCast(parameters[4], OrdTy);
136 order_succ = ConstantInt::get(OrdTy,
137 (int) AtomicOrderingCABI::seq_cst);
138 order_fail = ConstantInt::get(OrdTy,
139 (int) AtomicOrderingCABI::seq_cst);
142 Value *args[] = {Addr, CmpOperand, NewOperand,
143 order_succ, order_fail};
145 Instruction* funcInst=CallInst::Create(CDSAtomicCAS_V2[Idx], args,"");
146 ReplaceInstWithInst(CI, funcInst);