Skip to content

Commit 18a195e

Browse files
committed
[LoopInterchange] Constrain LI withing supported loop nest depth
This patch is an extension to llvm#115128. After profiling LLVM test-suite, I see a lot of loop nest of depth more than `MaxLoopNestDepth` which is 10. Early exit for them would save compile-time as it would avoid computing DependenceInfo and CacheCost.
1 parent 026fbe5 commit 18a195e

File tree

3 files changed

+108
-13
lines changed

3 files changed

+108
-13
lines changed

llvm/lib/Transforms/Scalar/LoopInterchange.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ using CharMatrix = std::vector<std::vector<char>>;
6969
// Maximum number of dependencies that can be handled in the dependency matrix.
7070
static const unsigned MaxMemInstrCount = 100;
7171

72+
// Minimum loop depth supported.
73+
static const unsigned MinLoopNestDepth = 2;
74+
7275
// Maximum loop depth supported.
7376
static const unsigned MaxLoopNestDepth = 10;
7477

@@ -239,10 +242,12 @@ static void populateWorklist(Loop &L, LoopVector &LoopList) {
239242
LoopList.push_back(CurrentLoop);
240243
}
241244

242-
static bool hasMinimumLoopDepth(SmallVectorImpl<Loop *> &LoopList) {
245+
static bool hasSupportedLoopDepth(SmallVectorImpl<Loop *> &LoopList) {
243246
unsigned LoopNestDepth = LoopList.size();
244-
if (LoopNestDepth < 2) {
245-
LLVM_DEBUG(dbgs() << "Loop doesn't contain minimum nesting level.\n");
247+
if (LoopNestDepth < MinLoopNestDepth || LoopNestDepth > MaxLoopNestDepth) {
248+
LLVM_DEBUG(dbgs() << "Unsupported depth of loop nest " << LoopNestDepth
249+
<< " should be [" << MinLoopNestDepth << ", "
250+
<< MaxLoopNestDepth << "]\n");
246251
return false;
247252
}
248253
return true;
@@ -430,15 +435,10 @@ struct LoopInterchange {
430435
bool processLoopList(SmallVectorImpl<Loop *> &LoopList) {
431436
bool Changed = false;
432437

433-
// Ensure minimum loop nest depth.
434-
assert(hasMinimumLoopDepth(LoopList) && "Loop nest does not meet minimum depth.");
438+
// Ensure proper loop nest depth.
439+
assert(hasSupportedLoopDepth(LoopList) && "Unsupported depth of loop nest.");
435440

436441
unsigned LoopNestDepth = LoopList.size();
437-
if (LoopNestDepth > MaxLoopNestDepth) {
438-
LLVM_DEBUG(dbgs() << "Cannot handle loops of depth greater than "
439-
<< MaxLoopNestDepth << "\n");
440-
return false;
441-
}
442442
if (!isComputableLoopNest(LoopList)) {
443443
LLVM_DEBUG(dbgs() << "Not valid loop candidate for interchange\n");
444444
return false;
@@ -1725,8 +1725,8 @@ PreservedAnalyses LoopInterchangePass::run(LoopNest &LN,
17251725
LPMUpdater &U) {
17261726
Function &F = *LN.getParent();
17271727
SmallVector<Loop *, 8> LoopList(LN.getLoops());
1728-
// Ensure minimum depth of the loop nest to do the interchange.
1729-
if (!hasMinimumLoopDepth(LoopList))
1728+
// Ensure proper depth of the loop nest to do the interchange.
1729+
if (!hasSupportedLoopDepth(LoopList))
17301730
return PreservedAnalyses::all();
17311731

17321732
DependenceInfo DI(&F, &AR.AA, &AR.SE, &AR.LI);

llvm/test/Transforms/LoopInterchange/bail-out-one-loop.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i6
1515
; CHECK-NOT: Delinearizing
1616
; CHECK-NOT: Strides:
1717
; CHECK-NOT: Terms:
18-
; CHECK: Loop doesn't contain minimum nesting level.
18+
; CHECK: Unsupported depth of loop nest 1 should be [2, 10]
1919

2020
define void @foo() {
2121
entry:
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
; REQUIRES: asserts
2+
; RUN: opt < %s -passes=loop-interchange -debug -disable-output 2>&1| FileCheck %s
3+
4+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5+
6+
; For deep loop nest, delinearization should not be run.
7+
8+
; CHECK-NOT: Delinearizing
9+
; CHECK-NOT: Strides:
10+
; CHECK-NOT: Terms:
11+
; CHECK: Unsupported depth of loop nest 11 should be [2, 10]
12+
define void @big_loop_nest() {
13+
entry:
14+
br label %for1.header
15+
16+
for1.header:
17+
%j = phi i64 [ 0, %entry ], [ %j.next, %for1.inc ]
18+
br label %for2.header
19+
for2.header:
20+
%k = phi i64 [ 0, %for1.header ], [ %k.next, %for2.inc ]
21+
br label %for3.header
22+
for3.header:
23+
%l = phi i64 [ 0, %for2.header ], [ %l.next, %for3.inc ]
24+
br label %for4.header
25+
for4.header:
26+
%m = phi i64 [ 0, %for3.header ], [ %m.next, %for4.inc ]
27+
br label %for5.header
28+
for5.header:
29+
%n = phi i64 [ 0, %for4.header ], [ %n.next, %for5.inc ]
30+
br label %for6.header
31+
for6.header:
32+
%o = phi i64 [ 0, %for5.header ], [ %o.next, %for6.inc ]
33+
br label %for7.header
34+
for7.header:
35+
%p = phi i64 [ 0, %for6.header ], [ %p.next, %for7.inc ]
36+
br label %for8.header
37+
for8.header:
38+
%q = phi i64 [ 0, %for7.header ], [ %q.next, %for8.inc ]
39+
br label %for9.header
40+
for9.header:
41+
%r = phi i64 [ 0, %for8.header ], [ %r.next, %for9.inc ]
42+
br label %for10.header
43+
for10.header:
44+
%s = phi i64 [ 0, %for9.header ], [ %s.next, %for10.inc ]
45+
br label %for11
46+
for11:
47+
%t = phi i64 [ %t.next, %for11 ], [ 0, %for10.header ]
48+
%t.next = add nuw nsw i64 %t, 1
49+
%exitcond = icmp eq i64 %t.next, 99
50+
br i1 %exitcond, label %for1.inc, label %for11
51+
52+
for1.inc:
53+
%j.next = add nuw nsw i64 %j, 1
54+
%exitcond26 = icmp eq i64 %j.next, 99
55+
br i1 %exitcond26, label %for2.inc, label %for1.header
56+
for2.inc:
57+
%k.next = add nuw nsw i64 %k, 1
58+
%exitcond27 = icmp eq i64 %j.next, 99
59+
br i1 %exitcond27, label %for3.inc, label %for2.header
60+
for3.inc:
61+
%l.next = add nuw nsw i64 %l, 1
62+
%exitcond28 = icmp eq i64 %l.next, 99
63+
br i1 %exitcond28, label %for4.inc, label %for3.header
64+
for4.inc:
65+
%m.next = add nuw nsw i64 %m, 1
66+
%exitcond29 = icmp eq i64 %m.next, 99
67+
br i1 %exitcond29, label %for5.inc, label %for4.header
68+
for5.inc:
69+
%n.next = add nuw nsw i64 %n, 1
70+
%exitcond30 = icmp eq i64 %n.next, 99
71+
br i1 %exitcond30, label %for6.inc, label %for5.header
72+
for6.inc:
73+
%o.next = add nuw nsw i64 %o, 1
74+
%exitcond31 = icmp eq i64 %o.next, 99
75+
br i1 %exitcond31, label %for7.inc, label %for6.header
76+
for7.inc:
77+
%p.next = add nuw nsw i64 %p, 1
78+
%exitcond32 = icmp eq i64 %p.next, 99
79+
br i1 %exitcond32, label %for8.inc, label %for7.header
80+
for8.inc:
81+
%q.next = add nuw nsw i64 %q, 1
82+
%exitcond33 = icmp eq i64 %q.next, 99
83+
br i1 %exitcond33, label %for9.inc, label %for8.header
84+
for9.inc:
85+
%r.next = add nuw nsw i64 %r, 1
86+
%exitcond34 = icmp eq i64 %q.next, 99
87+
br i1 %exitcond34, label %for10.inc, label %for9.header
88+
for10.inc:
89+
%s.next = add nuw nsw i64 %s, 1
90+
%exitcond35 = icmp eq i64 %s.next, 99
91+
br i1 %exitcond35, label %for.end, label %for10.header
92+
93+
for.end:
94+
ret void
95+
}

0 commit comments

Comments
 (0)