Skip to content

Commit bc145d6

Browse files
committed
[LoopInterchange] Exit early in certain cases in legality check (NFC)
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 an early exit logic for such cases. Note that this is only a small improvement on its own, but it's necessary to relax the legality check I'm working on.
1 parent 370aecb commit bc145d6

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

llvm/lib/Transforms/Scalar/LoopInterchange.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,18 +231,22 @@ 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", othrewise 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;
246250
}
247251

248252
// Checks if it is legal to interchange 2 loops.
@@ -256,10 +260,19 @@ static bool isLegalToInterChangeLoops(CharMatrix &DepMatrix,
256260
// Create temporary DepVector check its lexicographical order
257261
// before and after swapping OuterLoop vs InnerLoop
258262
Cur = DepMatrix[Row];
259-
if (!isLexicographicallyPositive(Cur))
263+
264+
// If the direction vector is lexicographically positive due to an element
265+
// to the left of OuterLoopId, it is still positive after exchanging the two
266+
// loops. In such a case we can skip the subsequent check.
267+
if (isLexicographicallyPositive(Cur, 0, OuterLoopId) == true)
268+
continue;
269+
270+
// Check if the direction vector is lexicographically positive (or zero)
271+
// for both before/after exchanged.
272+
if (isLexicographicallyPositive(Cur, 0, Cur.size()) == false)
260273
return false;
261274
std::swap(Cur[InnerLoopId], Cur[OuterLoopId]);
262-
if (!isLexicographicallyPositive(Cur))
275+
if (isLexicographicallyPositive(Cur, 0, Cur.size()) == false)
263276
return false;
264277
}
265278
return true;

0 commit comments

Comments
 (0)