diff options
author | Nicolai Haehnle <nhaehnle@gmail.com> | 2018-10-31 13:26:48 +0000 |
---|---|---|
committer | Nicolai Haehnle <nhaehnle@gmail.com> | 2018-10-31 13:26:48 +0000 |
commit | 28212cc6891559855d41066d68e64a84097bb749 (patch) | |
tree | 58796a00d00b99291d0b62e166d4dce0242cb6a6 /llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp | |
parent | 2efccd2cf2804e2143c67c01bdfa44c5e3d887ac (diff) | |
download | bcm5719-llvm-28212cc6891559855d41066d68e64a84097bb749.tar.gz bcm5719-llvm-28212cc6891559855d41066d68e64a84097bb749.zip |
AMDGPU: Remove PHI loop condition optimization
Summary:
The optimization to early break out of loops if all threads are dead was
never fully implemented.
But the PHI node analyzing is actually causing a number of problems, so
remove all the extra code for it.
(This does actually regress code quality in a few places because it
ends up relying more heavily on phi's of i1, which we don't do a
great job with. However, since it fixes real bugs in the wild, we
should take this change. I have some prototype changes to improve
i1 lowering in general -- not just for control flow -- which should
help recover the code quality, I just need to make those changes
fit for general consumption. -- Nicolai)
Change-Id: I6fc6c6c8961857ac6009fcfb9f7e5e48dc23fbb1
Patch-by: Christian König <christian.koenig@amd.com>
Reviewers: arsenm, rampitec, tpr
Subscribers: kzhuravl, jvesely, wdng, yaxunl, dstuttard, t-tye, llvm-commits
Differential Revision: https://reviews.llvm.org/D53359
llvm-svn: 345718
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp')
-rw-r--r-- | llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp | 86 |
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); } |