merge
authorbdemsky <bdemsky@uci.edu>
Fri, 21 Jun 2019 03:38:14 +0000 (20:38 -0700)
committerbdemsky <bdemsky@uci.edu>
Fri, 21 Jun 2019 03:38:14 +0000 (20:38 -0700)
1  2 
CDSPass.cpp

diff --cc CDSPass.cpp
index 354e5bd49b7c00e1845f646c9e98860bbc730486,886621ff7f1e6ed51a15804201f9e141a1d778b0..0cebdf01ac647d65fcaf9d437ef4e6e01ce4358b
@@@ -1,7 -1,7 +1,8 @@@
  //===-- 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.
  //
  #include "llvm/Transforms/IPO/PassManagerBuilder.h"
  #include <vector>
  
--#define DEBUG_TYPE "CDS"
  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);
 +}
  
- #define FUNCARRAYSIZE 4
  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");
  
@@@ -74,10 -62,10 +74,6 @@@ STATISTIC(NumOmittedReadsFromConstantGl
  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;
@@@ -87,18 -75,18 +83,17 @@@ Type * Int64PtrTy
  
  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;
  
--bool start = false;
--
  int getAtomicOrderIndex(AtomicOrdering order){
    switch (order) {
      case AtomicOrdering::Monotonic: 
    }
  }
  
--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;
@@@ -170,281 -158,9 +139,331 @@@ static bool isVtableAccess(Instruction 
    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);
-       Int8Ty  = Type::getInt8Ty(Ctx);
-       Int16Ty = Type::getInt16Ty(Ctx);
-       Int32Ty = Type::getInt32Ty(Ctx);
-       Int64Ty = Type::getInt64Ty(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 < FUNCARRAYSIZE; i++) {
++      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)
- {
++bool isAtomicCall(Instruction *I) {
 +      if ( auto *CI = dyn_cast<CallInst>(I) ) {
 +              Function *fun = CI->getCalledFunction();
 +              if (fun == NULL)
 +                      return false;
 +
 +              StringRef funName = fun->getName();
-               if ( (CI->isTailCall() && funName.contains("atomic_")) ||
-                       funName.contains("atomic_compare_exchange_") ) {
-                       // printArgs(CI);
-                       return true;
++                // 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)
- {
++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.
@@@ -607,8 -323,8 +626,8 @@@ bool CDSPass::instrumentLoadOrStore(Ins
    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)) {
  */
  
    Value *OnAccessFunc = nullptr;
--  OnAccessFunc = IsWrite ? CDSStore[index] : CDSLoad[index];
++  OnAccessFunc = IsWrite ? CDSStore[Idx] : CDSLoad[Idx];
    
    Type *ArgType = IRB.CreatePointerCast(Addr, Addr->getType())->getType();
  
    return true;
  }
  
--// todo: replace getTypeSize with the getMemoryAccessFuncIndex
  bool CDSPass::instrumentAtomic(Instruction * I, const DataLayout &DL) {
    IRBuilder<> IRB(I);
    // LLVMContext &Ctx = IRB.getContext();
  
    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());
--
      Value *val = SI->getValueOperand();
--    Value *ptr = SI->getPointerOperand();
      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);
--//    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)) {
++    Value *Addr = RMWI->getPointerOperand();
++    int Idx=getMemoryAccessFuncIndex(Addr, DL);
      int atomic_order_index = getAtomicOrderIndex(RMWI->getOrdering());
--
      Value *val = RMWI->getValOperand();
--    Value *ptr = RMWI->getPointerOperand();
      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);
--//    errs() << RMWI->getOperationName(RMWI->getOperation());
--//    errs() << " replaced\n";
    } 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();
                       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;
@@@ -769,12 -485,12 +770,12 @@@ int CDSPass::getMemoryAccessFuncIndex(V
    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);
--  // assert(Idx < FUNCARRAYSIZE);
++  assert(Idx < kNumberOfAccessSizes);
    return Idx;
  }