[llvm] [LoopInterchange] Exit early in certain cases in legality check (NFC) (PR #139254)
Ryotaro Kasuga via llvm-commits
llvm-commits at lists.llvm.org
Mon May 12 05:44:43 PDT 2025
https://github.com/kasuga-fj updated https://github.com/llvm/llvm-project/pull/139254
>From bc145d6a4cb91e311af482d85fa2e7f91c29f200 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Fri, 9 May 2025 10:52:47 +0000
Subject: [PATCH 1/4] [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.
---
.../lib/Transforms/Scalar/LoopInterchange.cpp | 25 ++++++++++++++-----
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index fb7bc7c4be6c8..f6d1860e66e1a 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -231,18 +231,22 @@ static void interChangeDependencies(CharMatrix &DepMatrix, unsigned FromIndx,
std::swap(DepMatrix[I][ToIndx], DepMatrix[I][FromIndx]);
}
-// After interchanging, check if the direction vector is valid.
+// Check if a direction vector is lexicographically positive. Return true if it
+// is positive, nullopt if it is "zero", othrewise false.
// [Theorem] A permutation of the loops in a perfect nest is legal if and only
// if the direction matrix, after the same permutation is applied to its
// columns, has no ">" direction as the leftmost non-"=" direction in any row.
-static bool isLexicographicallyPositive(std::vector<char> &DV) {
- for (unsigned char Direction : DV) {
+static std::optional<bool> isLexicographicallyPositive(std::vector<char> &DV,
+ unsigned Begin,
+ unsigned End) {
+ ArrayRef<char> DVRef(DV);
+ for (unsigned char Direction : DVRef.slice(Begin, End - Begin)) {
if (Direction == '<')
return true;
if (Direction == '>' || Direction == '*')
return false;
}
- return true;
+ return std::nullopt;
}
// Checks if it is legal to interchange 2 loops.
@@ -256,10 +260,19 @@ static bool isLegalToInterChangeLoops(CharMatrix &DepMatrix,
// Create temporary DepVector check its lexicographical order
// before and after swapping OuterLoop vs InnerLoop
Cur = DepMatrix[Row];
- if (!isLexicographicallyPositive(Cur))
+
+ // If the direction vector is lexicographically positive due to an element
+ // to the left of OuterLoopId, it is still positive after exchanging the two
+ // loops. In such a case we can skip the subsequent check.
+ if (isLexicographicallyPositive(Cur, 0, OuterLoopId) == true)
+ continue;
+
+ // Check if the direction vector is lexicographically positive (or zero)
+ // for both before/after exchanged.
+ if (isLexicographicallyPositive(Cur, 0, Cur.size()) == false)
return false;
std::swap(Cur[InnerLoopId], Cur[OuterLoopId]);
- if (!isLexicographicallyPositive(Cur))
+ if (isLexicographicallyPositive(Cur, 0, Cur.size()) == false)
return false;
}
return true;
>From cb51f8b0738b122b2279eda36542297cb79ff3b5 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Mon, 12 May 2025 21:36:06 +0900
Subject: [PATCH 2/4] Apply suggestions from code review
Co-authored-by: Michael Kruse <llvm-project at meinersbur.de>
---
llvm/lib/Transforms/Scalar/LoopInterchange.cpp | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index f6d1860e66e1a..e5178a27f98bf 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -232,13 +232,13 @@ static void interChangeDependencies(CharMatrix &DepMatrix, unsigned FromIndx,
}
// Check if a direction vector is lexicographically positive. Return true if it
-// is positive, nullopt if it is "zero", othrewise false.
+// is positive, nullopt if it is "zero", otherwise false.
// [Theorem] A permutation of the loops in a perfect nest is legal if and only
// if the direction matrix, after the same permutation is applied to its
// columns, has no ">" direction as the leftmost non-"=" direction in any row.
static std::optional<bool> isLexicographicallyPositive(std::vector<char> &DV,
- unsigned Begin,
- unsigned End) {
+ unsigned Begin = 0,
+ unsigned End = DV.size()) {
ArrayRef<char> DVRef(DV);
for (unsigned char Direction : DVRef.slice(Begin, End - Begin)) {
if (Direction == '<')
@@ -261,9 +261,8 @@ static bool isLegalToInterChangeLoops(CharMatrix &DepMatrix,
// before and after swapping OuterLoop vs InnerLoop
Cur = DepMatrix[Row];
- // If the direction vector is lexicographically positive due to an element
- // to the left of OuterLoopId, it is still positive after exchanging the two
- // loops. In such a case we can skip the subsequent check.
+ // If the surrounding loops already ensure that the direction vector is lexicographically positive, nothing within the loop will be able to break the dependence.
+ // In such a case we can skip the subsequent check.
if (isLexicographicallyPositive(Cur, 0, OuterLoopId) == true)
continue;
>From f226aa175afd56861d4c1e425a1cf4b790cd0118 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Mon, 12 May 2025 12:41:32 +0000
Subject: [PATCH 3/4] Apply format
---
llvm/lib/Transforms/Scalar/LoopInterchange.cpp | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index e5178a27f98bf..cca27e07b31b0 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -236,9 +236,9 @@ static void interChangeDependencies(CharMatrix &DepMatrix, unsigned FromIndx,
// [Theorem] A permutation of the loops in a perfect nest is legal if and only
// if the direction matrix, after the same permutation is applied to its
// columns, has no ">" direction as the leftmost non-"=" direction in any row.
-static std::optional<bool> isLexicographicallyPositive(std::vector<char> &DV,
- unsigned Begin = 0,
- unsigned End = DV.size()) {
+static std::optional<bool>
+isLexicographicallyPositive(std::vector<char> &DV, unsigned Begin = 0,
+ unsigned End = DV.size()) {
ArrayRef<char> DVRef(DV);
for (unsigned char Direction : DVRef.slice(Begin, End - Begin)) {
if (Direction == '<')
@@ -261,8 +261,9 @@ static bool isLegalToInterChangeLoops(CharMatrix &DepMatrix,
// before and after swapping OuterLoop vs InnerLoop
Cur = DepMatrix[Row];
- // If the surrounding loops already ensure that the direction vector is lexicographically positive, nothing within the loop will be able to break the dependence.
- // In such a case we can skip the subsequent check.
+ // If the surrounding loops already ensure that the direction vector is
+ // lexicographically positive, nothing within the loop will be able to break
+ // the dependence. In such a case we can skip the subsequent check.
if (isLexicographicallyPositive(Cur, 0, OuterLoopId) == true)
continue;
>From 4eaf657d4b71865c67f74c9ba30cea0ab40f78e6 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Mon, 12 May 2025 12:42:43 +0000
Subject: [PATCH 4/4] Fix default arguments
---
llvm/lib/Transforms/Scalar/LoopInterchange.cpp | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index cca27e07b31b0..e101943a3f615 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -236,9 +236,9 @@ static void interChangeDependencies(CharMatrix &DepMatrix, unsigned FromIndx,
// [Theorem] A permutation of the loops in a perfect nest is legal if and only
// if the direction matrix, after the same permutation is applied to its
// columns, has no ">" direction as the leftmost non-"=" direction in any row.
-static std::optional<bool>
-isLexicographicallyPositive(std::vector<char> &DV, unsigned Begin = 0,
- unsigned End = DV.size()) {
+static std::optional<bool> isLexicographicallyPositive(std::vector<char> &DV,
+ unsigned Begin,
+ unsigned End) {
ArrayRef<char> DVRef(DV);
for (unsigned char Direction : DVRef.slice(Begin, End - Begin)) {
if (Direction == '<')
@@ -249,6 +249,10 @@ isLexicographicallyPositive(std::vector<char> &DV, unsigned Begin = 0,
return std::nullopt;
}
+static std::optional<bool> isLexicographicallyPositive(std::vector<char> &DV) {
+ return isLexicographicallyPositive(DV, 0, DV.size());
+}
+
// Checks if it is legal to interchange 2 loops.
static bool isLegalToInterChangeLoops(CharMatrix &DepMatrix,
unsigned InnerLoopId,
@@ -269,10 +273,10 @@ static bool isLegalToInterChangeLoops(CharMatrix &DepMatrix,
// Check if the direction vector is lexicographically positive (or zero)
// for both before/after exchanged.
- if (isLexicographicallyPositive(Cur, 0, Cur.size()) == false)
+ if (isLexicographicallyPositive(Cur) == false)
return false;
std::swap(Cur[InnerLoopId], Cur[OuterLoopId]);
- if (isLexicographicallyPositive(Cur, 0, Cur.size()) == false)
+ if (isLexicographicallyPositive(Cur) == false)
return false;
}
return true;
More information about the llvm-commits
mailing list