-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[IVDescriptors] Call getOpcode on demand in getReductionOpChain. nfc #118777
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
@llvm/pr-subscribers-llvm-analysis Author: Mel Chen (Mel-Chen) ChangesNon-arithmetic reductions do not require the use of binary opcodes. In the future, once all users of Full diff: https://github.com/llvm/llvm-project/pull/118777.diff 2 Files Affected:
diff --git a/llvm/include/llvm/Analysis/IVDescriptors.h b/llvm/include/llvm/Analysis/IVDescriptors.h
index 5d992faf99d27f..913cd8db894cf0 100644
--- a/llvm/include/llvm/Analysis/IVDescriptors.h
+++ b/llvm/include/llvm/Analysis/IVDescriptors.h
@@ -213,6 +213,9 @@ class RecurrenceDescriptor {
/// Returns true if the recurrence kind is a floating point kind.
static bool isFloatingPointRecurrenceKind(RecurKind Kind);
+ /// Returns true if the recurrence kind is arithmetic.
+ static bool isArithmeticRecurrenceKind(RecurKind Kind);
+
/// Returns true if the recurrence kind is an integer min/max kind.
static bool isIntMinMaxRecurrenceKind(RecurKind Kind) {
return Kind == RecurKind::UMin || Kind == RecurKind::UMax ||
diff --git a/llvm/lib/Analysis/IVDescriptors.cpp b/llvm/lib/Analysis/IVDescriptors.cpp
index e1eb219cf977e1..103f1d3149121b 100644
--- a/llvm/lib/Analysis/IVDescriptors.cpp
+++ b/llvm/lib/Analysis/IVDescriptors.cpp
@@ -60,6 +60,11 @@ bool RecurrenceDescriptor::isFloatingPointRecurrenceKind(RecurKind Kind) {
return (Kind != RecurKind::None) && !isIntegerRecurrenceKind(Kind);
}
+bool RecurrenceDescriptor::isArithmeticRecurrenceKind(RecurKind Kind) {
+ return (Kind != RecurKind::None) && !isMinMaxRecurrenceKind(Kind) &&
+ !isAnyOfRecurrenceKind(Kind);
+}
+
/// Determines if Phi may have been type-promoted. If Phi has a single user
/// that ANDs the Phi with a type mask, return the user. RT is updated to
/// account for the narrower bit width represented by the mask, and the AND
@@ -1063,7 +1068,7 @@ unsigned RecurrenceDescriptor::getOpcode(RecurKind Kind) {
SmallVector<Instruction *, 4>
RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const {
SmallVector<Instruction *, 4> ReductionOperations;
- unsigned RedOp = getOpcode();
+ bool IsArithmetic = isArithmeticRecurrenceKind(Kind);
// Search down from the Phi to the LoopExitInstr, looking for instructions
// with a single user of the correct type for the reduction.
@@ -1081,7 +1086,7 @@ RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const {
// more expensive than out-of-loop reductions, and need to be costed more
// carefully.
unsigned ExpectedUses = 1;
- if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp)
+ if (!IsArithmetic)
ExpectedUses = 2;
auto getNextInstruction = [&](Instruction *Cur) -> Instruction * {
@@ -1089,7 +1094,7 @@ RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const {
Instruction *UI = cast<Instruction>(User);
if (isa<PHINode>(UI))
continue;
- if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) {
+ if (!IsArithmetic) {
// We are expecting a icmp/select pair, which we go to the next select
// instruction if we can. We already know that Cur has 2 uses.
if (isa<SelectInst>(UI))
@@ -1101,7 +1106,7 @@ RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const {
return nullptr;
};
auto isCorrectOpcode = [&](Instruction *Cur) {
- if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) {
+ if (!IsArithmetic) {
Value *LHS, *RHS;
return SelectPatternResult::isMinOrMax(
matchSelectPattern(Cur, LHS, RHS).Flavor);
@@ -1110,7 +1115,7 @@ RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const {
if (isFMulAddIntrinsic(Cur))
return true;
- return Cur->getOpcode() == RedOp;
+ return Cur->getOpcode() == getOpcode();
};
// Attempt to look through Phis which are part of the reduction chain
|
return Cur->getOpcode() == RedOp; | ||
return Cur->getOpcode() == getOpcode(); |
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.
We're checking for opcode here anyway.
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.
Only arithmetic reductions call getOpcode and check the opcode, non-arithmetic won't reach this check statement.
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.
Not sure about this.
llvm/lib/Analysis/IVDescriptors.cpp
Outdated
auto isCorrectOpcode = [&](Instruction *Cur) { | ||
if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) { | ||
if (!IsArithmetic) { |
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.
This function is called isCorrectOpcode(), and it doesn't check opcode anymore?
llvm/lib/Analysis/IVDescriptors.cpp
Outdated
if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) | ||
if (!IsArithmetic) |
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.
Sounds like IsArithmetic needs to be inverted, since we're checking the negation everywhere, but then I wouldn't know what to call the new variable.
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.
We can call it as IsNonArithmetic, I think.
82a107d
1282bd9
to
82a107d
Compare
llvm/lib/Analysis/IVDescriptors.cpp
Outdated
@@ -1081,15 +1086,15 @@ RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const { | |||
// more expensive than out-of-loop reductions, and need to be costed more | |||
// carefully. | |||
unsigned ExpectedUses = 1; | |||
if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) | |||
if (IsNonArithmetic) |
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.
I'm not sure this patch is really NFC because in theory IsNonArithmetic
could be true when Kind is RecurKind::None. Also, even if you remove references to getOpcode
for AnyOf recurrence kinds in this function there are still lots of places in LoopVectorize.cpp that call RecurrenceDescriptor::getOpcode(). It's not obvious to me right now that you can avoid calling getOpcode
for AnyOf types. Also, if you have to specialise the code everywhere to avoid calling getOpcode
for AnyOf kinds wouldn't that make the code even more complicated?
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.
I'm not sure this patch is really NFC because in theory
IsNonArithmetic
could be true when Kind is RecurKind::None.
This is a great reminder, but I don't think Kind
would normally be None
in the function getReductionOpChain
. I believe using an assertion here would be more appropriate.
8dd7cde
Also, even if you remove references to
getOpcode
for AnyOf recurrence kinds in this function there are still lots of places in LoopVectorize.cpp that call RecurrenceDescriptor::getOpcode().
Yes, also in SLP that need to be refined. #121549
This is just the first step in the cleanup.
It's not obvious to me right now that you can avoid calling
getOpcode
for AnyOf types. Also, if you have to specialise the code everywhere to avoid callinggetOpcode
for AnyOf kinds wouldn't that make the code even more complicated?
The main purpose of avoiding to call getOpcode
is to unify AnyOf
.
This won't make things more complicated; the design and usage will be similar to llvm::getRecurrenceIdentity
.
On the contrary, passing the type into getOpcode
would make it more complex #118393 : when an AnyOf
recurrence needs to call getOpcode
, I would first have to determine whether it is a select(icmp ixx)
or select(fcmp float/double...)
before calling getOpcode
.
llvm/lib/Analysis/IVDescriptors.cpp
Outdated
@@ -1063,7 +1068,7 @@ unsigned RecurrenceDescriptor::getOpcode(RecurKind Kind) { | |||
SmallVector<Instruction *, 4> | |||
RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const { | |||
SmallVector<Instruction *, 4> ReductionOperations; | |||
unsigned RedOp = getOpcode(); | |||
bool IsNonArithmetic = !isArithmeticRecurrenceKind(Kind); |
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.
I think I'd prefer this to be:
bool IsComparison = Instruction::ICmp || RedOp == Instruction::FCmp;
or something like that. It's more precise and we don't have to worry about updating isArithmeticRecurrenceKind
every time we add a new recurrence kind. It also explicitly excludes RecurKind::None.
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.
Hmm, I don't want to call getOpcode
for every recurrences. How about adding isComparisonRecurrenceKind
function?
82a107d
to
8dd7cde
Compare
…:createOp (NFC) (llvm#122239) This patch is one part of unifying IAnyOf and FAnyOf reduction. llvm#118393 The related patch is llvm#118777.
8dd7cde
to
367cfd1
Compare
ping |
1 similar comment
ping |
Ping |
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, thanks.
…dency of non-arithmetic reductions on getOpcode.
367cfd1
to
137c6c4
Compare
…lvm#118777) Non-arithmetic reductions do not require the binary opcodes. As a first step toward removing the dependency of non-arithmetic reductions on `getOpcode` function, this patch refactors the `getReductionOpChain` function. In the future, once all users of `getOpcode` function are refactored, an assertion can be added to `getOpcode` function to ensure that only arithmetic reductions rely on it.
…lvm#118777) Non-arithmetic reductions do not require the binary opcodes. As a first step toward removing the dependency of non-arithmetic reductions on `getOpcode` function, this patch refactors the `getReductionOpChain` function. In the future, once all users of `getOpcode` function are refactored, an assertion can be added to `getOpcode` function to ensure that only arithmetic reductions rely on it.
…lvm#118777) Non-arithmetic reductions do not require the binary opcodes. As a first step toward removing the dependency of non-arithmetic reductions on `getOpcode` function, this patch refactors the `getReductionOpChain` function. In the future, once all users of `getOpcode` function are refactored, an assertion can be added to `getOpcode` function to ensure that only arithmetic reductions rely on it.
…lvm#118777) Non-arithmetic reductions do not require the binary opcodes. As a first step toward removing the dependency of non-arithmetic reductions on `getOpcode` function, this patch refactors the `getReductionOpChain` function. In the future, once all users of `getOpcode` function are refactored, an assertion can be added to `getOpcode` function to ensure that only arithmetic reductions rely on it.
Non-arithmetic reductions do not require the binary opcodes.
As a first step toward removing the dependency of non-arithmetic reductions on
getOpcode
function, this patch refactors thegetReductionOpChain
function.In the future, once all users of
getOpcode
function are refactored, an assertion can be added togetOpcode
function to ensure that only arithmetic reductions rely on it.