-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[LoopInterchange] Ignore the cost-model, force interchange if legal #148858
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This is useful for testing purposes, to get more test coverage.
@llvm/pr-subscribers-llvm-transforms Author: Sjoerd Meijer (sjoerdmeijer) ChangesThis is and has been proven useful for testing purposes, to get more test coverage. Full diff: https://github.com/llvm/llvm-project/pull/148858.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index a5008907b9014..b62c25d52861b 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -66,6 +66,10 @@ static cl::opt<unsigned int> MaxMemInstrCount(
"in the dependency matrix. Higher value may lead to more interchanges "
"at the cost of compile-time"));
+static cl::opt<bool> ForceLoopInterchange(
+ "loop-interchange-force", cl::init(false), cl::Hidden,
+ cl::desc("Ignore the cost model, and force interchange if it is legal"));
+
namespace {
using LoopVector = SmallVector<Loop *, 8>;
@@ -599,7 +603,8 @@ struct LoopInterchange {
}
LLVM_DEBUG(dbgs() << "Loops are legal to interchange\n");
LoopInterchangeProfitability LIP(OuterLoop, InnerLoop, SE, ORE);
- if (!LIP.isProfitable(InnerLoop, OuterLoop, InnerLoopId, OuterLoopId,
+ if (!ForceLoopInterchange &&
+ !LIP.isProfitable(InnerLoop, OuterLoop, InnerLoopId, OuterLoopId,
DependencyMatrix, CCM)) {
LLVM_DEBUG(dbgs() << "Interchanging loops not profitable.\n");
return false;
diff --git a/llvm/test/Transforms/LoopInterchange/profitability-vectorization.ll b/llvm/test/Transforms/LoopInterchange/profitability-vectorization.ll
index 16952a66aa78e..59196bbbb9c00 100644
--- a/llvm/test/Transforms/LoopInterchange/profitability-vectorization.ll
+++ b/llvm/test/Transforms/LoopInterchange/profitability-vectorization.ll
@@ -2,6 +2,10 @@
; RUN: -pass-remarks-output=%t -disable-output
; RUN: FileCheck -input-file %t --check-prefix=PROFIT-CACHE %s
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 \
+; RUN: -pass-remarks-output=%t -disable-output -loop-interchange-force=true
+; RUN: FileCheck -input-file %t --check-prefix=PROFIT-VEC %s
+
; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 \
; RUN: -pass-remarks-output=%t -disable-output -loop-interchange-profitabilities=vectorize,cache,instorder
; RUN: FileCheck -input-file %t --check-prefix=PROFIT-VEC %s
|
static cl::opt<bool> ForceLoopInterchange( | ||
"loop-interchange-force", cl::init(false), cl::Hidden, | ||
cl::desc("Ignore the cost model, and force interchange if it is legal")); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better if we call it -loop-interchange-ignore-cost-model
? -force
seems it covers wider scenarios.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about adding something like force
here instead? I personally think it could be useful in some cases, e.g., we can specify -loop-interchange-profitabilities=cache,force
. The behavior is slightly different from -loop-interchange-profitabilities=cache
. The former will interchange the loops if it is not unprofitable for the cache, while the latter will perform the interchange if it is profitable for the cache. The result will differ in cases where it is unclear whether interchanging is profitable or unprofitable for the cache.
; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 \ | ||
; RUN: -pass-remarks-output=%t -disable-output -loop-interchange-force=true | ||
; RUN: FileCheck -input-file %t --check-prefix=PROFIT-VEC %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please add another test case? Interchanging the loops in this test would be beneficial in perspective of vectorizatoin (i.e., isProfitableForVectorization
returns true in this case) because it makes the innermost loop vectorizable. It would be ideal to add a case where interchanging is definitely unprofitable.
Yeah, I don't mind adding it there, that makes sense. I am a little bit undecided, but I am thinking that the combination But I see what you would like to achieve, so let me summarise the kind of 3 states that we could have:
The first one could be achieved by I might do this in a follow up with another patch to address the issue when the cost-model is undecided. I am not totally in love with this, but I think I will add options:
to prefer interchange when the profitability is not clear. I think a separate option |
Sorry, I spaced out and forgot to mention what I’m actually concerned about: the behavior when both Being able to specify something like |
I think that should be forcing interchange, which should be the current behaviour. But I am adding |
✅ With the latest revision this PR passed the C/C++ code formatter. |
// TODO? We ignore the force option when it appears in a list, i.e. it | ||
// should occur as the only option to be effective, as mentioned in the | ||
// help. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// TODO? We ignore the force option when it appears in a list, i.e. it | |
// should occur as the only option to be effective, as mentioned in the | |
// help. | |
shouldInterchange = true; |
|
||
// Return true if interchange is forced. | ||
if (Profitabilities.size() == 1 && Profitabilities[0] == RuleTy::Ignore) | ||
return true; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary if we handle RuleTy::Ignore
properly in the later switch statement.
llvm/test/Transforms/LoopInterchange/profitability-vectorization.ll
Outdated
Show resolved
Hide resolved
Co-authored-by: Ryotaro Kasuga <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
orce interchange can occur odd behavior in some cases. Can you add a test to show it? Here is an example:
int A[4][4][4];
for (int i = 0; i < 4; i++)
for (int j = 1; j < 4; j++)
for (int k = 0; k < 4; k++)
A[3-i][j-1][k] = A[i][j][k];
IIUIC, the following scenario happens due to the bubble-sort based heuristic:
- Try to interchange the 2nd loop (j-loop) and 3rd loop (k-loop). It is legal, so they are interchanged.
- Try to interchange the 1st loop (i-loop) and 2nd loop (k-loop, because the j-loop and k-loop were interchanged). It is illegal, so they are NOT interchanged.
- Try to interchange the 2nd loop (k-loop) and 3rd loop (j-loop). It is legal indeed, so they are interchanged again.
Consequently, the first interchange is reverted, and the final loop order remains the same as the original. I believe this is acceptable, considering that the force interchange option is intended for testing purposes. However, it is worth clarifying this behavior with an example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Please consider to simplify the test, as @fhahn mentioned.
@@ -1311,6 +1324,9 @@ bool LoopInterchangeProfitability::isProfitable( | |||
shouldInterchange = | |||
isProfitableForVectorization(InnerLoopId, OuterLoopId, DepMatrix); | |||
break; | |||
case RuleTy::Ignore: | |||
// Nothing to do, this has no effect. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe using llvm_unreachable
is better?
@@ -0,0 +1,43 @@ | |||
; RUN: opt < %s -passes=loop-interchange -pass-remarks-output=%t -disable-output -loop-interchange-profitabilities=ignore -S |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
orce interchange can occur odd behavior in some cases. Can you add a test to show it? Here is an example:
int A[4][4][4]; for (int i = 0; i < 4; i++) for (int j = 1; j < 4; j++) for (int k = 0; k < 4; k++) A[3-i][j-1][k] = A[i][j][k];IIUIC, the following scenario happens due to the bubble-sort based heuristic:
1. Try to interchange the 2nd loop (j-loop) and 3rd loop (k-loop). It is legal, so they are interchanged. 2. Try to interchange the 1st loop (i-loop) and 2nd loop (k-loop, because the j-loop and k-loop were interchanged). It is illegal, so they are NOT interchanged. 3. Try to interchange the 2nd loop (k-loop) and 3rd loop (j-loop). It is legal indeed, so they are interchanged again.
Consequently, the first interchange is reverted, and the final loop order remains the same as the original. I believe this is acceptable, considering that the force interchange option is intended for testing purposes. However, it is worth clarifying this behavior with an example.
Could you please add this? It's fine to do it in another PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, thanks, I will commit this and look at that suggestion early next week.
This allows me to run more testing over the weekend.
I have already found a couple of interchange problems, but can raise issues when this option is available.
This is and has been proven useful for testing purposes, to get more test coverage.