merge
[c11llvm.git] / CDSPass.cpp
index 886621ff7f1e6ed51a15804201f9e141a1d778b0..0cebdf01ac647d65fcaf9d437ef4e6e01ce4358b 100644 (file)
@@ -1,7 +1,8 @@
 //===-- CDSPass.cpp - xxx -------------------------------===//
 //
 //===-- CDSPass.cpp - xxx -------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
 #include <vector>
 
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
 #include <vector>
 
-#define DEBUG_TYPE "CDS"
 using namespace llvm;
 
 using namespace llvm;
 
-#include "getPosition.hpp"
-
-#define FUNCARRAYSIZE 4
+#define DEBUG_TYPE "CDS"
+#include <llvm/IR/DebugLoc.h>
+
+Value *getPosition( 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);
+       }
+
+       return IRB . CreateGlobalStringPtr (position_string);
+}
 
 STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
 STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
 
 STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
 STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
+STATISTIC(NumAccessesWithBadSize, "Number of accesses with bad size");
 // STATISTIC(NumInstrumentedVtableWrites, "Number of vtable ptr writes");
 // STATISTIC(NumInstrumentedVtableReads, "Number of vtable ptr reads");
 
 // STATISTIC(NumInstrumentedVtableWrites, "Number of vtable ptr writes");
 // STATISTIC(NumInstrumentedVtableReads, "Number of vtable ptr reads");
 
