Merge /home/git/c11llvm
[c11llvm.git] / CDSPass.cpp
index 164de72030e29259f06ad382feac1234d2fa46ac..108d4deadd54bceb020085519ea88db0f9ed4a2f 100644 (file)
@@ -115,6 +115,7 @@ namespace {
                static char ID;
                CDSPass() : FunctionPass(ID) {}
                bool runOnFunction(Function &F) override; 
+               StringRef getPassName() const override;
 
        private:
                void initializeCallbacks(Module &M);
@@ -150,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();
@@ -327,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";
@@ -341,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
@@ -366,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(
@@ -384,8 +391,6 @@ bool CDSPass::runOnFunction(Function &F) {
 
                        Res = true;
                }
-
-               F.dump();
        }
 
        return false;
@@ -679,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);
@@ -746,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};
 
@@ -763,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];
 
@@ -786,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);