-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[TTI] Support scalable offsets in getScalingFactorCost #88113
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
Changes from 2 commits
49ee8d7
2a61c4d
5228db4
10a454a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,8 @@ class Function; | |
/// Base class for use as a mix-in that aids implementing | ||
/// a TargetTransformInfo-compatible class. | ||
class TargetTransformInfoImplBase { | ||
friend class TargetTransformInfo; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just wondered why this is needed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a leftover from a previous attempt at making an overloaded method to call the existing fixed-only method from the base implementation if there wasn't an override of the newer method. It didn't work out, so I've removed it. Thanks for spotting it. |
||
|
||
protected: | ||
typedef TargetTransformInfo TTI; | ||
|
||
|
@@ -326,12 +328,13 @@ class TargetTransformInfoImplBase { | |
bool prefersVectorizedAddressing() const { return true; } | ||
|
||
InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, | ||
int64_t BaseOffset, bool HasBaseReg, | ||
StackOffset BaseOffset, bool HasBaseReg, | ||
int64_t Scale, | ||
unsigned AddrSpace) const { | ||
// Guess that all legal addressing mode are free. | ||
if (isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, Scale, | ||
AddrSpace)) | ||
if (isLegalAddressingMode(Ty, BaseGV, BaseOffset.getFixed(), HasBaseReg, | ||
Scale, AddrSpace, /*I=*/nullptr, | ||
BaseOffset.getScalable())) | ||
return 0; | ||
return -1; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2571,14 +2571,15 @@ bool ARMTTIImpl::preferPredicatedReductionSelect( | |
} | ||
|
||
InstructionCost ARMTTIImpl::getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, | ||
int64_t BaseOffset, | ||
StackOffset BaseOffset, | ||
bool HasBaseReg, int64_t Scale, | ||
unsigned AddrSpace) const { | ||
TargetLoweringBase::AddrMode AM; | ||
AM.BaseGV = BaseGV; | ||
AM.BaseOffs = BaseOffset; | ||
AM.BaseOffs = BaseOffset.getFixed(); | ||
AM.HasBaseReg = HasBaseReg; | ||
AM.Scale = Scale; | ||
assert(!BaseOffset.getScalable() && "Scalable offsets unsupported"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure this assert is necessary. I'd just assign |
||
if (getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace)) { | ||
if (ST->hasFPAO()) | ||
return AM.Scale < 0 ? 1 : 0; // positive offsets execute faster | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6708,7 +6708,7 @@ InstructionCost X86TTIImpl::getInterleavedMemoryOpCost( | |
} | ||
|
||
InstructionCost X86TTIImpl::getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, | ||
int64_t BaseOffset, | ||
StackOffset BaseOffset, | ||
bool HasBaseReg, int64_t Scale, | ||
unsigned AddrSpace) const { | ||
// Scaling factors are not free at all. | ||
|
@@ -6731,9 +6731,10 @@ InstructionCost X86TTIImpl::getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, | |
// vmovaps %ymm1, (%r8) can use port 2, 3, or 7. | ||
TargetLoweringBase::AddrMode AM; | ||
AM.BaseGV = BaseGV; | ||
AM.BaseOffs = BaseOffset; | ||
AM.BaseOffs = BaseOffset.getFixed(); | ||
AM.HasBaseReg = HasBaseReg; | ||
AM.Scale = Scale; | ||
assert(!BaseOffset.getScalable() && "Scalable offsets unsupported"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above, this is the responsibility of the users of |
||
if (getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace)) | ||
// Scale represents reg2 * scale, thus account for 1 | ||
// as soon as we use a second register. | ||
|
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.
It seems we now have three approaches for passing a 'scalable' and a 'fixed-length' offset to interfaces for this:
StackOffset
(this patch forgetScalingFactorCost
)isLegalAddressingMode
)isLegalAddImmediate
vsisLegalAddScalableImmediate
)It would be good to settle on a single approach. @paulwalker-arm is there a particular reason you're pushing for (1) for this interface?
If we go for (1), I think we should rename
StackOffset
toMemOffset
to make it more generic, because in this instance the offset does not necessarily apply only to stack addresses.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 made my request because the function was changed to take both a fixed-length and a scalar offset, which is exactly why
StackOffset
exists (albeit, as you say, with a name that's now out of date). I think all offset related common code interfaces should be unified to accept the fact they can be fixed or scaled and thus use whichever of the TypeSize.h family of types that best fits the specific need. I'll note we are missing a generic type likeTypeSize
but signed, to make this truly possible.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.
FWIW, my original patches did have a new type like that -- I originally called it AddressOffset, then TargetImmediate. I got some feedback that separating the terms out might be better, so we ended up with different int64_ts.
If we end up with an address formula with both fixed and scalable immediate terms, we'll have to prioritize one over the for a given target other due to the way LSR currently forms the Uses it will evaluate. AFAIK nobody implements instructions with mixed fixed and scalable immediates, so one or the other immediate would need to become part of the base for that formula.