Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e3f7762

Browse filesBrowse files
committed
!fixup address latest comments, thanks
1 parent 27a2178 commit e3f7762
Copy full SHA for e3f7762

File tree

3 files changed

+52
-29
lines changed
Filter options

3 files changed

+52
-29
lines changed

‎llvm/include/llvm/Transforms/Utils/LoopPeel.h

Copy file name to clipboardExpand all lines: llvm/include/llvm/Transforms/Utils/LoopPeel.h
+7-3Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,15 @@ namespace llvm {
2121

2222
bool canPeel(const Loop *L);
2323

24+
/// Returns true if the last iteration of \p L can be peeled off. It makes sure
25+
/// the loop exit condition can be adjusted when peeling and that the loop
26+
/// executes at least 2 iterations.
27+
bool canPeelLastIteration(const Loop &L, ScalarEvolution &SE);
28+
2429
/// VMap is the value-map that maps instructions from the original loop to
2530
/// instructions in the last peeled-off iteration. If \p PeelLast is true, peel
26-
/// off the last \p PeelCount iterations from \p L. In that case, the caller has
27-
/// to make sure that the exit condition can be adjusted when peeling and that
28-
/// the loop executes at least 2 iterations.
31+
/// off the last \p PeelCount iterations from \p L (canPeelLastIteration must be
32+
/// true for \p L), otherwise peel off the first \p PeelCount iterations.
2933
bool peelLoop(Loop *L, unsigned PeelCount, bool PeelLast, LoopInfo *LI,
3034
ScalarEvolution *SE, DominatorTree &DT, AssumptionCache *AC,
3135
bool PreserveLCSSA, ValueToValueMapTy &VMap);

‎llvm/lib/Transforms/Utils/LoopPeel.cpp

Copy file name to clipboardExpand all lines: llvm/lib/Transforms/Utils/LoopPeel.cpp
+24-18Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -326,13 +326,7 @@ static unsigned peelToTurnInvariantLoadsDerefencebale(Loop &L,
326326
return 0;
327327
}
328328

329-
/// Returns true if the last iteration can be peeled off and the condition (Pred
330-
/// LeftAR, RightSCEV) is known at the last iteration and the inverse condition
331-
/// is known at the second-to-last. This function also has to make sure the loop
332-
/// exit condition can be adjusted when peeling and that the loop executes at
333-
/// least 2 iterations.
334-
static bool canPeelLastIteration(Loop &L, const SCEVAddRecExpr *LeftAR,
335-
const SCEV *RightSCEV, ScalarEvolution &SE) {
329+
bool llvm::canPeelLastIteration(const Loop &L, ScalarEvolution &SE) {
336330
const SCEV *BTC = SE.getBackedgeTakenCount(&L);
337331
Value *Inc;
338332
CmpPredicate Pred;
@@ -351,16 +345,27 @@ static bool canPeelLastIteration(Loop &L, const SCEVAddRecExpr *LeftAR,
351345
// * the exit condition must be a NE/EQ compare of an induction with step
352346
// of 1.
353347
BasicBlock *Latch = L.getLoopLatch();
354-
if (Latch != L.getExitingBlock() ||
355-
!match(Latch->getTerminator(),
356-
m_Br(m_ICmp(Pred, m_Value(Inc), m_Value()), m_BasicBlock(Succ1),
357-
m_BasicBlock(Succ2))) ||
358-
!((Pred == CmpInst::ICMP_EQ && Succ2 == L.getHeader()) ||
359-
(Pred == CmpInst::ICMP_NE && Succ1 == L.getHeader())) ||
360-
!isa<SCEVAddRecExpr>(SE.getSCEV(Inc)) ||
361-
!cast<SCEVAddRecExpr>(SE.getSCEV(Inc))->getStepRecurrence(SE)->isOne())
348+
return Latch == L.getExitingBlock() &&
349+
match(Latch->getTerminator(),
350+
m_Br(m_ICmp(Pred, m_Value(Inc), m_Value()), m_BasicBlock(Succ1),
351+
m_BasicBlock(Succ2))) &&
352+
((Pred == CmpInst::ICMP_EQ && Succ2 == L.getHeader()) ||
353+
(Pred == CmpInst::ICMP_NE && Succ1 == L.getHeader())) &&
354+
isa<SCEVAddRecExpr>(SE.getSCEV(Inc)) &&
355+
cast<SCEVAddRecExpr>(SE.getSCEV(Inc))->getStepRecurrence(SE)->isOne();
356+
}
357+
358+
/// Returns true if the last iteration can be peeled off and the condition (Pred
359+
/// LeftAR, RightSCEV) is known at the last iteration and the inverse condition
360+
/// is known at the second-to-last.
361+
static bool shouldPeelLastIteration(Loop &L, CmpPredicate Pred,
362+
const SCEVAddRecExpr *LeftAR,
363+
const SCEV *RightSCEV,
364+
ScalarEvolution &SE) {
365+
if (!canPeelLastIteration(L, SE))
362366
return false;
363367

368+
const SCEV *BTC = SE.getBackedgeTakenCount(&L);
364369
const SCEV *ValAtLastIter =
365370
SE.applyLoopGuards(LeftAR->evaluateAtIteration(BTC, SE), &L);
366371
const SCEV *ValAtSecondToLastIter = LeftAR->evaluateAtIteration(
@@ -470,7 +475,7 @@ static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
470475
const SCEV *Step = LeftAR->getStepRecurrence(SE);
471476
if (!PeelWhilePredicateIsKnown(NewPeelCount, IterVal, RightSCEV, Step,
472477
Pred)) {
473-
if (canPeelLastIteration(L, LeftAR, RightSCEV, SE))
478+
if (shouldPeelLastIteration(L, Pred, LeftAR, RightSCEV, SE))
474479
DesiredPeelCount = -1;
475480
return;
476481
}
@@ -987,8 +992,9 @@ bool llvm::peelLoop(Loop *L, unsigned PeelCount, bool PeelLast, LoopInfo *LI,
987992
bool PreserveLCSSA, ValueToValueMapTy &LVMap) {
988993
assert(PeelCount > 0 && "Attempt to peel out zero iterations?");
989994
assert(canPeel(L) && "Attempt to peel a loop which is not peelable?");
990-
assert((!PeelLast || PeelCount == 1) &&
991-
"can only peel off a single iteration from the end for now");
995+
assert((!PeelLast || (canPeelLastIteration(*L, *SE) && PeelCount == 1)) &&
996+
"when peeling the last iteration, the loop must be supported and can "
997+
"only peel a single iteration");
992998

993999
LoopBlocksDFS LoopBlocks(L);
9941000
LoopBlocks.perform(LI);

‎llvm/test/Transforms/LoopUnroll/peel-last-iteration.ll

Copy file name to clipboardExpand all lines: llvm/test/Transforms/LoopUnroll/peel-last-iteration.ll
+21-8Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,27 @@ define i64 @peel_single_block_loop_iv_step_1_eq_pred() {
8787
; CHECK-NEXT: [[ENTRY:.*]]:
8888
; CHECK-NEXT: br label %[[LOOP:.*]]
8989
; CHECK: [[LOOP]]:
90-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
90+
; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV:%.*]], %[[LOOP]] ]
91+
; CHECK-NEXT: call void @foo(i32 20)
92+
; CHECK-NEXT: [[IV]] = add nuw nsw i64 [[IV1]], 1
9193
; CHECK-NEXT: [[CMP18_NOT:%.*]] = icmp eq i64 [[IV]], 63
92-
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP18_NOT]], i32 10, i32 20
94+
; CHECK-NEXT: br i1 [[CMP18_NOT]], label %[[EXIT_PEEL_BEGIN:.*]], label %[[LOOP]], !llvm.loop [[LOOP2:![0-9]+]]
95+
; CHECK: [[EXIT_PEEL_BEGIN]]:
96+
; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LOOP]] ]
97+
; CHECK-NEXT: [[IV_LCSSA1:%.*]] = phi i64 [ [[IV1]], %[[LOOP]] ]
98+
; CHECK-NEXT: br label %[[LOOP_PEEL:.*]]
99+
; CHECK: [[LOOP_PEEL]]:
100+
; CHECK-NEXT: [[CMP_PEEL:%.*]] = icmp eq i64 [[IV_LCSSA]], 63
101+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP_PEEL]], i32 10, i32 20
93102
; CHECK-NEXT: call void @foo(i32 [[COND]])
94-
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
103+
; CHECK-NEXT: [[IV_NEXT:%.*]] = add i64 [[IV_LCSSA]], 1
95104
; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 64
96-
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[LOOP]]
105+
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_PEEL_NEXT:.*]], label %[[EXIT_PEEL_NEXT]]
106+
; CHECK: [[EXIT_PEEL_NEXT]]:
107+
; CHECK-NEXT: br label %[[LOOP_PEEL_NEXT:.*]]
108+
; CHECK: [[LOOP_PEEL_NEXT]]:
109+
; CHECK-NEXT: br label %[[EXIT:.*]]
97110
; CHECK: [[EXIT]]:
98-
; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LOOP]] ]
99111
; CHECK-NEXT: ret i64 [[IV_LCSSA]]
100112
;
101113
entry:
@@ -157,7 +169,7 @@ define i64 @peel_single_block_loop_iv_step_1_nested_loop() {
157169
; CHECK-NEXT: call void @foo(i32 20)
158170
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
159171
; CHECK-NEXT: [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 63
160-
; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[OUTER_LATCH_PEEL_BEGIN:.*]], !llvm.loop [[LOOP2:![0-9]+]]
172+
; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[OUTER_LATCH_PEEL_BEGIN:.*]], !llvm.loop [[LOOP3:![0-9]+]]
161173
; CHECK: [[OUTER_LATCH_PEEL_BEGIN]]:
162174
; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], %[[LOOP]] ]
163175
; CHECK-NEXT: br label %[[LOOP_PEEL:.*]]
@@ -217,7 +229,7 @@ define i64 @peel_multi_block_loop_iv_step_1() {
217229
; CHECK: [[LATCH]]:
218230
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
219231
; CHECK-NEXT: [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 63
220-
; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[EXIT_PEEL_BEGIN:.*]], !llvm.loop [[LOOP3:![0-9]+]]
232+
; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[EXIT_PEEL_BEGIN:.*]], !llvm.loop [[LOOP4:![0-9]+]]
221233
; CHECK: [[EXIT_PEEL_BEGIN]]:
222234
; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], %[[LATCH]] ]
223235
; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LATCH]] ]
@@ -429,7 +441,7 @@ define i32 @peel_loop_with_branch_and_phi_uses(ptr %x, i1 %c) {
429441
; CHECK-NEXT: [[ADD1]] = add nsw i32 [[L1]], [[RED1]]
430442
; CHECK-NEXT: [[IV_NEXT1]] = add nuw nsw i32 [[IV1]], 1
431443
; CHECK-NEXT: [[EC1:%.*]] = icmp ne i32 [[IV_NEXT1]], 99
432-
; CHECK-NEXT: br i1 [[EC1]], label %[[LOOP_HEADER]], label %[[LOOPEXIT_PEEL_BEGIN:.*]], !llvm.loop [[LOOP4:![0-9]+]]
444+
; CHECK-NEXT: br i1 [[EC1]], label %[[LOOP_HEADER]], label %[[LOOPEXIT_PEEL_BEGIN:.*]], !llvm.loop [[LOOP5:![0-9]+]]
433445
; CHECK: [[LOOPEXIT_PEEL_BEGIN]]:
434446
; CHECK-NEXT: [[RED:%.*]] = phi i32 [ [[ADD1]], %[[LOOP_LATCH]] ]
435447
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT1]], %[[LOOP_LATCH]] ]
@@ -497,4 +509,5 @@ declare i1 @cond()
497509
; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[META1]]}
498510
; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META1]]}
499511
; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]]}
512+
; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META1]]}
500513
;.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.