remove rename main
[c11llvm.git] / CDSPass.cpp
1 //===-- CDSPass.cpp - xxx -------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // This file is a modified version of ThreadSanitizer.cpp, a part of a race detector.
12 //
13 // The tool is under development, for the details about previous versions see
14 // http://code.google.com/p/data-race-test
15 //
16 // The instrumentation phase is quite simple:
17 //   - Insert calls to run-time library before every memory access.
18 //      - Optimizations may apply to avoid instrumenting some of the accesses.
19 //   - Insert calls at function entry/exit.
20 // The rest is handled by the run-time library.
21 //===----------------------------------------------------------------------===//
22
23 #include "llvm/ADT/Statistic.h"
24 #include "llvm/ADT/StringExtras.h"
25 #include "llvm/ADT/SmallString.h"
26 #include "llvm/Analysis/ValueTracking.h"
27 #include "llvm/Analysis/CaptureTracking.h"
28 #include "llvm/IR/BasicBlock.h"
29 #include "llvm/IR/Function.h"
30 #include "llvm/IR/IRBuilder.h"
31 #include "llvm/IR/Instructions.h"
32 #include "llvm/IR/IntrinsicInst.h"
33 #include "llvm/IR/LLVMContext.h"
34 #include "llvm/IR/LegacyPassManager.h"
35 #include "llvm/IR/Module.h"
36 #include "llvm/IR/PassManager.h"
37 #include "llvm/Pass.h"
38 #include "llvm/ProfileData/InstrProf.h"
39 #include "llvm/Support/raw_ostream.h"
40 #include "llvm/Support/AtomicOrdering.h"
41 #include "llvm/Support/Debug.h"
42 #include "llvm/Transforms/Scalar.h"
43 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
44 #include "llvm/Transforms/Utils/EscapeEnumerator.h"
45 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
46 #include <vector>
47
48 using namespace llvm;
49
50 #define DEBUG_TYPE "CDS"
51 #include <llvm/IR/DebugLoc.h>
52
53 Value *getPosition( Instruction * I, IRBuilder <> IRB, bool print = false)
54 {
55         const DebugLoc & debug_location = I->getDebugLoc ();
56         std::string position_string;
57         {
58                 llvm::raw_string_ostream position_stream (position_string);
59                 debug_location . print (position_stream);
60         }
61
62         if (print) {
63                 errs() << position_string << "\n";
64         }
65
66         return IRB.CreateGlobalStringPtr (position_string);
67 }
68
69 STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
70 STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
71 STATISTIC(NumOmittedReadsBeforeWrite,
72           "Number of reads ignored due to following writes");
73 STATISTIC(NumAccessesWithBadSize, "Number of accesses with bad size");
74 // STATISTIC(NumInstrumentedVtableWrites, "Number of vtable ptr writes");
75 // STATISTIC(NumInstrumentedVtableReads, "Number of vtable ptr reads");
76 STATISTIC(NumOmittedReadsFromConstantGlobals,
77           "Number of reads from constant globals");
78 STATISTIC(NumOmittedReadsFromVtable, "Number of vtable reads");
79 STATISTIC(NumOmittedNonCaptured, "Number of accesses ignored due to capturing");
80
81 // static const char *const kCDSModuleCtorName = "cds.module_ctor";
82 // static const char *const kCDSInitName = "cds_init";
83
84 Type * OrdTy;
85 Type * IntPtrTy;
86 Type * Int8PtrTy;
87 Type * Int16PtrTy;
88 Type * Int32PtrTy;
89 Type * Int64PtrTy;
90
91 Type * VoidTy;
92
93 static const size_t kNumberOfAccessSizes = 4;
94
95 int getAtomicOrderIndex(AtomicOrdering order) {
96         switch (order) {
97                 case AtomicOrdering::Monotonic: 
98                         return (int)AtomicOrderingCABI::relaxed;
99                 //  case AtomicOrdering::Consume:         // not specified yet
100                 //    return AtomicOrderingCABI::consume;
101                 case AtomicOrdering::Acquire: 
102                         return (int)AtomicOrderingCABI::acquire;
103                 case AtomicOrdering::Release: 
104                         return (int)AtomicOrderingCABI::release;
105                 case AtomicOrdering::AcquireRelease: 
106                         return (int)AtomicOrderingCABI::acq_rel;
107                 case AtomicOrdering::SequentiallyConsistent: 
108                         return (int)AtomicOrderingCABI::seq_cst;
109                 default:
110                         // unordered or Not Atomic
111                         return -1;
112         }
113 }
114
115 AtomicOrderingCABI indexToAtomicOrder(int index) {
116         switch (index) {
117                 case 0:
118                         return AtomicOrderingCABI::relaxed;
119                 case 1:
120                         return AtomicOrderingCABI::consume;
121                 case 2:
122                         return AtomicOrderingCABI::acquire;
123                 case 3:
124                         return AtomicOrderingCABI::release;
125                 case 4:
126                         return AtomicOrderingCABI::acq_rel;
127                 case 5:
128                         return AtomicOrderingCABI::seq_cst;
129                 default:
130                         errs() << "Bad Atomic index\n";
131                         return AtomicOrderingCABI::seq_cst;
132         }
133 }
134
135 /* According to atomic_base.h: __cmpexch_failure_order */
136 int AtomicCasFailureOrderIndex(int index) {
137         AtomicOrderingCABI succ_order = indexToAtomicOrder(index);
138         AtomicOrderingCABI fail_order;
139         if (succ_order == AtomicOrderingCABI::acq_rel)
140                 fail_order = AtomicOrderingCABI::acquire;
141         else if (succ_order == AtomicOrderingCABI::release) 
142                 fail_order = AtomicOrderingCABI::relaxed;
143         else
144                 fail_order = succ_order;
145
146         return (int) fail_order;
147 }
148
149 /* The original function checkSanitizerInterfaceFunction was defined
150  * in llvm/Transforms/Utils/ModuleUtils.h
151  */
152 static Function * checkCDSPassInterfaceFunction(Constant *FuncOrBitcast) {
153         if (isa<Function>(FuncOrBitcast))
154                 return cast<Function>(FuncOrBitcast);
155         FuncOrBitcast->print(errs());
156         errs() << '\n';
157         std::string Err;
158         raw_string_ostream Stream(Err);
159         Stream << "CDSPass interface function redefined: " << *FuncOrBitcast;
160         report_fatal_error(Err);
161 }
162
163 namespace {
164         struct CDSPass : public FunctionPass {
165                 CDSPass() : FunctionPass(ID) {}
166                 StringRef getPassName() const override;
167                 bool runOnFunction(Function &F) override;
168                 bool doInitialization(Module &M) override;
169                 static char ID;
170
171         private:
172                 void initializeCallbacks(Module &M);
173                 bool instrumentLoadOrStore(Instruction *I, const DataLayout &DL);
174                 bool instrumentVolatile(Instruction *I, const DataLayout &DL);
175                 bool instrumentMemIntrinsic(Instruction *I);
176                 bool isAtomicCall(Instruction *I);
177                 bool instrumentAtomic(Instruction *I, const DataLayout &DL);
178                 bool instrumentAtomicCall(CallInst *CI, const DataLayout &DL);
179                 bool shouldInstrumentBeforeAtomics(Instruction *I);
180                 void chooseInstructionsToInstrument(SmallVectorImpl<Instruction *> &Local,
181                                                                                         SmallVectorImpl<Instruction *> &All,
182                                                                                         const DataLayout &DL);
183                 bool addrPointsToConstantData(Value *Addr);
184                 int getMemoryAccessFuncIndex(Value *Addr, const DataLayout &DL);
185
186                 Function * CDSFuncEntry;
187                 Function * CDSFuncExit;
188
189                 Function * CDSLoad[kNumberOfAccessSizes];
190                 Function * CDSStore[kNumberOfAccessSizes];
191                 Function * CDSVolatileLoad[kNumberOfAccessSizes];
192                 Function * CDSVolatileStore[kNumberOfAccessSizes];
193                 Function * CDSAtomicInit[kNumberOfAccessSizes];
194                 Function * CDSAtomicLoad[kNumberOfAccessSizes];
195                 Function * CDSAtomicStore[kNumberOfAccessSizes];
196                 Function * CDSAtomicRMW[AtomicRMWInst::LAST_BINOP + 1][kNumberOfAccessSizes];
197                 Function * CDSAtomicCAS_V1[kNumberOfAccessSizes];
198                 Function * CDSAtomicCAS_V2[kNumberOfAccessSizes];
199                 Function * CDSAtomicThreadFence;
200                 Function * MemmoveFn, * MemcpyFn, * MemsetFn;
201                 // Function * CDSCtorFunction;
202
203                 std::vector<StringRef> AtomicFuncNames;
204                 std::vector<StringRef> PartialAtomicFuncNames;
205         };
206 }
207
208 StringRef CDSPass::getPassName() const {
209         return "CDSPass";
210 }
211
212 void CDSPass::initializeCallbacks(Module &M) {
213         LLVMContext &Ctx = M.getContext();
214         AttributeList Attr;
215         Attr = Attr.addAttribute(Ctx, AttributeList::FunctionIndex,
216                         Attribute::NoUnwind);
217
218         Type * Int1Ty = Type::getInt1Ty(Ctx);
219         Type * Int32Ty = Type::getInt32Ty(Ctx);
220         OrdTy = Type::getInt32Ty(Ctx);
221
222         Int8PtrTy  = Type::getInt8PtrTy(Ctx);
223         Int16PtrTy = Type::getInt16PtrTy(Ctx);
224         Int32PtrTy = Type::getInt32PtrTy(Ctx);
225         Int64PtrTy = Type::getInt64PtrTy(Ctx);
226
227         VoidTy = Type::getVoidTy(Ctx);
228
229         CDSFuncEntry = checkCDSPassInterfaceFunction(
230                                                 M.getOrInsertFunction("cds_func_entry", 
231                                                 Attr, VoidTy, Int8PtrTy));
232         CDSFuncExit = checkCDSPassInterfaceFunction(
233                                                 M.getOrInsertFunction("cds_func_exit", 
234                                                 Attr, VoidTy, Int8PtrTy));
235
236         // Get the function to call from our untime library.
237         for (unsigned i = 0; i < kNumberOfAccessSizes; i++) {
238                 const unsigned ByteSize = 1U << i;
239                 const unsigned BitSize = ByteSize * 8;
240
241                 std::string ByteSizeStr = utostr(ByteSize);
242                 std::string BitSizeStr = utostr(BitSize);
243
244                 Type *Ty = Type::getIntNTy(Ctx, BitSize);
245                 Type *PtrTy = Ty->getPointerTo();
246
247                 // uint8_t cds_atomic_load8 (void * obj, int atomic_index)
248                 // void cds_atomic_store8 (void * obj, int atomic_index, uint8_t val)
249                 SmallString<32> LoadName("cds_load" + BitSizeStr);
250                 SmallString<32> StoreName("cds_store" + BitSizeStr);
251                 SmallString<32> VolatileLoadName("cds_volatile_load" + BitSizeStr);
252                 SmallString<32> VolatileStoreName("cds_volatile_store" + BitSizeStr);
253                 SmallString<32> AtomicInitName("cds_atomic_init" + BitSizeStr);
254                 SmallString<32> AtomicLoadName("cds_atomic_load" + BitSizeStr);
255                 SmallString<32> AtomicStoreName("cds_atomic_store" + BitSizeStr);
256
257                 CDSLoad[i]  = checkCDSPassInterfaceFunction(
258                                                         M.getOrInsertFunction(LoadName, Attr, VoidTy, PtrTy));
259                 CDSStore[i] = checkCDSPassInterfaceFunction(
260                                                         M.getOrInsertFunction(StoreName, Attr, VoidTy, PtrTy));
261                 CDSVolatileLoad[i]  = checkCDSPassInterfaceFunction(
262                                                                 M.getOrInsertFunction(VolatileLoadName,
263                                                                 Attr, Ty, PtrTy, Int8PtrTy));
264                 CDSVolatileStore[i] = checkCDSPassInterfaceFunction(
265                                                                 M.getOrInsertFunction(VolatileStoreName, 
266                                                                 Attr, VoidTy, PtrTy, Ty, Int8PtrTy));
267                 CDSAtomicInit[i] = checkCDSPassInterfaceFunction(
268                                                         M.getOrInsertFunction(AtomicInitName, 
269                                                         Attr, VoidTy, PtrTy, Ty, Int8PtrTy));
270                 CDSAtomicLoad[i]  = checkCDSPassInterfaceFunction(
271                                                                 M.getOrInsertFunction(AtomicLoadName, 
272                                                                 Attr, Ty, PtrTy, OrdTy, Int8PtrTy));
273                 CDSAtomicStore[i] = checkCDSPassInterfaceFunction(
274                                                                 M.getOrInsertFunction(AtomicStoreName, 
275                                                                 Attr, VoidTy, PtrTy, Ty, OrdTy, Int8PtrTy));
276
277                 for (int op = AtomicRMWInst::FIRST_BINOP; 
278                         op <= AtomicRMWInst::LAST_BINOP; ++op) {
279                         CDSAtomicRMW[op][i] = nullptr;
280                         std::string NamePart;
281
282                         if (op == AtomicRMWInst::Xchg)
283                                 NamePart = "_exchange";
284                         else if (op == AtomicRMWInst::Add) 
285                                 NamePart = "_fetch_add";
286                         else if (op == AtomicRMWInst::Sub)
287                                 NamePart = "_fetch_sub";
288                         else if (op == AtomicRMWInst::And)
289                                 NamePart = "_fetch_and";
290                         else if (op == AtomicRMWInst::Or)
291                                 NamePart = "_fetch_or";
292                         else if (op == AtomicRMWInst::Xor)
293                                 NamePart = "_fetch_xor";
294                         else
295                                 continue;
296
297                         SmallString<32> AtomicRMWName("cds_atomic" + NamePart + BitSizeStr);
298                         CDSAtomicRMW[op][i] = checkCDSPassInterfaceFunction(
299                                                                         M.getOrInsertFunction(AtomicRMWName, 
300                                                                         Attr, Ty, PtrTy, Ty, OrdTy, Int8PtrTy));
301                 }
302
303                 // only supportes strong version
304                 SmallString<32> AtomicCASName_V1("cds_atomic_compare_exchange" + BitSizeStr + "_v1");
305                 SmallString<32> AtomicCASName_V2("cds_atomic_compare_exchange" + BitSizeStr + "_v2");
306                 CDSAtomicCAS_V1[i] = checkCDSPassInterfaceFunction(
307                                                                 M.getOrInsertFunction(AtomicCASName_V1, 
308                                                                 Attr, Ty, PtrTy, Ty, Ty, OrdTy, OrdTy, Int8PtrTy));
309                 CDSAtomicCAS_V2[i] = checkCDSPassInterfaceFunction(
310                                                                 M.getOrInsertFunction(AtomicCASName_V2, 
311                                                                 Attr, Int1Ty, PtrTy, PtrTy, Ty, OrdTy, OrdTy, Int8PtrTy));
312         }
313
314         CDSAtomicThreadFence = checkCDSPassInterfaceFunction(
315                         M.getOrInsertFunction("cds_atomic_thread_fence", Attr, VoidTy, OrdTy, Int8PtrTy));
316
317         MemmoveFn = checkCDSPassInterfaceFunction(
318                                         M.getOrInsertFunction("memmove", Attr, Int8PtrTy, Int8PtrTy,
319                                         Int8PtrTy, IntPtrTy));
320         MemcpyFn = checkCDSPassInterfaceFunction(
321                                         M.getOrInsertFunction("memcpy", Attr, Int8PtrTy, Int8PtrTy,
322                                         Int8PtrTy, IntPtrTy));
323         MemsetFn = checkCDSPassInterfaceFunction(
324                                         M.getOrInsertFunction("memset", Attr, Int8PtrTy, Int8PtrTy,
325                                         Int32Ty, IntPtrTy));
326 }
327
328 bool CDSPass::doInitialization(Module &M) {
329         const DataLayout &DL = M.getDataLayout();
330         IntPtrTy = DL.getIntPtrType(M.getContext());
331         
332         // createSanitizerCtorAndInitFunctions is defined in "llvm/Transforms/Utils/ModuleUtils.h"
333         // We do not support it yet
334         /*
335         std::tie(CDSCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions(
336                         M, kCDSModuleCtorName, kCDSInitName, {}, {});
337
338         appendToGlobalCtors(M, CDSCtorFunction, 0);
339         */
340
341         AtomicFuncNames = 
342         {
343                 "atomic_init", "atomic_load", "atomic_store", 
344                 "atomic_fetch_", "atomic_exchange", "atomic_compare_exchange_"
345         };
346
347         PartialAtomicFuncNames = 
348         { 
349                 "load", "store", "fetch", "exchange", "compare_exchange_" 
350         };
351
352         return true;
353 }
354
355 static bool isVtableAccess(Instruction *I) {
356         if (MDNode *Tag = I->getMetadata(LLVMContext::MD_tbaa))
357                 return Tag->isTBAAVtableAccess();
358         return false;
359 }
360
361 // Do not instrument known races/"benign races" that come from compiler
362 // instrumentatin. The user has no way of suppressing them.
363 static bool shouldInstrumentReadWriteFromAddress(const Module *M, Value *Addr) {
364         // Peel off GEPs and BitCasts.
365         Addr = Addr->stripInBoundsOffsets();
366
367         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Addr)) {
368                 if (GV->hasSection()) {
369                         StringRef SectionName = GV->getSection();
370                         // Check if the global is in the PGO counters section.
371                         auto OF = Triple(M->getTargetTriple()).getObjectFormat();
372                         if (SectionName.endswith(
373                               getInstrProfSectionName(IPSK_cnts, OF, /*AddSegmentInfo=*/false)))
374                                 return false;
375                 }
376
377                 // Check if the global is private gcov data.
378                 if (GV->getName().startswith("__llvm_gcov") ||
379                 GV->getName().startswith("__llvm_gcda"))
380                 return false;
381         }
382
383         // Do not instrument acesses from different address spaces; we cannot deal
384         // with them.
385         if (Addr) {
386                 Type *PtrTy = cast<PointerType>(Addr->getType()->getScalarType());
387                 if (PtrTy->getPointerAddressSpace() != 0)
388                         return false;
389         }
390
391         return true;
392 }
393
394 bool CDSPass::addrPointsToConstantData(Value *Addr) {
395         // If this is a GEP, just analyze its pointer operand.
396         if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Addr))
397                 Addr = GEP->getPointerOperand();
398
399         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Addr)) {
400                 if (GV->isConstant()) {
401                         // Reads from constant globals can not race with any writes.
402                         NumOmittedReadsFromConstantGlobals++;
403                         return true;
404                 }
405         } else if (LoadInst *L = dyn_cast<LoadInst>(Addr)) {
406                 if (isVtableAccess(L)) {
407                         // Reads from a vtable pointer can not race with any writes.
408                         NumOmittedReadsFromVtable++;
409                         return true;
410                 }
411         }
412         return false;
413 }
414
415 bool CDSPass::shouldInstrumentBeforeAtomics(Instruction * Inst) {
416         if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
417                 AtomicOrdering ordering = LI->getOrdering();
418                 if ( isAtLeastOrStrongerThan(ordering, AtomicOrdering::Acquire) )
419                         return true;
420         } else if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
421                 AtomicOrdering ordering = SI->getOrdering();
422                 if ( isAtLeastOrStrongerThan(ordering, AtomicOrdering::Acquire) )
423                         return true;
424         } else if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(Inst)) {
425                 AtomicOrdering ordering = RMWI->getOrdering();
426                 if ( isAtLeastOrStrongerThan(ordering, AtomicOrdering::Acquire) )
427                         return true;
428         } else if (AtomicCmpXchgInst *CASI = dyn_cast<AtomicCmpXchgInst>(Inst)) {
429                 AtomicOrdering ordering = CASI->getSuccessOrdering();
430                 if ( isAtLeastOrStrongerThan(ordering, AtomicOrdering::Acquire) )
431                         return true;
432         } else if (FenceInst *FI = dyn_cast<FenceInst>(Inst)) {
433                 AtomicOrdering ordering = FI->getOrdering();
434                 if ( isAtLeastOrStrongerThan(ordering, AtomicOrdering::Acquire) )
435                         return true;
436         }
437
438         return false;
439 }
440
441 void CDSPass::chooseInstructionsToInstrument(
442         SmallVectorImpl<Instruction *> &Local, SmallVectorImpl<Instruction *> &All,
443         const DataLayout &DL) {
444         SmallPtrSet<Value*, 8> WriteTargets;
445         // Iterate from the end.
446         for (Instruction *I : reverse(Local)) {
447                 if (StoreInst *Store = dyn_cast<StoreInst>(I)) {
448                         Value *Addr = Store->getPointerOperand();
449                         if (!shouldInstrumentReadWriteFromAddress(I->getModule(), Addr))
450                                 continue;
451                         WriteTargets.insert(Addr);
452                 } else {
453                         LoadInst *Load = cast<LoadInst>(I);
454                         Value *Addr = Load->getPointerOperand();
455                         if (!shouldInstrumentReadWriteFromAddress(I->getModule(), Addr))
456                                 continue;
457                         if (WriteTargets.count(Addr)) {
458                                 // We will write to this temp, so no reason to analyze the read.
459                                 NumOmittedReadsBeforeWrite++;
460                                 continue;
461                         }
462                         if (addrPointsToConstantData(Addr)) {
463                                 // Addr points to some constant data -- it can not race with any writes.
464                                 continue;
465                         }
466                 }
467                 Value *Addr = isa<StoreInst>(*I)
468                         ? cast<StoreInst>(I)->getPointerOperand()
469                         : cast<LoadInst>(I)->getPointerOperand();
470                 if (isa<AllocaInst>(GetUnderlyingObject(Addr, DL)) &&
471                                 !PointerMayBeCaptured(Addr, true, true)) {
472                         // The variable is addressable but not captured, so it cannot be
473                         // referenced from a different thread and participate in a data race
474                         // (see llvm/Analysis/CaptureTracking.h for details).
475                         NumOmittedNonCaptured++;
476                         continue;
477                 }
478                 All.push_back(I);
479         }
480         Local.clear();
481 }
482
483 /* Not implemented
484 void CDSPass::InsertRuntimeIgnores(Function &F) {
485         IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI());
486         IRB.CreateCall(CDSIgnoreBegin);
487         EscapeEnumerator EE(F, "cds_ignore_cleanup", ClHandleCxxExceptions);
488         while (IRBuilder<> *AtExit = EE.Next()) {
489                 AtExit->CreateCall(CDSIgnoreEnd);
490         }
491 }*/
492
493 bool CDSPass::runOnFunction(Function &F) {
494         initializeCallbacks( *F.getParent() );
495         SmallVector<Instruction*, 8> AllLoadsAndStores;
496         SmallVector<Instruction*, 8> LocalLoadsAndStores;
497         SmallVector<Instruction*, 8> VolatileLoadsAndStores;
498         SmallVector<Instruction*, 8> AtomicAccesses;
499         SmallVector<Instruction*, 8> MemIntrinCalls;
500
501         bool Res = false;
502         bool HasAtomic = false;
503         bool HasVolatile = false;
504         const DataLayout &DL = F.getParent()->getDataLayout();
505
506         for (auto &BB : F) {
507                 for (auto &Inst : BB) {
508                         if ( (&Inst)->isAtomic() ) {
509                                 AtomicAccesses.push_back(&Inst);
510                                 HasAtomic = true;
511
512                                 if (shouldInstrumentBeforeAtomics(&Inst)) {
513                                         chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores,
514                                                 DL);
515                                 }
516                         } else if (isAtomicCall(&Inst) ) {
517                                 AtomicAccesses.push_back(&Inst);
518                                 HasAtomic = true;
519                                 chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores,
520                                         DL);
521                         } else if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst)) {
522                                 LoadInst *LI = dyn_cast<LoadInst>(&Inst);
523                                 StoreInst *SI = dyn_cast<StoreInst>(&Inst);
524                                 bool isVolatile = ( LI ? LI->isVolatile() : SI->isVolatile() );
525
526                                 if (isVolatile) {
527                                         VolatileLoadsAndStores.push_back(&Inst);
528                                         HasVolatile = true;
529                                 } else
530                                         LocalLoadsAndStores.push_back(&Inst);
531                         } else if (isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) {
532                                 if (isa<MemIntrinsic>(Inst))
533                                         MemIntrinCalls.push_back(&Inst);
534
535                                 /*if (CallInst *CI = dyn_cast<CallInst>(&Inst))
536                                         maybeMarkSanitizerLibraryCallNoBuiltin(CI, TLI);
537                                 */
538
539                                 chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores,
540                                         DL);
541                         }
542                 }
543
544                 chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores, DL);
545         }
546
547         for (auto Inst : AllLoadsAndStores) {
548                 Res |= instrumentLoadOrStore(Inst, DL);
549         }
550
551         for (auto Inst : VolatileLoadsAndStores) {
552                 Res |= instrumentVolatile(Inst, DL);
553         }
554
555         for (auto Inst : AtomicAccesses) {
556                 Res |= instrumentAtomic(Inst, DL);
557         }
558
559         for (auto Inst : MemIntrinCalls) {
560                 Res |= instrumentMemIntrinsic(Inst);
561         }
562
563         // Only instrument functions that contain atomics or volatiles
564         if (Res && ( HasAtomic || HasVolatile) ) {
565                 IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI());
566                 /* Unused for now
567                 Value *ReturnAddress = IRB.CreateCall(
568                         Intrinsic::getDeclaration(F.getParent(), Intrinsic::returnaddress),
569                         IRB.getInt32(0));
570                 */
571
572                 Value * FuncName = IRB.CreateGlobalStringPtr(F.getName());
573                 IRB.CreateCall(CDSFuncEntry, FuncName);
574
575                 EscapeEnumerator EE(F, "cds_cleanup", true);
576                 while (IRBuilder<> *AtExit = EE.Next()) {
577                   AtExit->CreateCall(CDSFuncExit, FuncName);
578                 }
579
580                 Res = true;
581         }
582
583         return false;
584 }
585
586 bool CDSPass::instrumentLoadOrStore(Instruction *I,
587                                                                         const DataLayout &DL) {
588         IRBuilder<> IRB(I);
589         bool IsWrite = isa<StoreInst>(*I);
590         Value *Addr = IsWrite
591                 ? cast<StoreInst>(I)->getPointerOperand()
592                 : cast<LoadInst>(I)->getPointerOperand();
593
594         // swifterror memory addresses are mem2reg promoted by instruction selection.
595         // As such they cannot have regular uses like an instrumentation function and
596         // it makes no sense to track them as memory.
597         if (Addr->isSwiftError())
598                 return false;
599
600         int Idx = getMemoryAccessFuncIndex(Addr, DL);
601         if (Idx < 0)
602                 return false;
603
604         if (IsWrite && isVtableAccess(I)) {
605                 /* TODO
606                 LLVM_DEBUG(dbgs() << "  VPTR : " << *I << "\n");
607                 Value *StoredValue = cast<StoreInst>(I)->getValueOperand();
608                 // StoredValue may be a vector type if we are storing several vptrs at once.
609                 // In this case, just take the first element of the vector since this is
610                 // enough to find vptr races.
611                 if (isa<VectorType>(StoredValue->getType()))
612                         StoredValue = IRB.CreateExtractElement(
613                                         StoredValue, ConstantInt::get(IRB.getInt32Ty(), 0));
614                 if (StoredValue->getType()->isIntegerTy())
615                         StoredValue = IRB.CreateIntToPtr(StoredValue, IRB.getInt8PtrTy());
616                 // Call TsanVptrUpdate.
617                 IRB.CreateCall(TsanVptrUpdate,
618                                                 {IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()),
619                                                         IRB.CreatePointerCast(StoredValue, IRB.getInt8PtrTy())});
620                 NumInstrumentedVtableWrites++;
621                 */
622                 return true;
623         }
624
625         if (!IsWrite && isVtableAccess(I)) {
626                 /* TODO
627                 IRB.CreateCall(TsanVptrLoad,
628                                                  IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()));
629                 NumInstrumentedVtableReads++;
630                 */
631                 return true;
632         }
633
634         // TODO: unaligned reads and writes
635
636         Value *OnAccessFunc = nullptr;
637         OnAccessFunc = IsWrite ? CDSStore[Idx] : CDSLoad[Idx];
638
639         Type *ArgType = IRB.CreatePointerCast(Addr, Addr->getType())->getType();
640
641         if ( ArgType != Int8PtrTy && ArgType != Int16PtrTy && 
642                         ArgType != Int32PtrTy && ArgType != Int64PtrTy ) {
643                 // if other types of load or stores are passed in
644                 return false;   
645         }
646
647         IRB.CreateCall(OnAccessFunc, IRB.CreatePointerCast(Addr, Addr->getType()));
648         if (IsWrite) NumInstrumentedWrites++;
649         else         NumInstrumentedReads++;
650         return true;
651 }
652
653 bool CDSPass::instrumentVolatile(Instruction * I, const DataLayout &DL) {
654         IRBuilder<> IRB(I);
655         Value *position = getPosition(I, IRB);
656
657         if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
658                 assert( LI->isVolatile() );
659                 Value *Addr = LI->getPointerOperand();
660                 int Idx=getMemoryAccessFuncIndex(Addr, DL);
661                 if (Idx < 0)
662                         return false;
663
664                 Value *args[] = {Addr, position};
665                 Instruction* funcInst = CallInst::Create(CDSVolatileLoad[Idx], args);
666                 ReplaceInstWithInst(LI, funcInst);
667         } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
668                 assert( SI->isVolatile() );
669                 Value *Addr = SI->getPointerOperand();
670                 int Idx=getMemoryAccessFuncIndex(Addr, DL);
671                 if (Idx < 0)
672                         return false;
673
674                 Value *val = SI->getValueOperand();
675                 Value *args[] = {Addr, val, position};
676                 Instruction* funcInst = CallInst::Create(CDSVolatileStore[Idx], args);
677                 ReplaceInstWithInst(SI, funcInst);
678         } else {
679                 return false;
680         }
681
682         return true;
683 }
684
685 bool CDSPass::instrumentMemIntrinsic(Instruction *I) {
686         IRBuilder<> IRB(I);
687         if (MemSetInst *M = dyn_cast<MemSetInst>(I)) {
688                 IRB.CreateCall(
689                         MemsetFn,
690                         {IRB.CreatePointerCast(M->getArgOperand(0), IRB.getInt8PtrTy()),
691                          IRB.CreateIntCast(M->getArgOperand(1), IRB.getInt32Ty(), false),
692                          IRB.CreateIntCast(M->getArgOperand(2), IntPtrTy, false)});
693                 I->eraseFromParent();
694         } else if (MemTransferInst *M = dyn_cast<MemTransferInst>(I)) {
695                 IRB.CreateCall(
696                         isa<MemCpyInst>(M) ? MemcpyFn : MemmoveFn,
697                         {IRB.CreatePointerCast(M->getArgOperand(0), IRB.getInt8PtrTy()),
698                          IRB.CreatePointerCast(M->getArgOperand(1), IRB.getInt8PtrTy()),
699                          IRB.CreateIntCast(M->getArgOperand(2), IntPtrTy, false)});
700                 I->eraseFromParent();
701         }
702         return false;
703 }
704
705 bool CDSPass::instrumentAtomic(Instruction * I, const DataLayout &DL) {
706         IRBuilder<> IRB(I);
707
708         if (auto *CI = dyn_cast<CallInst>(I)) {
709                 return instrumentAtomicCall(CI, DL);
710         }
711
712         Value *position = getPosition(I, IRB);
713
714         if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
715                 Value *Addr = LI->getPointerOperand();
716                 int Idx=getMemoryAccessFuncIndex(Addr, DL);
717                 if (Idx < 0)
718                         return false;
719
720                 int atomic_order_index = getAtomicOrderIndex(LI->getOrdering());
721                 Value *order = ConstantInt::get(OrdTy, atomic_order_index);
722                 Value *args[] = {Addr, order, position};
723                 Instruction* funcInst = CallInst::Create(CDSAtomicLoad[Idx], args);
724                 ReplaceInstWithInst(LI, funcInst);
725         } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
726                 Value *Addr = SI->getPointerOperand();
727                 int Idx=getMemoryAccessFuncIndex(Addr, DL);
728                 if (Idx < 0)
729                         return false;
730
731                 int atomic_order_index = getAtomicOrderIndex(SI->getOrdering());
732                 Value *val = SI->getValueOperand();
733                 Value *order = ConstantInt::get(OrdTy, atomic_order_index);
734                 Value *args[] = {Addr, val, order, position};
735                 Instruction* funcInst = CallInst::Create(CDSAtomicStore[Idx], args);
736                 ReplaceInstWithInst(SI, funcInst);
737         } else if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(I)) {
738                 Value *Addr = RMWI->getPointerOperand();
739                 int Idx=getMemoryAccessFuncIndex(Addr, DL);
740                 if (Idx < 0)
741                         return false;
742
743                 int atomic_order_index = getAtomicOrderIndex(RMWI->getOrdering());
744                 Value *val = RMWI->getValOperand();
745                 Value *order = ConstantInt::get(OrdTy, atomic_order_index);
746                 Value *args[] = {Addr, val, order, position};
747                 Instruction* funcInst = CallInst::Create(CDSAtomicRMW[RMWI->getOperation()][Idx], args);
748                 ReplaceInstWithInst(RMWI, funcInst);
749         } else if (AtomicCmpXchgInst *CASI = dyn_cast<AtomicCmpXchgInst>(I)) {
750                 IRBuilder<> IRB(CASI);
751
752                 Value *Addr = CASI->getPointerOperand();
753                 int Idx=getMemoryAccessFuncIndex(Addr, DL);
754                 if (Idx < 0)
755                         return false;
756
757                 const unsigned ByteSize = 1U << Idx;
758                 const unsigned BitSize = ByteSize * 8;
759                 Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
760                 Type *PtrTy = Ty->getPointerTo();
761
762                 Value *CmpOperand = IRB.CreateBitOrPointerCast(CASI->getCompareOperand(), Ty);
763                 Value *NewOperand = IRB.CreateBitOrPointerCast(CASI->getNewValOperand(), Ty);
764
765                 int atomic_order_index_succ = getAtomicOrderIndex(CASI->getSuccessOrdering());
766                 int atomic_order_index_fail = getAtomicOrderIndex(CASI->getFailureOrdering());
767                 Value *order_succ = ConstantInt::get(OrdTy, atomic_order_index_succ);
768                 Value *order_fail = ConstantInt::get(OrdTy, atomic_order_index_fail);
769
770                 Value *Args[] = {IRB.CreatePointerCast(Addr, PtrTy),
771                                                  CmpOperand, NewOperand,
772                                                  order_succ, order_fail, position};
773
774                 CallInst *funcInst = IRB.CreateCall(CDSAtomicCAS_V1[Idx], Args);
775                 Value *Success = IRB.CreateICmpEQ(funcInst, CmpOperand);
776
777                 Value *OldVal = funcInst;
778                 Type *OrigOldValTy = CASI->getNewValOperand()->getType();
779                 if (Ty != OrigOldValTy) {
780                         // The value is a pointer, so we need to cast the return value.
781                         OldVal = IRB.CreateIntToPtr(funcInst, OrigOldValTy);
782                 }
783
784                 Value *Res =
785                   IRB.CreateInsertValue(UndefValue::get(CASI->getType()), OldVal, 0);
786                 Res = IRB.CreateInsertValue(Res, Success, 1);
787
788                 I->replaceAllUsesWith(Res);
789                 I->eraseFromParent();
790         } else if (FenceInst *FI = dyn_cast<FenceInst>(I)) {
791                 int atomic_order_index = getAtomicOrderIndex(FI->getOrdering());
792                 Value *order = ConstantInt::get(OrdTy, atomic_order_index);
793                 Value *Args[] = {order, position};
794
795                 CallInst *funcInst = CallInst::Create(CDSAtomicThreadFence, Args);
796                 ReplaceInstWithInst(FI, funcInst);
797                 // errs() << "Thread Fences replaced\n";
798         }
799         return true;
800 }
801
802 bool CDSPass::isAtomicCall(Instruction *I) {
803         if ( auto *CI = dyn_cast<CallInst>(I) ) {
804                 Function *fun = CI->getCalledFunction();
805                 if (fun == NULL)
806                         return false;
807
808                 StringRef funName = fun->getName();
809
810                 // TODO: come up with better rules for function name checking
811                 for (StringRef name : AtomicFuncNames) {
812                         if ( funName.contains(name) ) 
813                                 return true;
814                 }
815                 
816                 for (StringRef PartialName : PartialAtomicFuncNames) {
817                         if (funName.contains(PartialName) && 
818                                         funName.contains("atomic") )
819                                 return true;
820                 }
821         }
822
823         return false;
824 }
825
826 bool CDSPass::instrumentAtomicCall(CallInst *CI, const DataLayout &DL) {
827         IRBuilder<> IRB(CI);
828         Function *fun = CI->getCalledFunction();
829         StringRef funName = fun->getName();
830         std::vector<Value *> parameters;
831
832         User::op_iterator begin = CI->arg_begin();
833         User::op_iterator end = CI->arg_end();
834         for (User::op_iterator it = begin; it != end; ++it) {
835                 Value *param = *it;
836                 parameters.push_back(param);
837         }
838
839         // obtain source line number of the CallInst
840         Value *position = getPosition(CI, IRB);
841
842         // the pointer to the address is always the first argument
843         Value *OrigPtr = parameters[0];
844
845         int Idx = getMemoryAccessFuncIndex(OrigPtr, DL);
846         if (Idx < 0)
847                 return false;
848
849         const unsigned ByteSize = 1U << Idx;
850         const unsigned BitSize = ByteSize * 8;
851         Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
852         Type *PtrTy = Ty->getPointerTo();
853
854         // atomic_init; args = {obj, order}
855         if (funName.contains("atomic_init")) {
856                 Value *OrigVal = parameters[1];
857
858                 Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
859                 Value *val;
860                 if (OrigVal->getType()->isPtrOrPtrVectorTy())
861                         val = IRB.CreatePointerCast(OrigVal, Ty);
862                 else
863                         val = IRB.CreateIntCast(OrigVal, Ty, true);
864
865                 Value *args[] = {ptr, val, position};
866
867                 Instruction* funcInst = CallInst::Create(CDSAtomicInit[Idx], args);
868                 ReplaceInstWithInst(CI, funcInst);
869
870                 return true;
871         }
872
873         // atomic_load; args = {obj, order}
874         if (funName.contains("atomic_load")) {
875                 bool isExplicit = funName.contains("atomic_load_explicit");
876
877                 Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
878                 Value *order;
879                 if (isExplicit)
880                         order = IRB.CreateBitOrPointerCast(parameters[1], OrdTy);
881                 else 
882                         order = ConstantInt::get(OrdTy, 
883                                                         (int) AtomicOrderingCABI::seq_cst);
884                 Value *args[] = {ptr, order, position};
885                 
886                 Instruction* funcInst = CallInst::Create(CDSAtomicLoad[Idx], args);
887                 ReplaceInstWithInst(CI, funcInst);
888
889                 return true;
890         } else if (funName.contains("atomic") && 
891                                         funName.contains("load") ) {
892                 // does this version of call always have an atomic order as an argument?
893                 Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
894                 Value *order = IRB.CreateBitOrPointerCast(parameters[1], OrdTy);
895                 Value *args[] = {ptr, order, position};
896
897                 if (!CI->getType()->isPointerTy()) {
898                         return false;   
899                 } 
900
901                 CallInst *funcInst = IRB.CreateCall(CDSAtomicLoad[Idx], args);
902                 Value *RetVal = IRB.CreateIntToPtr(funcInst, CI->getType());
903
904                 CI->replaceAllUsesWith(RetVal);
905                 CI->eraseFromParent();
906
907                 return true;
908         }
909
910         // atomic_store; args = {obj, val, order}
911         if (funName.contains("atomic_store")) {
912                 bool isExplicit = funName.contains("atomic_store_explicit");
913                 Value *OrigVal = parameters[1];
914
915                 Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
916                 Value *val = IRB.CreatePointerCast(OrigVal, Ty);
917                 Value *order;
918                 if (isExplicit)
919                         order = IRB.CreateBitOrPointerCast(parameters[2], OrdTy);
920                 else 
921                         order = ConstantInt::get(OrdTy, 
922                                                         (int) AtomicOrderingCABI::seq_cst);
923                 Value *args[] = {ptr, val, order, position};
924                 
925                 Instruction* funcInst = CallInst::Create(CDSAtomicStore[Idx], args);
926                 ReplaceInstWithInst(CI, funcInst);
927
928                 return true;
929         } else if (funName.contains("atomic") && 
930                                         funName.contains("store") ) {
931                 // Does this version of call always have an atomic order as an argument?
932                 Value *OrigVal = parameters[1];
933
934                 Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
935                 Value *val;
936                 if (OrigVal->getType()->isPtrOrPtrVectorTy())
937                         val = IRB.CreatePointerCast(OrigVal, Ty);
938                 else
939                         val = IRB.CreateIntCast(OrigVal, Ty, true);
940
941                 Value *order = IRB.CreateBitOrPointerCast(parameters[2], OrdTy);
942                 Value *args[] = {ptr, val, order, position};
943
944                 Instruction* funcInst = CallInst::Create(CDSAtomicStore[Idx], args);
945                 ReplaceInstWithInst(CI, funcInst);
946
947                 return true;
948         }
949
950         // atomic_fetch_*; args = {obj, val, order}
951         if (funName.contains("atomic_fetch_") || 
952                 funName.contains("atomic_exchange")) {
953
954                 /* TODO: implement stricter function name checking */
955                 if (funName.contains("non"))
956                         return false;
957
958                 bool isExplicit = funName.contains("_explicit");
959                 Value *OrigVal = parameters[1];
960
961                 int op;
962                 if ( funName.contains("_fetch_add") )
963                         op = AtomicRMWInst::Add;
964                 else if ( funName.contains("_fetch_sub") )
965                         op = AtomicRMWInst::Sub;
966                 else if ( funName.contains("_fetch_and") )
967                         op = AtomicRMWInst::And;
968                 else if ( funName.contains("_fetch_or") )
969                         op = AtomicRMWInst::Or;
970                 else if ( funName.contains("_fetch_xor") )
971                         op = AtomicRMWInst::Xor;
972                 else if ( funName.contains("atomic_exchange") )
973                         op = AtomicRMWInst::Xchg;
974                 else {
975                         errs() << "Unknown atomic read-modify-write operation\n";
976                         return false;
977                 }
978
979                 Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
980                 Value *val;
981                 if (OrigVal->getType()->isPtrOrPtrVectorTy())
982                         val = IRB.CreatePointerCast(OrigVal, Ty);
983                 else
984                         val = IRB.CreateIntCast(OrigVal, Ty, true);
985
986                 Value *order;
987                 if (isExplicit)
988                         order = IRB.CreateBitOrPointerCast(parameters[2], OrdTy);
989                 else 
990                         order = ConstantInt::get(OrdTy, 
991                                                         (int) AtomicOrderingCABI::seq_cst);
992                 Value *args[] = {ptr, val, order, position};
993                 
994                 Instruction* funcInst = CallInst::Create(CDSAtomicRMW[op][Idx], args);
995                 ReplaceInstWithInst(CI, funcInst);
996
997                 return true;
998         } else if (funName.contains("fetch")) {
999                 errs() << "atomic fetch captured. Not implemented yet. ";
1000                 errs() << "See source file :";
1001                 getPosition(CI, IRB, true);
1002                 return false;
1003         } else if (funName.contains("exchange") &&
1004                         !funName.contains("compare_exchange") ) {
1005                 if (CI->getType()->isPointerTy()) {
1006                         /**
1007                          * TODO: instrument the following case
1008                          * mcs-lock.h
1009                          * std::atomic<struct T *> m_tail;
1010                          * struct T * me;
1011                          * struct T * pred = m_tail.exchange(me, memory_order_*);
1012                          */
1013                         errs() << "atomic exchange captured. Not implemented yet. ";
1014                         errs() << "See source file :";
1015                         getPosition(CI, IRB, true);
1016
1017                         return false;
1018                 }
1019
1020                 Value *OrigVal = parameters[1];
1021
1022                 Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
1023                 Value *val;
1024                 if (OrigVal->getType()->isPtrOrPtrVectorTy())
1025                         val = IRB.CreatePointerCast(OrigVal, Ty);
1026                 else
1027                         val = IRB.CreateIntCast(OrigVal, Ty, true);
1028
1029                 Value *order = IRB.CreateBitOrPointerCast(parameters[2], OrdTy);
1030                 Value *args[] = {ptr, val, order, position};
1031                 int op = AtomicRMWInst::Xchg;
1032
1033                 Instruction* funcInst = CallInst::Create(CDSAtomicRMW[op][Idx], args);
1034                 ReplaceInstWithInst(CI, funcInst);
1035
1036                 return true;
1037         }
1038
1039         /* atomic_compare_exchange_*; 
1040            args = {obj, expected, new value, order1, order2}
1041         */
1042         if ( funName.contains("atomic_compare_exchange_") ) {
1043                 bool isExplicit = funName.contains("_explicit");
1044
1045                 Value *Addr = IRB.CreatePointerCast(OrigPtr, PtrTy);
1046                 Value *CmpOperand = IRB.CreatePointerCast(parameters[1], PtrTy);
1047                 Value *NewOperand = IRB.CreateBitOrPointerCast(parameters[2], Ty);
1048
1049                 Value *order_succ, *order_fail;
1050                 if (isExplicit) {
1051                         order_succ = IRB.CreateBitOrPointerCast(parameters[3], OrdTy);
1052
1053                         if (parameters.size() > 4) {
1054                                 order_fail = IRB.CreateBitOrPointerCast(parameters[4], OrdTy);
1055                         } else {
1056                                 /* The failure order is not provided */
1057                                 order_fail = order_succ;
1058                                 ConstantInt * order_succ_cast = dyn_cast<ConstantInt>(order_succ);
1059                                 int index = order_succ_cast->getSExtValue();
1060
1061                                 order_fail = ConstantInt::get(OrdTy,
1062                                                                 AtomicCasFailureOrderIndex(index));
1063                         }
1064                 } else  {
1065                         order_succ = ConstantInt::get(OrdTy, 
1066                                                         (int) AtomicOrderingCABI::seq_cst);
1067                         order_fail = ConstantInt::get(OrdTy, 
1068                                                         (int) AtomicOrderingCABI::seq_cst);
1069                 }
1070
1071                 Value *args[] = {Addr, CmpOperand, NewOperand, 
1072                                                         order_succ, order_fail, position};
1073                 
1074                 Instruction* funcInst = CallInst::Create(CDSAtomicCAS_V2[Idx], args);
1075                 ReplaceInstWithInst(CI, funcInst);
1076
1077                 return true;
1078         } else if ( funName.contains("compare_exchange_strong") ||
1079                                 funName.contains("compare_exchange_weak") ) {
1080                 Value *Addr = IRB.CreatePointerCast(OrigPtr, PtrTy);
1081                 Value *CmpOperand = IRB.CreatePointerCast(parameters[1], PtrTy);
1082                 Value *NewOperand = IRB.CreateBitOrPointerCast(parameters[2], Ty);
1083
1084                 Value *order_succ, *order_fail;
1085                 order_succ = IRB.CreateBitOrPointerCast(parameters[3], OrdTy);
1086
1087                 if (parameters.size() > 4) {
1088                         order_fail = IRB.CreateBitOrPointerCast(parameters[4], OrdTy);
1089                 } else {
1090                         /* The failure order is not provided */
1091                         order_fail = order_succ;
1092                         ConstantInt * order_succ_cast = dyn_cast<ConstantInt>(order_succ);
1093                         int index = order_succ_cast->getSExtValue();
1094
1095                         order_fail = ConstantInt::get(OrdTy,
1096                                                         AtomicCasFailureOrderIndex(index));
1097                 }
1098
1099                 Value *args[] = {Addr, CmpOperand, NewOperand, 
1100                                                         order_succ, order_fail, position};
1101                 Instruction* funcInst = CallInst::Create(CDSAtomicCAS_V2[Idx], args);
1102                 ReplaceInstWithInst(CI, funcInst);
1103
1104                 return true;
1105         }
1106
1107         return false;
1108 }
1109
1110 int CDSPass::getMemoryAccessFuncIndex(Value *Addr,
1111                                                                                 const DataLayout &DL) {
1112         Type *OrigPtrTy = Addr->getType();
1113         Type *OrigTy = cast<PointerType>(OrigPtrTy)->getElementType();
1114         assert(OrigTy->isSized());
1115         uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy);
1116         if (TypeSize != 8  && TypeSize != 16 &&
1117                 TypeSize != 32 && TypeSize != 64 && TypeSize != 128) {
1118                 NumAccessesWithBadSize++;
1119                 // Ignore all unusual sizes.
1120                 return -1;
1121         }
1122         size_t Idx = countTrailingZeros(TypeSize / 8);
1123         //assert(Idx < kNumberOfAccessSizes);
1124         if (Idx >= kNumberOfAccessSizes) {
1125                 return -1;
1126         }
1127         return Idx;
1128 }
1129
1130
1131 char CDSPass::ID = 0;
1132
1133 // Automatically enable the pass.
1134 static void registerCDSPass(const PassManagerBuilder &,
1135                                                         legacy::PassManagerBase &PM) {
1136         PM.add(new CDSPass());
1137 }
1138
1139 /* Enable the pass when opt level is greater than 0 */
1140 static RegisterStandardPasses 
1141         RegisterMyPass1(PassManagerBuilder::EP_OptimizerLast,
1142 registerCDSPass);
1143
1144 /* Enable the pass when opt level is 0 */
1145 static RegisterStandardPasses 
1146         RegisterMyPass2(PassManagerBuilder::EP_EnabledOnOptLevel0,
1147 registerCDSPass);