Skip to content

Commit 619f57f

Browse files
committed
[LoopInterchange] Update the direction of undistributed loop to EQ
This commit enables loop-interchange for the case in #71519. With the loop-interchange, the case can be vectorized. for (int nl = 0; nl < 10000000/256; nl++) // Level 1 for (int i = 0; i < 256; ++i) // Level 2 for (int j = 1; j < 256; j++) // Level 3 aa[j][i] = aa[j - 1][i] + bb[j][i]; The case can't be interchanged without normalizaion. normalizaion didn't occur because the direction of level 1 loop dependence between aa[j][i] and aa[j - 1][i] is default value '*'. By scanning SCEV form of the pointer of aa[j][i] and aa[j - 1][i], the pass and determine the IV of loop 1(nl) didn't affect the value of aa[j][i] and aa[j - 1][i]. And then updating the direction of loop 1 to '=' to enable the normalization.
1 parent cdc9378 commit 619f57f

File tree

2 files changed

+55
-6
lines changed

2 files changed

+55
-6
lines changed

llvm/lib/Transforms/Scalar/LoopInterchange.cpp

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,45 @@ static void dumpDirection(raw_ostream &OS, std::vector<Dependence::DVEntry> &DV,
117117
OS << "]\n";
118118
}
119119

120+
// Get the Loops will affect Expr result.
121+
static void getAffectedLoop(const SCEV *Expr, SmallBitVector &Loops,
122+
ScalarEvolution *SE) {
123+
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
124+
if (!AddRec)
125+
return;
126+
127+
Loops.set(AddRec->getLoop()->getLoopDepth());
128+
const SCEV *Start = AddRec->getStart();
129+
const SCEV *Step = AddRec->getStepRecurrence(*SE);
130+
getAffectedLoop(Start, Loops, SE);
131+
getAffectedLoop(Step, Loops, SE);
132+
}
133+
134+
// Update the Direction of undistributed loop to EQ.
135+
static void
136+
updateUndistributedLoopDirection(std::vector<Dependence::DVEntry> &DV,
137+
unsigned Levels, ScalarEvolution *SE,
138+
Instruction *Src, Instruction *Dst) {
139+
SmallBitVector DistributedLoops(Levels + 1);
140+
Value *SrcPtr = getLoadStorePointerOperand(Src);
141+
Value *DstPtr = getLoadStorePointerOperand(Dst);
142+
const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
143+
const SCEV *DstSCEV = SE->getSCEV(DstPtr);
144+
getAffectedLoop(SrcSCEV, DistributedLoops, SE);
145+
getAffectedLoop(DstSCEV, DistributedLoops, SE);
146+
for (unsigned II = 1; II < Levels; ++II)
147+
// Set the direction of the loop to EQ if the loop won't affect the
148+
// SCEV of Src and Dst.
149+
if (!DistributedLoops.test(II)) {
150+
dbgs() << "Set level " << II << " loop direction to =\n";
151+
DV[II - 1].Direction = Dependence::DVEntry::EQ;
152+
}
153+
}
154+
120155
static bool normalize(std::vector<Dependence::DVEntry> &DV, unsigned Levels,
121-
ScalarEvolution *SE) {
156+
ScalarEvolution *SE, Instruction *Src, Instruction *Dst) {
157+
updateUndistributedLoopDirection(DV, Levels, SE, Src, Dst);
158+
122159
if (!isDirectionNegative(DV, Levels))
123160
return false;
124161

@@ -189,7 +226,7 @@ static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level,
189226
DV[II - 1].Direction = D->getDirection(II);
190227
// If the direction vector is negative, normalize it to
191228
// make it non-negative.
192-
if (normalize(DV, Levels, SE))
229+
if (normalize(DV, Levels, SE, Src, Dst))
193230
LLVM_DEBUG(dbgs() << "Negative dependence vector normalized.\n");
194231
LLVM_DEBUG(StringRef DepType =
195232
D->isFlow() ? "flow" : D->isAnti() ? "anti" : "output";

llvm/test/Transforms/LoopInterchange/pr71519.ll

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,24 @@
55
@aa = global [256 x [256 x float]] zeroinitializer, align 64
66
@bb = global [256 x [256 x float]] zeroinitializer, align 64
77

8-
;; for (int nl = 0; nl < 10000000/256; nl++)
9-
;; for (int i = 0; i < 256; ++i)
10-
;; for (int j = 1; j < 256; j++)
8+
;; This test check that the direction of level 1 loop dependence between
9+
;; aa[j][i] and aa[j - 1][i] will be set to '=' instead of default '*'.
10+
;; Because level 1 loop IV(nl) won't affect the value of aa[j][i] and
11+
;; aa[j - 1][i].
12+
;; By setting to '=' will enable normalize and legalize the interchange.
13+
;;
14+
;; for (int nl = 0; nl < 10000000/256; nl++) // Level 1
15+
;; for (int i = 0; i < 256; ++i) // Level 2
16+
;; for (int j = 1; j < 256; j++) // Level 3
1117
;; aa[j][i] = aa[j - 1][i] + bb[j][i];
1218

13-
; CHECK: Not interchanging loops. Cannot prove legality.
19+
; CHECK: Set level 1 loop direction to =
20+
; CHECK: Before normalizing negative direction vectors:
21+
; CHECK: [= = >]
22+
; CHECK: After normalizing negative direction vectors:
23+
; CGECK: [= = <]
24+
; CHECK: Negative dependence vector normalized.
25+
; CHECK: Loops interchanged.
1426

1527
define float @s231() {
1628
entry:

0 commit comments

Comments
 (0)