@@ -62,10 +74,6 @@ STATISTIC(NumOmittedReadsFromConstantGlobals,
 STATISTIC(NumOmittedReadsFromVtable, "Number of vtable reads");
 STATISTIC(NumOmittedNonCaptured, "Number of accesses ignored due to capturing");
 
 STATISTIC(NumOmittedReadsFromVtable, "Number of vtable reads");
 STATISTIC(NumOmittedNonCaptured, "Number of accesses ignored due to capturing");
 
-Type * Int8Ty;
-Type * Int16Ty;
-Type * Int32Ty;
-Type * Int64Ty;
 Type * OrdTy;
 
 Type * Int8PtrTy;
 Type * OrdTy;
 
 Type * Int8PtrTy;
@@ -75,18 +83,17 @@ Type * Int64PtrTy;
 
 Type * VoidTy;
 
 
 Type * VoidTy;
 
-Constant * CDSLoad[FUNCARRAYSIZE];
-Constant * CDSStore[FUNCARRAYSIZE];
-Constant * CDSAtomicInit[FUNCARRAYSIZE];
-Constant * CDSAtomicLoad[FUNCARRAYSIZE];
-Constant * CDSAtomicStore[FUNCARRAYSIZE];
-Constant * CDSAtomicRMW[AtomicRMWInst::LAST_BINOP + 1][FUNCARRAYSIZE];
-Constant * CDSAtomicCAS_V1[FUNCARRAYSIZE];
-Constant * CDSAtomicCAS_V2[FUNCARRAYSIZE];
+static const size_t kNumberOfAccessSizes = 4;
+Constant * CDSLoad[kNumberOfAccessSizes];
+Constant * CDSStore[kNumberOfAccessSizes];
+Constant * CDSAtomicInit[kNumberOfAccessSizes];
+Constant * CDSAtomicLoad[kNumberOfAccessSizes];
+Constant * CDSAtomicStore[kNumberOfAccessSizes];
+Constant * CDSAtomicRMW[AtomicRMWInst::LAST_BINOP + 1][kNumberOfAccessSizes];
+Constant * CDSAtomicCAS_V1[kNumberOfAccessSizes];
+Constant * CDSAtomicCAS_V2[kNumberOfAccessSizes];
 Constant * CDSAtomicThreadFence;
 
 Constant * CDSAtomicThreadFence;
 
-bool start = false;
-
 int getAtomicOrderIndex(AtomicOrdering order){
   switch (order) {
     case AtomicOrdering::Monotonic: 
 int getAtomicOrderIndex(AtomicOrdering order){
   switch (order) {
     case AtomicOrdering::Monotonic: 
@@ -107,32 +114,6 @@ int getAtomicOrderIndex(AtomicOrdering order){
   }
 }
 
   }
 }
 
-int getTypeSize(Type* type) {
-  if (type == Int8PtrTy) {
-    return sizeof(char)*8;
-  } else if (type == Int16PtrTy) {
-    return sizeof(short)*8;
-  } else if (type == Int32PtrTy) {
-    return sizeof(int)*8;
-  } else if (type == Int64PtrTy) {
-    return sizeof(long long int)*8;
-  } else {
-    return sizeof(void*)*8;
-  }
-
-  return -1;
-}
-
-static int sizetoindex(int size) {
-  switch(size) {
-    case 8:     return 0;
-    case 16:    return 1;
-    case 32:    return 2;
-    case 64:    return 3;
-  }
-  return -1;
-}
-
 namespace {
   struct CDSPass : public FunctionPass {
     static char ID;
 namespace {
   struct CDSPass : public FunctionPass {
     static char ID;
@@ -158,9 +139,331 @@ static bool isVtableAccess(Instruction *I) {
   return false;
 }
 
   return false;
 }
 
-#include "initializeCallbacks.hpp"
-#include "isAtomicCall.hpp"
-#include "instrumentAtomicCall.hpp"
+void CDSPass::initializeCallbacks(Module &M) {
+       LLVMContext &Ctx = M.getContext();
+
+       Type * Int1Ty = Type::getInt1Ty(Ctx);
+       OrdTy = Type::getInt32Ty(Ctx);
+
+       Int8PtrTy  = Type::getInt8PtrTy(Ctx);
+       Int16PtrTy = Type::getInt16PtrTy(Ctx);
+       Int32PtrTy = Type::getInt32PtrTy(Ctx);
+       Int64PtrTy = Type::getInt64PtrTy(Ctx);
+
+       VoidTy = Type::getVoidTy(Ctx);
+  
+       // Get the function to call from our untime library.
+       for (unsigned i = 0; i < kNumberOfAccessSizes; i++) {
+               const unsigned ByteSize = 1U << i;
+               const unsigned BitSize = ByteSize * 8;
+
+               std::string ByteSizeStr = utostr(ByteSize);
+               std::string BitSizeStr = utostr(BitSize);
+
+               Type *Ty = Type::getIntNTy(Ctx, BitSize);
+               Type *PtrTy = Ty->getPointerTo();
+
+               // uint8_t cds_atomic_load8 (void * obj, int atomic_index)
+               // 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> 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);
+               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) {
+                       CDSAtomicRMW[op][i] = nullptr;
+                       std::string NamePart;
+
+                       if (op == AtomicRMWInst::Xchg)
+                               NamePart = "_exchange";
+                       else if (op == AtomicRMWInst::Add) 
+                               NamePart = "_fetch_add";
+                       else if (op == AtomicRMWInst::Sub)
+                               NamePart = "_fetch_sub";
+                       else if (op == AtomicRMWInst::And)
+                               NamePart = "_fetch_and";
+                       else if (op == AtomicRMWInst::Or)
+                               NamePart = "_fetch_or";
+                       else if (op == AtomicRMWInst::Xor)
+                               NamePart = "_fetch_xor";
+                       else
+                               continue;
+
+                       SmallString<32> AtomicRMWName("cds_atomic" + NamePart + BitSizeStr);
+                       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, Int8PtrTy);
+               CDSAtomicCAS_V2[i] = M.getOrInsertFunction(AtomicCASName_V2, 
+                                                               Int1Ty, PtrTy, PtrTy, Ty, OrdTy, OrdTy, Int8PtrTy);
+       }
+
+       CDSAtomicThreadFence = M.getOrInsertFunction("cds_atomic_thread_fence", 
+                                                                                                       VoidTy, OrdTy, Int8PtrTy);
+}
+
+void printArgs(CallInst *);
+
+bool isAtomicCall(Instruction *I) {
+       if ( auto *CI = dyn_cast<CallInst>(I) ) {
+               Function *fun = CI->getCalledFunction();
+               if (fun == NULL)
+                       return false;
+
+               StringRef funName = fun->getName();
+                // todo: come up with better rules for function name checking
+                if ( funName.contains("atomic_") ) {
+                        return true;
+                } else if (funName.contains("atomic") ) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+void printArgs (CallInst *CI) {
+       Function *fun = CI->getCalledFunction();
+       StringRef funName = fun->getName();
+
+       User::op_iterator begin = CI->arg_begin();
+       User::op_iterator end = CI->arg_end();
+
+       if ( funName.contains("atomic_") ) {
+               std::vector<Value *> parameters;
+
+               for (User::op_iterator it = begin; it != end; ++it) {
+                       Value *param = *it;
+                       parameters.push_back(param);
+                       errs() << *param << " type: " << *param->getType()  << "\n";
+               }
+       }
+
+}
+
+bool CDSPass::instrumentAtomicCall(CallInst *CI, const DataLayout &DL) {
+       IRBuilder<> IRB(CI);
+       Function *fun = CI->getCalledFunction();
+       StringRef funName = fun->getName();
+       std::vector<Value *> parameters;
+
+       User::op_iterator begin = CI->arg_begin();
+       User::op_iterator end = CI->arg_end();
+       for (User::op_iterator it = begin; it != end; ++it) {
+               Value *param = *it;
+               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 (Idx < 0)
+               return false;
+
+       const unsigned ByteSize = 1U << Idx;
+       const unsigned BitSize = ByteSize * 8;
+       Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
+       Type *PtrTy = Ty->getPointerTo();
+
+       // atomic_init; args = {obj, order}
+       if (funName.contains("atomic_init")) {
+               Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
+               Value *val = IRB.CreateBitOrPointerCast(parameters[1], Ty);
+               Value *args[] = {ptr, val, position};
+
+               Instruction* funcInst=CallInst::Create(CDSAtomicInit[Idx], args);
+               ReplaceInstWithInst(CI, funcInst);
+
+               return true;
+       }
+
+       // atomic_load; args = {obj, order}
+       if (funName.contains("atomic_load")) {
+               bool isExplicit = funName.contains("atomic_load_explicit");
+
+               Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
+               Value *order;
+               if (isExplicit)
+                       order = IRB.CreateBitOrPointerCast(parameters[1], OrdTy);
+               else 
+                       order = ConstantInt::get(OrdTy, 
+                                                       (int) AtomicOrderingCABI::seq_cst);
+               Value *args[] = {ptr, order, position};
+               
+               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;
+        }
+
+       // atomic_store; args = {obj, val, order}
+       if (funName.contains("atomic_store")) {
+               bool isExplicit = funName.contains("atomic_store_explicit");
+               Value *OrigVal = parameters[1];
+
+               Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
+               Value *val = IRB.CreatePointerCast(OrigVal, Ty);
+               Value *order;
+               if (isExplicit)
+                       order = IRB.CreateBitOrPointerCast(parameters[2], OrdTy);
+               else 
+                       order = ConstantInt::get(OrdTy, 
+                                                       (int) AtomicOrderingCABI::seq_cst);
+               Value *args[] = {ptr, val, order, position};
+               
+               Instruction* funcInst=CallInst::Create(CDSAtomicStore[Idx], args);
+               ReplaceInstWithInst(CI, funcInst);
+
+               return true;
+       } else if (funName.contains("atomic") && 
+                                funName.contains("EEEE5store")) {
+                // 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;
+        }
+
+
+       // atomic_fetch_*; args = {obj, val, order}
+       if (funName.contains("atomic_fetch_") || 
+                       funName.contains("atomic_exchange") ) {
+               bool isExplicit = funName.contains("_explicit");
+               Value *OrigVal = parameters[1];
+
+               int op;
+               if ( funName.contains("_fetch_add") )
+                       op = AtomicRMWInst::Add;
+               else if ( funName.contains("_fetch_sub") )
+                       op = AtomicRMWInst::Sub;
+               else if ( funName.contains("_fetch_and") )
+                       op = AtomicRMWInst::And;
+               else if ( funName.contains("_fetch_or") )
+                       op = AtomicRMWInst::Or;
+               else if ( funName.contains("_fetch_xor") )
+                       op = AtomicRMWInst::Xor;
+               else if ( funName.contains("atomic_exchange") )
+                       op = AtomicRMWInst::Xchg;
+               else {
+                       errs() << "Unknown atomic read modify write operation\n";
+                       return false;
+               }
+
+               Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
+               Value *val = IRB.CreatePointerCast(OrigVal, Ty);
+               Value *order;
+               if (isExplicit)
+                       order = IRB.CreateBitOrPointerCast(parameters[2], OrdTy);
+               else 
+                       order = ConstantInt::get(OrdTy, 
+                                                       (int) AtomicOrderingCABI::seq_cst);
+               Value *args[] = {ptr, val, order, position};
+               
+               Instruction* funcInst=CallInst::Create(CDSAtomicRMW[op][Idx], args);
+               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}
+       */
+       if ( funName.contains("atomic_compare_exchange_") ) {
+               bool isExplicit = funName.contains("_explicit");
+
+               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;
+               if (isExplicit) {
+                       order_succ = IRB.CreateBitOrPointerCast(parameters[3], OrdTy);
+                       order_fail = IRB.CreateBitOrPointerCast(parameters[4], OrdTy);
+               } else  {
+                       order_succ = ConstantInt::get(OrdTy, 
+                                                       (int) AtomicOrderingCABI::seq_cst);
+                       order_fail = ConstantInt::get(OrdTy, 
+                                                       (int) AtomicOrderingCABI::seq_cst);
+               }
+
+               Value *args[] = {Addr, CmpOperand, NewOperand, 
+                                                       order_succ, order_fail, position};
+               
+               Instruction* funcInst=CallInst::Create(CDSAtomicCAS_V2[Idx], args);
+               ReplaceInstWithInst(CI, funcInst);
+
+               return true;
+       } else if ( funName.contains("compare_exchange_strong") || 
+                                funName.contains("compare_exchange_weak") ) {
+                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;
+        }
+
+
+       return false;
+}
 
 static bool shouldInstrumentReadWriteFromAddress(const Module *M, Value *Addr) {
   // Peel off GEPs and BitCasts.
 
 static bool shouldInstrumentReadWriteFromAddress(const Module *M, Value *Addr) {
   // Peel off GEPs and BitCasts.
@@ -323,8 +626,8 @@ bool CDSPass::instrumentLoadOrStore(Instruction *I,
   if (Addr->isSwiftError())
     return false;
 
   if (Addr->isSwiftError())
     return false;
 
-  int size = getTypeSize(Addr->getType());
-  int index = sizetoindex(size);
+  int Idx = getMemoryAccessFuncIndex(Addr, DL);
+
 
 //  not supported by CDS yet
 /*  if (IsWrite && isVtableAccess(I)) {
 
 //  not supported by CDS yet
 /*  if (IsWrite && isVtableAccess(I)) {
@@ -355,7 +658,7 @@ bool CDSPass::instrumentLoadOrStore(Instruction *I,
 */
 
   Value *OnAccessFunc = nullptr;
 */
 
   Value *OnAccessFunc = nullptr;
-  OnAccessFunc = IsWrite ? CDSStore[index] : CDSLoad[index];
+  OnAccessFunc = IsWrite ? CDSStore[Idx] : CDSLoad[Idx];
   
   Type *ArgType = IRB.CreatePointerCast(Addr, Addr->getType())->getType();
 
   
   Type *ArgType = IRB.CreatePointerCast(Addr, Addr->getType())->getType();
 
@@ -372,7 +675,6 @@ bool CDSPass::instrumentLoadOrStore(Instruction *I,
   return true;
 }
 
   return true;
 }
 
-// todo: replace getTypeSize with the getMemoryAccessFuncIndex
 bool CDSPass::instrumentAtomic(Instruction * I, const DataLayout &DL) {
   IRBuilder<> IRB(I);
   // LLVMContext &Ctx = IRB.getContext();
 bool CDSPass::instrumentAtomic(Instruction * I, const DataLayout &DL) {
   IRBuilder<> IRB(I);
   // LLVMContext &Ctx = IRB.getContext();
@@ -383,56 +685,39 @@ bool CDSPass::instrumentAtomic(Instruction * I, const DataLayout &DL) {
 
   Value *position = getPosition(I, IRB);
 
 
   Value *position = getPosition(I, IRB);
 
-  if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
+  if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
+    Value *Addr = LI->getPointerOperand();
+    int Idx=getMemoryAccessFuncIndex(Addr, DL);
+    int atomic_order_index = getAtomicOrderIndex(LI->getOrdering());
+    Value *order = ConstantInt::get(OrdTy, atomic_order_index);
+    Value *args[] = {Addr, order, position};
+    Instruction* funcInst=CallInst::Create(CDSAtomicLoad[Idx], args);
+    ReplaceInstWithInst(LI, funcInst);
+  } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
+    Value *Addr = SI->getPointerOperand();
+    int Idx=getMemoryAccessFuncIndex(Addr, DL);
     int atomic_order_index = getAtomicOrderIndex(SI->getOrdering());
     int atomic_order_index = getAtomicOrderIndex(SI->getOrdering());
-
     Value *val = SI->getValueOperand();
     Value *val = SI->getValueOperand();
-    Value *ptr = SI->getPointerOperand();
     Value *order = ConstantInt::get(OrdTy, atomic_order_index);
     Value *order = ConstantInt::get(OrdTy, atomic_order_index);
-    Value *args[] = {ptr, val, order, position};
-
-    int size=getTypeSize(ptr->getType());
-    int index=sizetoindex(size);
-
-    Instruction* funcInst=CallInst::Create(CDSAtomicStore[index], args);
+    Value *args[] = {Addr, val, order, position};
+    Instruction* funcInst=CallInst::Create(CDSAtomicStore[Idx], args);
     ReplaceInstWithInst(SI, funcInst);
     ReplaceInstWithInst(SI, funcInst);
-//    errs() << "Store replaced\n";
-  } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
-    int atomic_order_index = getAtomicOrderIndex(LI->getOrdering());
-
-    Value *ptr = LI->getPointerOperand();
-    Value *order = ConstantInt::get(OrdTy, atomic_order_index);
-    Value *args[] = {ptr, order, position};
-
-    int size=getTypeSize(ptr->getType());
-    int index=sizetoindex(size);
-
-    Instruction* funcInst=CallInst::Create(CDSAtomicLoad[index], args);
-    ReplaceInstWithInst(LI, funcInst);
-//    errs() << "Load Replaced\n";
   } else if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(I)) {
   } else if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(I)) {
+    Value *Addr = RMWI->getPointerOperand();
+    int Idx=getMemoryAccessFuncIndex(Addr, DL);
     int atomic_order_index = getAtomicOrderIndex(RMWI->getOrdering());
     int atomic_order_index = getAtomicOrderIndex(RMWI->getOrdering());
-
     Value *val = RMWI->getValOperand();
     Value *val = RMWI->getValOperand();
-    Value *ptr = RMWI->getPointerOperand();
     Value *order = ConstantInt::get(OrdTy, atomic_order_index);
     Value *order = ConstantInt::get(OrdTy, atomic_order_index);
-    Value *args[] = {ptr, val, order, position};
-
-    int size = getTypeSize(ptr->getType());
-    int index = sizetoindex(size);
-
-    Instruction* funcInst = CallInst::Create(CDSAtomicRMW[RMWI->getOperation()][index], args);
+    Value *args[] = {Addr, val, order, position};
+    Instruction* funcInst = CallInst::Create(CDSAtomicRMW[RMWI->getOperation()][Idx], args);
     ReplaceInstWithInst(RMWI, funcInst);
     ReplaceInstWithInst(RMWI, funcInst);
-//    errs() << RMWI->getOperationName(RMWI->getOperation());
-//    errs() << " replaced\n";
   } else if (AtomicCmpXchgInst *CASI = dyn_cast<AtomicCmpXchgInst>(I)) {
     IRBuilder<> IRB(CASI);
 
     Value *Addr = CASI->getPointerOperand();
   } else if (AtomicCmpXchgInst *CASI = dyn_cast<AtomicCmpXchgInst>(I)) {
     IRBuilder<> IRB(CASI);
 
     Value *Addr = CASI->getPointerOperand();
+    int Idx=getMemoryAccessFuncIndex(Addr, DL);
 
 
-    int size = getTypeSize(Addr->getType());
-    int index = sizetoindex(size);
-    const unsigned ByteSize = 1U << index;
+    const unsigned ByteSize = 1U << Idx;
     const unsigned BitSize = ByteSize * 8;
     Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
     Type *PtrTy = Ty->getPointerTo();
     const unsigned BitSize = ByteSize * 8;
     Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
     Type *PtrTy = Ty->getPointerTo();
@@ -449,7 +734,7 @@ bool CDSPass::instrumentAtomic(Instruction * I, const DataLayout &DL) {
                      CmpOperand, NewOperand,
                      order_succ, order_fail, position};
 
                      CmpOperand, NewOperand,
                      order_succ, order_fail, position};
 
-    CallInst *funcInst = IRB.CreateCall(CDSAtomicCAS_V1[index], Args);
+    CallInst *funcInst = IRB.CreateCall(CDSAtomicCAS_V1[Idx], Args);
     Value *Success = IRB.CreateICmpEQ(funcInst, CmpOperand);
 
     Value *OldVal = funcInst;
     Value *Success = IRB.CreateICmpEQ(funcInst, CmpOperand);
 
     Value *OldVal = funcInst;
@@ -485,12 +770,12 @@ int CDSPass::getMemoryAccessFuncIndex(Value *Addr,
   uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy);
   if (TypeSize != 8  && TypeSize != 16 &&
       TypeSize != 32 && TypeSize != 64 && TypeSize != 128) {
   uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy);
   if (TypeSize != 8  && TypeSize != 16 &&
       TypeSize != 32 && TypeSize != 64 && TypeSize != 128) {
-    // NumAccessesWithBadSize++;
+    NumAccessesWithBadSize++;
     // Ignore all unusual sizes.
     return -1;
   }
   size_t Idx = countTrailingZeros(TypeSize / 8);
     // Ignore all unusual sizes.
     return -1;
   }
   size_t Idx = countTrailingZeros(TypeSize / 8);
-  // assert(Idx < FUNCARRAYSIZE);
+  assert(Idx < kNumberOfAccessSizes);
   return Idx;
 }
 
   return Idx;
 }