[PATCH] D103959: [LoopDeletion] Handle Phis with similar inputs from different block
Max Kazantsev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 9 05:46:31 PDT 2021
mkazantsev created this revision.
mkazantsev added reviewers: reames, nikic, lebedev.ri, fhahn.
Herald added a subscriber: hiraditya.
mkazantsev requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
This patch lifts the requirement to have the only incoming live blocks for Phis. There can be multiple live blocks
if hte same value comes to phi from all of them.
https://reviews.llvm.org/D103959
Files:
llvm/lib/Transforms/Scalar/LoopDeletion.cpp
llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
Index: llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
===================================================================
--- llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
+++ llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
@@ -667,14 +667,14 @@
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SUM_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[SUB:%.*]] = sub i32 4, [[SUM]]
; CHECK-NEXT: [[IS_POSITIVE:%.*]] = icmp sgt i32 [[SUB]], 0
; CHECK-NEXT: br i1 [[IS_POSITIVE]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
; CHECK: if.true:
; CHECK-NEXT: br i1 undef, label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]]
; CHECK: if.true.1:
-; CHECK-NEXT: br label [[BACKEDGE]]
+; CHECK-NEXT: br label [[BACKEDGE:%.*]]
; CHECK: if.true.2:
; CHECK-NEXT: br label [[BACKEDGE]]
; CHECK: if.false:
@@ -685,9 +685,11 @@
; CHECK-NEXT: br label [[BACKEDGE]]
; CHECK: backedge:
; CHECK-NEXT: [[MERGE_PHI:%.*]] = phi i32 [ 0, [[IF_FALSE_1]] ], [ 0, [[IF_FALSE_2]] ], [ [[SUB]], [[IF_TRUE_1]] ], [ [[SUB]], [[IF_TRUE_2]] ]
-; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[MERGE_PHI]]
+; CHECK-NEXT: [[SUM_NEXT:%.*]] = add i32 [[SUM]], [[MERGE_PHI]]
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[SUM_NEXT]], 4
-; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]]
+; CHECK-NEXT: br i1 [[LOOP_COND]], label [[BACKEDGE_LOOP_CRIT_EDGE:%.*]], label [[DONE:%.*]]
+; CHECK: backedge.loop_crit_edge:
+; CHECK-NEXT: unreachable
; CHECK: done:
; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[BACKEDGE]] ]
; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]
Index: llvm/lib/Transforms/Scalar/LoopDeletion.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopDeletion.cpp
+++ llvm/lib/Transforms/Scalar/LoopDeletion.cpp
@@ -248,20 +248,22 @@
// Check if there is only one predecessor on 1st iteration. Note that because
// we iterate in RPOT, we have already visited all its (non-latch)
// predecessors.
- auto GetSolePredecessorOnFirstIteration = [&](BasicBlock * BB)->BasicBlock * {
+ auto GetSoleInputOnFirstIteration = [&](PHINode & PN)->Value * {
+ BasicBlock *BB = PN.getParent();
if (BB == Header)
- return L->getLoopPredecessor();
- BasicBlock *OnlyPred = nullptr;
+ return PN.getIncomingValueForBlock(L->getLoopPredecessor());
+ Value *OnlyInput = nullptr;
for (auto *Pred : predecessors(BB))
- if (OnlyPred != Pred && LiveEdges.count({ Pred, BB })) {
- // 2 live preds.
- if (OnlyPred)
+ if (LiveEdges.count({ Pred, BB })) {
+ Value *Incoming = PN.getIncomingValueForBlock(Pred);
+ // Two inputs.
+ if (OnlyInput && OnlyInput != Incoming)
return nullptr;
- OnlyPred = Pred;
+ OnlyInput = Incoming;
}
- assert(OnlyPred && "No live predecessors?");
- return OnlyPred;
+ assert(OnlyInput && "No live predecessors?");
+ return OnlyInput;
};
DenseMap<Value *, const SCEV *> FirstIterSCEV;
@@ -289,17 +291,16 @@
}
// If this block has only one live pred, map its phis onto their SCEVs.
- if (auto *OnlyPred = GetSolePredecessorOnFirstIteration(BB))
- for (auto &PN : BB->phis()) {
- if (!SE.isSCEVable(PN.getType()))
- continue;
- auto *Incoming = PN.getIncomingValueForBlock(OnlyPred);
- if (DT.dominates(Incoming, BB->getTerminator())) {
- const SCEV *IncSCEV =
- getSCEVOnFirstIteration(Incoming, L, SE, FirstIterSCEV);
- FirstIterSCEV[&PN] = IncSCEV;
- }
+ for (auto &PN : BB->phis()) {
+ if (!SE.isSCEVable(PN.getType()))
+ continue;
+ auto *Incoming = GetSoleInputOnFirstIteration(PN);
+ if (Incoming && DT.dominates(Incoming, BB->getTerminator())) {
+ const SCEV *IncSCEV =
+ getSCEVOnFirstIteration(Incoming, L, SE, FirstIterSCEV);
+ FirstIterSCEV[&PN] = IncSCEV;
}
+ }
using namespace PatternMatch;
ICmpInst::Predicate Pred;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D103959.350868.patch
Type: text/x-patch
Size: 4292 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210609/3a415a2f/attachment.bin>
More information about the llvm-commits
mailing list