Skip to content

Commit 6dc6ca3

Browse files
[LoopInterchange] Skip legality check if surrounding loops already guarantee dependency (NFC) (#139254)
The legality check in LoopInterchange allows two loops to be exchanged if all direction vectors are lexicographically positive (or zero) for both before and after the swap. The current implementation performs this routine naively. However, if a direction vector is lexicographically positive due to an element corresponding to a loop that is outside the given two loops (i.e., if there is an element `<` before the loops we are trying to interchange), then obviously it is also positive after exchanging them. For example, for a direction vector `[< < >]`, swapping the last two elements doesn't make it lexicographically negative because the first element is `<`. This patch adds a code to skip legality check if surrounding loops already guarantee that the direction vector is lexicographically positive. Note that this is only a small improvement on its own, but it's necessary to relax the legality check I'm working on. Split off from #118267 --------- Co-authored-by: Michael Kruse <[email protected]>
1 parent fbdb5ae commit 6dc6ca3

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

llvm/lib/Transforms/Scalar/LoopInterchange.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,18 +231,26 @@ static void interChangeDependencies(CharMatrix &DepMatrix, unsigned FromIndx,
231231
std::swap(DepMatrix[I][ToIndx], DepMatrix[I][FromIndx]);
232232
}
233233

234-
// After interchanging, check if the direction vector is valid.
234+
// Check if a direction vector is lexicographically positive. Return true if it
235+
// is positive, nullopt if it is "zero", otherwise false.
235236
// [Theorem] A permutation of the loops in a perfect nest is legal if and only
236237
// if the direction matrix, after the same permutation is applied to its
237238
// columns, has no ">" direction as the leftmost non-"=" direction in any row.
238-
static bool isLexicographicallyPositive(std::vector<char> &DV) {
239-
for (unsigned char Direction : DV) {
239+
static std::optional<bool> isLexicographicallyPositive(std::vector<char> &DV,
240+
unsigned Begin,
241+
unsigned End) {
242+
ArrayRef<char> DVRef(DV);
243+
for (unsigned char Direction : DVRef.slice(Begin, End - Begin)) {
240244
if (Direction == '<')
241245
return true;
242246
if (Direction == '>' || Direction == '*')
243247
return false;
244248
}
245-
return true;
249+
return std::nullopt;
250+
}
251+
252+
static std::optional<bool> isLexicographicallyPositive(std::vector<char> &DV) {
253+
return isLexicographicallyPositive(DV, 0, DV.size());
246254
}
247255

248256
// Checks if it is legal to interchange 2 loops.
@@ -256,10 +264,19 @@ static bool isLegalToInterChangeLoops(CharMatrix &DepMatrix,
256264
// Create temporary DepVector check its lexicographical order
257265
// before and after swapping OuterLoop vs InnerLoop
258266
Cur = DepMatrix[Row];
259-
if (!isLexicographicallyPositive(Cur))
267+
268+
// If the surrounding loops already ensure that the direction vector is
269+
// lexicographically positive, nothing within the loop will be able to break
270+
// the dependence. In such a case we can skip the subsequent check.
271+
if (isLexicographicallyPositive(Cur, 0, OuterLoopId) == true)
272+
continue;
273+
274+
// Check if the direction vector is lexicographically positive (or zero)
275+
// for both before/after exchanged.
276+
if (isLexicographicallyPositive(Cur) == false)
260277
return false;
261278
std::swap(Cur[InnerLoopId], Cur[OuterLoopId]);
262-
if (!isLexicographicallyPositive(Cur))
279+
if (isLexicographicallyPositive(Cur) == false)
263280
return false;
264281
}
265282
return true;

0 commit comments

Comments
 (0)