summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp86
1 files changed, 3 insertions, 83 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp b/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
index 8248dbe1b0f..90f430d5ca4 100644
--- a/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
+++ b/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
@@ -66,9 +66,7 @@ class SIAnnotateControlFlow : public FunctionPass {
Function *If;
Function *Else;
- Function *Break;
Function *IfBreak;
- Function *ElseBreak;
Function *Loop;
Function *EndCf;
@@ -95,8 +93,7 @@ class SIAnnotateControlFlow : public FunctionPass {
Value *
handleLoopCondition(Value *Cond, PHINode *Broken, llvm::Loop *L,
- BranchInst *Term,
- SmallVectorImpl<WeakTrackingVH> &LoopPhiConditions);
+ BranchInst *Term);
void handleLoop(BranchInst *Term);
@@ -149,9 +146,7 @@ bool SIAnnotateControlFlow::doInitialization(Module &M) {
If = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_if);
Else = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_else);
- Break = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_break);
IfBreak = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_if_break);
- ElseBreak = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_else_break);
Loop = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_loop);
EndCf = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_end_cf);
return false;
@@ -227,76 +222,7 @@ void SIAnnotateControlFlow::insertElse(BranchInst *Term) {
/// Recursively handle the condition leading to a loop
Value *SIAnnotateControlFlow::handleLoopCondition(
- Value *Cond, PHINode *Broken, llvm::Loop *L, BranchInst *Term,
- SmallVectorImpl<WeakTrackingVH> &LoopPhiConditions) {
- // Only search through PHI nodes which are inside the loop. If we try this
- // with PHI nodes that are outside of the loop, we end up inserting new PHI
- // nodes outside of the loop which depend on values defined inside the loop.
- // This will break the module with
- // 'Instruction does not dominate all users!' errors.
- PHINode *Phi = nullptr;
- if ((Phi = dyn_cast<PHINode>(Cond)) && L->contains(Phi)) {
- BasicBlock *Parent = Phi->getParent();
- PHINode *NewPhi = PHINode::Create(Int64, 0, "loop.phi", &Parent->front());
- Value *Ret = NewPhi;
-
- // Handle all non-constant incoming values first
- for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
- Value *Incoming = Phi->getIncomingValue(i);
- BasicBlock *From = Phi->getIncomingBlock(i);
- if (isa<ConstantInt>(Incoming)) {
- NewPhi->addIncoming(Broken, From);
- continue;
- }
-
- Phi->setIncomingValue(i, BoolFalse);
- Value *PhiArg = handleLoopCondition(Incoming, Broken, L,
- Term, LoopPhiConditions);
- NewPhi->addIncoming(PhiArg, From);
- }
-
- BasicBlock *IDom = DT->getNode(Parent)->getIDom()->getBlock();
-
- for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
- Value *Incoming = Phi->getIncomingValue(i);
- if (Incoming != BoolTrue)
- continue;
-
- BasicBlock *From = Phi->getIncomingBlock(i);
- if (From == IDom) {
- // We're in the following situation:
- // IDom/From
- // | \
- // | If-block
- // | /
- // Parent
- // where we want to break out of the loop if the If-block is not taken.
- // Due to the depth-first traversal, there should be an end.cf
- // intrinsic in Parent, and we insert an else.break before it.
- //
- // Note that the end.cf need not be the first non-phi instruction
- // of parent, particularly when we're dealing with a multi-level
- // break, but it should occur within a group of intrinsic calls
- // at the beginning of the block.
- CallInst *OldEnd = dyn_cast<CallInst>(Parent->getFirstInsertionPt());
- while (OldEnd && OldEnd->getCalledFunction() != EndCf)
- OldEnd = dyn_cast<CallInst>(OldEnd->getNextNode());
- if (OldEnd && OldEnd->getCalledFunction() == EndCf) {
- Value *Args[] = { OldEnd->getArgOperand(0), NewPhi };
- Ret = CallInst::Create(ElseBreak, Args, "", OldEnd);
- continue;
- }
- }
-
- Instruction *Insert = From->getTerminator();
- Value *PhiArg = CallInst::Create(Break, Broken, "", Insert);
- NewPhi->setIncomingValue(i, PhiArg);
- }
-
- LoopPhiConditions.push_back(WeakTrackingVH(Phi));
- return Ret;
- }
-
+ Value *Cond, PHINode *Broken, llvm::Loop *L, BranchInst *Term) {
if (Instruction *Inst = dyn_cast<Instruction>(Cond)) {
BasicBlock *Parent = Inst->getParent();
Instruction *Insert;
@@ -335,21 +261,15 @@ void SIAnnotateControlFlow::handleLoop(BranchInst *Term) {
BasicBlock *Target = Term->getSuccessor(1);
PHINode *Broken = PHINode::Create(Int64, 0, "phi.broken", &Target->front());
- SmallVector<WeakTrackingVH, 8> LoopPhiConditions;
Value *Cond = Term->getCondition();
Term->setCondition(BoolTrue);
- Value *Arg = handleLoopCondition(Cond, Broken, L, Term, LoopPhiConditions);
+ Value *Arg = handleLoopCondition(Cond, Broken, L, Term);
for (BasicBlock *Pred : predecessors(Target))
Broken->addIncoming(Pred == BB ? Arg : Int64Zero, Pred);
Term->setCondition(CallInst::Create(Loop, Arg, "", Term));
- for (WeakTrackingVH Val : llvm::reverse(LoopPhiConditions)) {
- if (PHINode *Cond = cast_or_null<PHINode>(Val))
- eraseIfUnused(Cond);
- }
-
push(Term->getSuccessor(0), Arg);
}
OpenPOWER on IntegriCloud