Adds bogus conditional branch after relaxed loads unconditionally (without local... relaxed-loads-noanalysis
authorPeizhao Ou <peizhaoo@uci.edu>
Mon, 2 Apr 2018 22:18:20 +0000 (15:18 -0700)
committerPeizhao Ou <peizhaoo@uci.edu>
Mon, 2 Apr 2018 22:18:20 +0000 (15:18 -0700)
lib/CodeGen/CodeGenPrepare.cpp

index f4ff3787e630347a89b3737db4ebb16239df75e5..dafe786719ef8ee9e63283054c410fa3a75ea3a5 100644 (file)
@@ -823,9 +823,19 @@ void TaintRelaxedLoads(Instruction* UsageInst, Instruction* InsertPoint) {
           Op0->getOpcode() == Instruction::And && Op1 && Op1->isZero()) {
         auto* Op01 = dyn_cast<ConstantInt>(Op0->getOperand(1));
         if (Op01 && Op01->isZero()) {
+          if (UsageInst == CmpInst) {
+            return;
+          }
+
           // Now we have a previously added fake cond branch.
           auto* Op00 = Op0->getOperand(0);
           IRBuilder<true, NoFolder> Builder(CmpInst);
+//          dbgs() << "Tainting existing fake branches: " << *BI << "\n"
+//                 << "\tInstUsage to taint:" << *UsageInst << "\n"
+//                 << "\tBeforeBB:" << *InsertPoint->getParent() << "\n"
+//                 << "\tOp0 =" << *Op0 << "\n"
+//                 << "\tOp00 =" << *Op00 << "\n";
+
           if (Op00->getType() == UsageInst->getType()) {
             AndTarget = UsageInst;
           } else {
@@ -835,6 +845,10 @@ void TaintRelaxedLoads(Instruction* UsageInst, Instruction* InsertPoint) {
           auto* AndZero = dyn_cast<Instruction>(Builder.CreateAnd(
               AndTarget, Constant::getNullValue(AndTarget->getType())));
           CmpInst->setOperand(0, AndZero);
+
+//          dbgs() << "\tAndTarget =" << *AndTarget << "\n"
+//                 << "\tAfterBB:" << *InsertPoint->getParent() << "\n";
+
           return;
         }
       }
@@ -852,6 +866,11 @@ void TaintRelaxedLoads(Instruction* UsageInst, Instruction* InsertPoint) {
   auto* FakeCondition = dyn_cast<Instruction>(Builder.CreateICmp(
       CmpInst::ICMP_NE, AndZero, Constant::getNullValue(AndTarget->getType())));
   AddFakeConditionalBranch(FakeCondition->getNextNode(), FakeCondition);
+
+//  dbgs() << "Adding new fake branches: " << *FakeCondition << "\n"
+//         << "\tInstUsage to taint:" << *UsageInst << "\n"
+//         << "\tAndTarget =" << *AndTarget << "\n"
+//         << "\tAfterBB:" << *FakeCondition->getParent() << "\n";
 }
 
 // XXX-comment: Finds the appropriate Value derived from an atomic load.
@@ -937,42 +956,16 @@ Instruction* findMostRecentDependenceUsage(LoadInst* LI, Instruction* LaterInst,
 
 // XXX-comment: Returns whether the code has been changed.
 bool AddFakeConditionalBranchAfterMonotonicLoads(
-    SmallSet<LoadInst*, 1>& MonotonicLoadInsts, DominatorTree* DT) {
+    SmallVector<LoadInst*, 1>& MonotonicLoadInsts, DominatorTree* DT) {
   bool Changed = false;
   while (!MonotonicLoadInsts.empty()) {
-    auto* LI = *MonotonicLoadInsts.begin();
-    MonotonicLoadInsts.erase(LI);
+    auto* LI = MonotonicLoadInsts.back();
+    MonotonicLoadInsts.pop_back();
     SmallVector<BasicBlock*, 2> ChainedBB;
     auto* FirstInst = findFirstStoreCondBranchInst(LI, &ChainedBB);
-    if (FirstInst != nullptr) {
-      if (FirstInst->getOpcode() == Instruction::Store) {
-        if (StoreAddressDependOnValue(dyn_cast<StoreInst>(FirstInst), LI)) {
-          continue;
-        }
-      } else if (FirstInst->getOpcode() == Instruction::Br) {
-        if (ConditionalBranchDependsOnValue(dyn_cast<BranchInst>(FirstInst),
-                                            LI)) {
-          continue;
-        }
-      } else {
-        IntrinsicInst* II = dyn_cast<IntrinsicInst>(FirstInst);
-        if (!II || II->getIntrinsicID() != Intrinsic::aarch64_stlxr) {
-          dbgs() << "FirstInst=" << *FirstInst << "\n";
-          assert(false && "findFirstStoreCondBranchInst() should return a "
-                          "store/condition branch instruction");
-        }
-      }
-    }
 
     // We really need to process the relaxed load now.
-    StoreInst* SI = nullptr;
-    IntrinsicInst* II = nullptr;
     if (FirstInst) {
-      SI = dyn_cast<StoreInst>(FirstInst);
-      II = dyn_cast<IntrinsicInst>(FirstInst);
-    }
-    if (FirstInst &&
-        (SI || (II && II->getIntrinsicID() == Intrinsic::aarch64_stlxr))) {
       // For immediately coming stores, taint the address of the store.
       if (FirstInst->getParent() == LI->getParent() ||
           DT->dominates(LI, FirstInst)) {
@@ -990,27 +983,8 @@ bool AddFakeConditionalBranchAfterMonotonicLoads(
         }
       }
     } else {
-      // No upcoming branch
-      if (!FirstInst) {
-        TaintRelaxedLoads(LI, nullptr);
-        Changed = true;
-      } else {
-        // For immediately coming branch, directly add a fake branch.
-        if (FirstInst->getParent() == LI->getParent() ||
-            DT->dominates(LI, FirstInst)) {
-          TaintRelaxedLoads(LI, FirstInst);
-          Changed = true;
-        } else {
-          auto* Inst =
-              findMostRecentDependenceUsage(LI, FirstInst, &ChainedBB, DT);
-          if (Inst) {
-            TaintRelaxedLoads(Inst, FirstInst);
-          } else {
-            LI->setOrdering(Acquire);
-          }
-          Changed = true;
-        }
-      }
+      LI->setOrdering(Acquire);
+      Changed = true;
     }
   }
   return Changed;
@@ -1388,7 +1362,7 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
   // XXX-comment: Delay dealing with relaxed loads in this function to avoid
   // further changes done by other passes (e.g., SimplifyCFG).
   // Collect all the relaxed loads.
-  SmallSet<LoadInst*, 1> MonotonicLoadInsts;
+  SmallVector<LoadInst*, 1> MonotonicLoadInsts;
   for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
     if (I->isAtomic()) {
       switch (I->getOpcode()) {
@@ -1396,7 +1370,7 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
           auto* LI = dyn_cast<LoadInst>(&*I);
           if (LI->getOrdering() == Monotonic &&
               !LI->getHasSubsequentAcqlRMW()) {
-            MonotonicLoadInsts.insert(LI);
+            MonotonicLoadInsts.push_back(LI);
           }
           break;
         }