Merge /home/git/c11llvm
[c11llvm.git] / CDSPass.cpp
index d550140dff5639f147009f15bf998738318bfbfc..108d4deadd54bceb020085519ea88db0f9ed4a2f 100644 (file)
@@ -89,7 +89,6 @@ Type * Int64PtrTy;
 Type * VoidTy;
 
 static const size_t kNumberOfAccessSizes = 4;
-static const int volatile_order = 6;
 
 int getAtomicOrderIndex(AtomicOrdering order){
        switch (order) {
@@ -116,6 +115,7 @@ namespace {
                static char ID;
                CDSPass() : FunctionPass(ID) {}
                bool runOnFunction(Function &F) override; 
+               StringRef getPassName() const override;
 
        private:
                void initializeCallbacks(Module &M);
@@ -151,6 +151,10 @@ namespace {
        };
 }
 
+StringRef CDSPass::getPassName() const {
+       return "CDSPass";
+}
+
 static bool isVtableAccess(Instruction *I) {
        if (MDNode *Tag = I->getMetadata(LLVMContext::MD_tbaa))
                return Tag->isTBAAVtableAccess();
@@ -199,9 +203,9 @@ void CDSPass::initializeCallbacks(Module &M) {
                CDSLoad[i]  = M.getOrInsertFunction(LoadName, VoidTy, PtrTy);
                CDSStore[i] = M.getOrInsertFunction(StoreName, VoidTy, PtrTy);
                CDSVolatileLoad[i]  = M.getOrInsertFunction(VolatileLoadName,
-                                                                       Ty, PtrTy, OrdTy, Int8PtrTy);
+                                                                       Ty, PtrTy, Int8PtrTy);
                CDSVolatileStore[i] = M.getOrInsertFunction(VolatileStoreName, 
-                                                                       VoidTy, PtrTy, Ty, OrdTy, Int8PtrTy);
+                                                                       VoidTy, PtrTy, Ty, Int8PtrTy);
                CDSAtomicInit[i] = M.getOrInsertFunction(AtomicInitName, 
                                                                VoidTy, PtrTy, Ty, Int8PtrTy);
                CDSAtomicLoad[i]  = M.getOrInsertFunction(AtomicLoadName, 
@@ -328,6 +332,7 @@ bool CDSPass::runOnFunction(Function &F) {
 
                bool Res = false;
                bool HasAtomic = false;
+               bool HasVolatile = false;
                const DataLayout &DL = F.getParent()->getDataLayout();
 
                // errs() << "--- " << F.getName() << "---\n";
@@ -342,9 +347,10 @@ bool CDSPass::runOnFunction(Function &F) {
                                        StoreInst *SI = dyn_cast<StoreInst>(&I);
                                        bool isVolatile = ( LI ? LI->isVolatile() : SI->isVolatile() );
 
-                                       if (isVolatile)
+                                       if (isVolatile) {
                                                VolatileLoadsAndStores.push_back(&I);
-                                       else
+                                               HasVolatile = true;
+                                       } else
                                                LocalLoadsAndStores.push_back(&I);
                                } else if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
                                        // not implemented yet
@@ -367,7 +373,7 @@ bool CDSPass::runOnFunction(Function &F) {
                }
 
                // only instrument functions that contain atomics
-               if (Res && HasAtomic) {
+               if (Res && ( HasAtomic || HasVolatile) ) {
                        IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI());
                        /* Unused for now
                        Value *ReturnAddress = IRB.CreateCall(
@@ -506,8 +512,7 @@ bool CDSPass::instrumentVolatile(Instruction * I, const DataLayout &DL) {
                if (Idx < 0)
                        return false;
 
-               Value *order = ConstantInt::get(OrdTy, volatile_order);
-               Value *args[] = {Addr, order, position};
+               Value *args[] = {Addr, position};
                Instruction* funcInst=CallInst::Create(CDSVolatileLoad[Idx], args);
                ReplaceInstWithInst(LI, funcInst);
        } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
@@ -518,8 +523,7 @@ bool CDSPass::instrumentVolatile(Instruction * I, const DataLayout &DL) {
                        return false;
 
                Value *val = SI->getValueOperand();
-               Value *order = ConstantInt::get(OrdTy, volatile_order);
-               Value *args[] = {Addr, val, order, position};
+               Value *args[] = {Addr, val, position};
                Instruction* funcInst=CallInst::Create(CDSVolatileStore[Idx], args);
                ReplaceInstWithInst(SI, funcInst);
        } else {
@@ -680,8 +684,15 @@ bool CDSPass::instrumentAtomicCall(CallInst *CI, const DataLayout &DL) {
 
        // atomic_init; args = {obj, order}
        if (funName.contains("atomic_init")) {
+               Value *OrigVal = parameters[1];
+
                Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
-               Value *val = IRB.CreateBitOrPointerCast(parameters[1], Ty);
+               Value *val;
+               if (OrigVal->getType()->isPtrOrPtrVectorTy())
+                       val = IRB.CreatePointerCast(OrigVal, Ty);
+               else
+                       val = IRB.CreateIntCast(OrigVal, Ty, true);
+
                Value *args[] = {ptr, val, position};
 
                Instruction* funcInst = CallInst::Create(CDSAtomicInit[Idx], args);
@@ -747,12 +758,17 @@ bool CDSPass::instrumentAtomicCall(CallInst *CI, const DataLayout &DL) {
 
                return true;
        } else if (funName.contains("atomic") && 
-                                       funName.contains("EEEE5store") ) {
+                                       funName.contains("store") ) {
                // 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 *val;
+               if (OrigVal->getType()->isPtrOrPtrVectorTy())
+                       val = IRB.CreatePointerCast(OrigVal, Ty);
+               else
+                       val = IRB.CreateIntCast(OrigVal, Ty, true);
+
                Value *order = IRB.CreateBitOrPointerCast(parameters[2], OrdTy);
                Value *args[] = {ptr, val, order, position};
 
@@ -764,7 +780,12 @@ bool CDSPass::instrumentAtomicCall(CallInst *CI, const DataLayout &DL) {
 
        // atomic_fetch_*; args = {obj, val, order}
        if (funName.contains("atomic_fetch_") || 
-                       funName.contains("atomic_exchange") ) {
+               funName.contains("atomic_exchange")) {
+
+               /* TODO: implement stricter function name checking */
+               if (funName.contains("non"))
+                       return false;
+
                bool isExplicit = funName.contains("_explicit");
                Value *OrigVal = parameters[1];
 
@@ -787,7 +808,12 @@ bool CDSPass::instrumentAtomicCall(CallInst *CI, const DataLayout &DL) {
                }
 
                Value *ptr = IRB.CreatePointerCast(OrigPtr, PtrTy);
-               Value *val = IRB.CreatePointerCast(OrigVal, Ty);
+               Value *val;
+               if (OrigVal->getType()->isPtrOrPtrVectorTy())
+                       val = IRB.CreatePointerCast(OrigVal, Ty);
+               else
+                       val = IRB.CreateIntCast(OrigVal, Ty, true);
+
                Value *order;
                if (isExplicit)
                        order = IRB.CreateBitOrPointerCast(parameters[2], OrdTy);