}
}
} else if (I->getNeedTainted()) {
- TaintRelaxedLoads(&*I, I->getNextNode());
+ // Adds a fake conditional branch outside of the RMW loop.
+ auto* LoopBB = I->getParent();
+ auto* LoopTerm = LoopBB->getTerminator();
+ auto* BI = dyn_cast<BranchInst>(LoopTerm);
+ assert(BI && BI->isConditional() && "RMW loop ends with unconditional branch?");
+ BasicBlock* EndBB = BI->getSuccessor(1);
+ if (EndBB == LoopBB) {
+ BI->getSuccessor(0);
+ }
+ TaintAtBlockBeginning(&*I, EndBB, DT);
}
}
EverMadeChange |=
AddFakeConditionalBranch(FakeCondition->getNextNode(), FakeCondition);
}
+// Taints the 'Inst' (i.e., adds a fake conditional block that uses the 'Inst')
+// at the beginning of basic block 'BB'. Note that if 'Inst' does not dominate
+// 'BB', we need to add appropriate an PHI node and taint the PHI node. Returns
+// true if the code is changed, and false otherwise.
+void TaintAtBlockBeginning(Instruction* Inst, BasicBlock* BB, DominatorTree* DT) {
+ auto* CurBB = Inst->getParent();
+ auto* FirstInst = BB->getFirstNonPHI();
+ if (DT->dominates(Inst, FirstInst)) {
+ return TaintRelaxedLoads(&*Inst, FirstInst);
+ }
+ IRBuilder<true, NoFolder> Builder(FirstInst);
+ auto* Phi = Builder.CreatePHI(Inst->getType(), 0, Inst->getName() + ".phi");
+ // Multiple blocks going to BB. We should add a PHI node w.r.t. 'Inst'.
+ for (auto* Pred : predecessors(BB)) {
+ Value* Val = nullptr;
+ if (Pred == CurBB) {
+ Val = Inst;
+ } else {
+ // We don't care what value other paths are.
+ Val = UndefValue::get(Inst->getType());
+ }
+ Phi->addIncoming(Val, Pred);
+ }
+ return TaintRelaxedLoads(Phi, Phi);
+}
+
// XXX-comment: Finds the appropriate Value derived from an atomic load.
// 'ChainedBB' contains all the blocks chained together with unconditional
// branches from LI's parent BB to the block with the first store/cond branch.
// Returns true if the code is changed, and false otherwise.
void TaintRelaxedLoads(Instruction* UsageInst, Instruction* InsertPoint);
+// Taints the 'Inst' (i.e., adds a fake conditional block that uses the 'Inst')
+// at the beginning of basic block 'BB'. Note that if 'Inst' does not dominate
+// 'BB', we need to add appropriate an PHI node and taint the PHI node. Returns
+// true if the code is changed, and false otherwise.
+void TaintAtBlockBeginning(Instruction* Inst, BasicBlock* BB, DominatorTree* DT);
+
// XXX-comment: Finds the appropriate Value derived from an atomic load.
// 'ChainedBB' contains all the blocks chained together with unconditional
// branches from LI's parent BB to the block with the first store/cond branch.