summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2017-03-24 20:57:10 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2017-03-24 20:57:10 +0000
commit0607a4427b11d5899bd18557b8c519e01b798e39 (patch)
treea8ee80ffeb77e77ee5ac06aff51393905a075ee9 /llvm/lib
parent6a1209ee876cbd03c13b53a12478ef8fa63267a7 (diff)
downloadbcm5719-llvm-0607a4427b11d5899bd18557b8c519e01b798e39.tar.gz
bcm5719-llvm-0607a4427b11d5899bd18557b8c519e01b798e39.zip
AMDGPU: Fix annotating loops with nested loop conditions
If the branch condition for a loop was a phi which itself was fed from a phi from a loop, it isn't safe to try to delete the phi until after the loop is handled. llvm-svn: 298737
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp30
1 files changed, 21 insertions, 9 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp b/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
index c9834bf5364..b7e62075244 100644
--- a/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
+++ b/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
@@ -22,6 +22,7 @@
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
using namespace llvm;
@@ -77,7 +78,8 @@ class SIAnnotateControlFlow : public FunctionPass {
void insertElse(BranchInst *Term);
Value *handleLoopCondition(Value *Cond, PHINode *Broken,
- llvm::Loop *L, BranchInst *Term);
+ llvm::Loop *L, BranchInst *Term,
+ SmallVectorImpl<WeakVH> &LoopPhiConditions);
void handleLoop(BranchInst *Term);
@@ -183,8 +185,9 @@ bool SIAnnotateControlFlow::isElse(PHINode *Phi) {
// \brief Erase "Phi" if it is not used any more
void SIAnnotateControlFlow::eraseIfUnused(PHINode *Phi) {
- if (!Phi->hasNUsesOrMore(1))
- Phi->eraseFromParent();
+ if (llvm::RecursivelyDeleteDeadPHINode(Phi)) {
+ DEBUG(dbgs() << "Erased unused condition phi\n");
+ }
}
/// \brief Open a new "If" block
@@ -208,8 +211,10 @@ void SIAnnotateControlFlow::insertElse(BranchInst *Term) {
}
/// \brief Recursively handle the condition leading to a loop
-Value *SIAnnotateControlFlow::handleLoopCondition(Value *Cond, PHINode *Broken,
- llvm::Loop *L, BranchInst *Term) {
+Value *SIAnnotateControlFlow::handleLoopCondition(
+ Value *Cond, PHINode *Broken,
+ llvm::Loop *L, BranchInst *Term,
+ SmallVectorImpl<WeakVH> &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
@@ -233,14 +238,14 @@ Value *SIAnnotateControlFlow::handleLoopCondition(Value *Cond, PHINode *Broken,
}
Phi->setIncomingValue(i, BoolFalse);
- Value *PhiArg = handleLoopCondition(Incoming, Broken, L, Term);
+ 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;
@@ -276,7 +281,7 @@ Value *SIAnnotateControlFlow::handleLoopCondition(Value *Cond, PHINode *Broken,
NewPhi->setIncomingValue(i, PhiArg);
}
- eraseIfUnused(Phi);
+ LoopPhiConditions.push_back(WeakVH(Phi));
return Ret;
}
@@ -318,14 +323,21 @@ void SIAnnotateControlFlow::handleLoop(BranchInst *Term) {
BasicBlock *Target = Term->getSuccessor(1);
PHINode *Broken = PHINode::Create(Int64, 0, "phi.broken", &Target->front());
+ SmallVector<WeakVH, 8> LoopPhiConditions;
Value *Cond = Term->getCondition();
Term->setCondition(BoolTrue);
- Value *Arg = handleLoopCondition(Cond, Broken, L, Term);
+ Value *Arg = handleLoopCondition(Cond, Broken, L, Term, LoopPhiConditions);
for (BasicBlock *Pred : predecessors(Target))
Broken->addIncoming(Pred == BB ? Arg : Int64Zero, Pred);
Term->setCondition(CallInst::Create(Loop, Arg, "", Term));
+
+ for (WeakVH Val : reverse(LoopPhiConditions)) {
+ if (PHINode *Cond = cast_or_null<PHINode>(Val))
+ eraseIfUnused(Cond);
+ }
+
push(Term->getSuccessor(0), Arg);
}
OpenPOWER on IntegriCloud