[llvm] [TTI] Constify BasicTTIImplBase::thisT() (PR #136575)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 21 09:54:48 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
@llvm/pr-subscribers-backend-arm
Author: Sergei Barannikov (s-barannikov)
<details>
<summary>Changes</summary>
The main change is making `thisT` method `const`, the rest of the
changes is fixing compilation errors (*).
(*) There are two tricky methods, `getVectorInstrCost()` and
`getIntImmCost()`.
They have several overloads; some of these overloads are typically
pulled in to derived classes using the `using` directive, and then
hidden by methods in the derived class.
The compiler does not complain if the hiding methods are not marked as
`const`, which means that clients will use the methods from the base
class. If after this change your target fails cost model tests, this
must be the reason. To resolve the issue you need to make all hiding
overloads `const`. See the second commit in this PR.
---
Patch is 149.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/136575.diff
26 Files Affected:
- (modified) llvm/include/llvm/Analysis/TargetTransformInfoImpl.h (+2)
- (modified) llvm/include/llvm/CodeGen/BasicTTIImpl.h (+50-44)
- (modified) llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp (+24-23)
- (modified) llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h (+32-28)
- (modified) llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp (+7-8)
- (modified) llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h (+13-10)
- (modified) llvm/lib/Target/AMDGPU/R600TargetTransformInfo.cpp (+2-2)
- (modified) llvm/lib/Target/AMDGPU/R600TargetTransformInfo.h (+3-2)
- (modified) llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp (+16-17)
- (modified) llvm/lib/Target/ARM/ARMTargetTransformInfo.h (+27-23)
- (modified) llvm/lib/Target/BPF/BPFTargetTransformInfo.h (+3-2)
- (modified) llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp (+12-13)
- (modified) llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.h (+17-15)
- (modified) llvm/lib/Target/Lanai/LanaiTargetTransformInfo.h (+2-1)
- (modified) llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.cpp (+1-2)
- (modified) llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h (+3-2)
- (modified) llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp (+11-11)
- (modified) llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h (+16-14)
- (modified) llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp (+28-27)
- (modified) llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h (+39-37)
- (modified) llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.cpp (+18-20)
- (modified) llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.h (+27-21)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.cpp (+6-7)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.h (+6-4)
- (modified) llvm/lib/Target/X86/X86TargetTransformInfo.cpp (+24-23)
- (modified) llvm/lib/Target/X86/X86TargetTransformInfo.h (+32-29)
``````````diff
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index 3fe0a9101fdee..ea481baddc5c3 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -47,6 +47,8 @@ class TargetTransformInfoImplBase {
const DataLayout &getDataLayout() const { return DL; }
+ // FIXME: It looks like this implementation is dead. All clients appear to
+ // use the (non-const) version from `TargetTransformInfoImplCRTPBase`.
InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr,
ArrayRef<const Value *> Operands, Type *AccessType,
TTI::TargetCostKind CostKind) const {
diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index f6ec21caa4d72..b42223eda9922 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -84,12 +84,13 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
using TTI = TargetTransformInfo;
/// Helper function to access this as a T.
- T *thisT() { return static_cast<T *>(this); }
+ const T *thisT() const { return static_cast<const T *>(this); }
/// Estimate a cost of Broadcast as an extract and sequence of insert
/// operations.
- InstructionCost getBroadcastShuffleOverhead(FixedVectorType *VTy,
- TTI::TargetCostKind CostKind) {
+ InstructionCost
+ getBroadcastShuffleOverhead(FixedVectorType *VTy,
+ TTI::TargetCostKind CostKind) const {
InstructionCost Cost = 0;
// Broadcast cost is equal to the cost of extracting the zero'th element
// plus the cost of inserting it into every element of the result vector.
@@ -105,8 +106,9 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
/// Estimate a cost of shuffle as a sequence of extract and insert
/// operations.
- InstructionCost getPermuteShuffleOverhead(FixedVectorType *VTy,
- TTI::TargetCostKind CostKind) {
+ InstructionCost
+ getPermuteShuffleOverhead(FixedVectorType *VTy,
+ TTI::TargetCostKind CostKind) const {
InstructionCost Cost = 0;
// Shuffle cost is equal to the cost of extracting element from its argument
// plus the cost of inserting them onto the result vector.
@@ -129,7 +131,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
InstructionCost getExtractSubvectorOverhead(VectorType *VTy,
TTI::TargetCostKind CostKind,
int Index,
- FixedVectorType *SubVTy) {
+ FixedVectorType *SubVTy) const {
assert(VTy && SubVTy &&
"Can only extract subvectors from vectors");
int NumSubElts = SubVTy->getNumElements();
@@ -157,7 +159,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
InstructionCost getInsertSubvectorOverhead(VectorType *VTy,
TTI::TargetCostKind CostKind,
int Index,
- FixedVectorType *SubVTy) {
+ FixedVectorType *SubVTy) const {
assert(VTy && SubVTy &&
"Can only insert subvectors into vectors");
int NumSubElts = SubVTy->getNumElements();
@@ -211,7 +213,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
bool VariableMask,
bool IsGatherScatter,
TTI::TargetCostKind CostKind,
- unsigned AddressSpace = 0) {
+ unsigned AddressSpace = 0) const {
// We cannot scalarize scalable vectors, so return Invalid.
if (isa<ScalableVectorType>(DataTy))
return InstructionCost::getInvalid();
@@ -299,7 +301,8 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
/// (e.g. scalarization).
std::optional<InstructionCost> getMultipleResultIntrinsicVectorLibCallCost(
const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind,
- RTLIB::Libcall LC, std::optional<unsigned> CallRetElementIndex = {}) {
+ RTLIB::Libcall LC,
+ std::optional<unsigned> CallRetElementIndex = {}) const {
Type *RetTy = ICA.getReturnType();
// Vector variants of the intrinsic can be mapped to a vector library call.
auto const *LibInfo = ICA.getLibInfo();
@@ -866,7 +869,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
const APInt &DemandedElts,
bool Insert, bool Extract,
TTI::TargetCostKind CostKind,
- ArrayRef<Value *> VL = {}) {
+ ArrayRef<Value *> VL = {}) const {
/// FIXME: a bitfield is not a reasonable abstraction for talking about
/// which elements are needed from a scalable vector
if (isa<ScalableVectorType>(InTy))
@@ -917,7 +920,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
/// Helper wrapper for the DemandedElts variant of getScalarizationOverhead.
InstructionCost getScalarizationOverhead(VectorType *InTy, bool Insert,
bool Extract,
- TTI::TargetCostKind CostKind) {
+ TTI::TargetCostKind CostKind) const {
if (isa<ScalableVectorType>(InTy))
return InstructionCost::getInvalid();
auto *Ty = cast<FixedVectorType>(InTy);
@@ -933,7 +936,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
InstructionCost
getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
ArrayRef<Type *> Tys,
- TTI::TargetCostKind CostKind) {
+ TTI::TargetCostKind CostKind) const {
assert(Args.size() == Tys.size() && "Expected matching Args and Tys");
InstructionCost Cost = 0;
@@ -963,7 +966,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
InstructionCost getScalarizationOverhead(VectorType *RetTy,
ArrayRef<const Value *> Args,
ArrayRef<Type *> Tys,
- TTI::TargetCostKind CostKind) {
+ TTI::TargetCostKind CostKind) const {
InstructionCost Cost = getScalarizationOverhead(
RetTy, /*Insert*/ true, /*Extract*/ false, CostKind);
if (!Args.empty())
@@ -1018,7 +1021,8 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
TTI::OperandValueInfo Opd1Info = {TTI::OK_AnyValue, TTI::OP_None},
TTI::OperandValueInfo Opd2Info = {TTI::OK_AnyValue, TTI::OP_None},
- ArrayRef<const Value *> Args = {}, const Instruction *CxtI = nullptr) {
+ ArrayRef<const Value *> Args = {},
+ const Instruction *CxtI = nullptr) const {
// Check if any of the operands are vector operands.
const TargetLoweringBase *TLI = getTLI();
int ISD = TLI->InstructionOpcodeToISD(Opcode);
@@ -1147,7 +1151,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
TTI::TargetCostKind CostKind, int Index,
VectorType *SubTp,
ArrayRef<const Value *> Args = {},
- const Instruction *CxtI = nullptr) {
+ const Instruction *CxtI = nullptr) const {
switch (improveShuffleKindFromMask(Kind, Mask, Tp, Index, SubTp)) {
case TTI::SK_Broadcast:
if (auto *FVT = dyn_cast<FixedVectorType>(Tp))
@@ -1175,7 +1179,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
TTI::CastContextHint CCH,
TTI::TargetCostKind CostKind,
- const Instruction *I = nullptr) {
+ const Instruction *I = nullptr) const {
if (BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I) == 0)
return 0;
@@ -1289,7 +1293,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
DstVTy->getElementCount().isVector()) {
Type *SplitDstTy = VectorType::getHalfElementsVectorType(DstVTy);
Type *SplitSrcTy = VectorType::getHalfElementsVectorType(SrcVTy);
- T *TTI = static_cast<T *>(this);
+ const T *TTI = thisT();
// If both types need to be split then the split is free.
InstructionCost SplitCost =
(!SplitSrc || !SplitDst) ? TTI->getVectorSplitCost() : 0;
@@ -1342,7 +1346,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
}
InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,
- const Instruction *I = nullptr) {
+ const Instruction *I = nullptr) const {
return BaseT::getCFInstrCost(Opcode, CostKind, I);
}
@@ -1351,7 +1355,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
TTI::TargetCostKind CostKind,
TTI::OperandValueInfo Op1Info = {TTI::OK_AnyValue, TTI::OP_None},
TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None},
- const Instruction *I = nullptr) {
+ const Instruction *I = nullptr) const {
const TargetLoweringBase *TLI = getTLI();
int ISD = TLI->InstructionOpcodeToISD(Opcode);
assert(ISD && "Invalid opcode");
@@ -1401,7 +1405,8 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val,
TTI::TargetCostKind CostKind,
- unsigned Index, Value *Op0, Value *Op1) {
+ unsigned Index, Value *Op0,
+ Value *Op1) const {
return getRegUsageForType(Val->getScalarType());
}
@@ -1430,10 +1435,10 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
Op1);
}
- InstructionCost getReplicationShuffleCost(Type *EltTy, int ReplicationFactor,
- int VF,
- const APInt &DemandedDstElts,
- TTI::TargetCostKind CostKind) {
+ InstructionCost
+ getReplicationShuffleCost(Type *EltTy, int ReplicationFactor, int VF,
+ const APInt &DemandedDstElts,
+ TTI::TargetCostKind CostKind) const {
assert(DemandedDstElts.getBitWidth() == (unsigned)VF * ReplicationFactor &&
"Unexpected size of DemandedDstElts.");
@@ -1463,11 +1468,11 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
return Cost;
}
- InstructionCost
- getMemoryOpCost(unsigned Opcode, Type *Src, MaybeAlign Alignment,
- unsigned AddressSpace, TTI::TargetCostKind CostKind,
- TTI::OperandValueInfo OpInfo = {TTI::OK_AnyValue, TTI::OP_None},
- const Instruction *I = nullptr) {
+ InstructionCost getMemoryOpCost(
+ unsigned Opcode, Type *Src, MaybeAlign Alignment, unsigned AddressSpace,
+ TTI::TargetCostKind CostKind,
+ TTI::OperandValueInfo OpInfo = {TTI::OK_AnyValue, TTI::OP_None},
+ const Instruction *I = nullptr) const {
assert(!Src->isVoidTy() && "Invalid type");
// Assume types, such as structs, are expensive.
if (getTLI()->getValueType(DL, Src, true) == MVT::Other)
@@ -1510,7 +1515,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
InstructionCost getMaskedMemoryOpCost(unsigned Opcode, Type *DataTy,
Align Alignment, unsigned AddressSpace,
- TTI::TargetCostKind CostKind) {
+ TTI::TargetCostKind CostKind) const {
// TODO: Pass on AddressSpace when we have test coverage.
return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment, true, false,
CostKind);
@@ -1520,14 +1525,14 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
const Value *Ptr, bool VariableMask,
Align Alignment,
TTI::TargetCostKind CostKind,
- const Instruction *I = nullptr) {
+ const Instruction *I = nullptr) const {
return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment, VariableMask,
true, CostKind);
}
InstructionCost getExpandCompressMemoryOpCost(
unsigned Opcode, Type *DataTy, bool VariableMask, Align Alignment,
- TTI::TargetCostKind CostKind, const Instruction *I = nullptr) {
+ TTI::TargetCostKind CostKind, const Instruction *I = nullptr) const {
// Treat expand load/compress store as gather/scatter operation.
// TODO: implement more precise cost estimation for these intrinsics.
return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment, VariableMask,
@@ -1538,7 +1543,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
const Value *Ptr, bool VariableMask,
Align Alignment,
TTI::TargetCostKind CostKind,
- const Instruction *I) {
+ const Instruction *I) const {
// For a target without strided memory operations (or for an illegal
// operation type on one which does), assume we lower to a gather/scatter
// operation. (Which may in turn be scalarized.)
@@ -1691,7 +1696,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
/// Get intrinsic cost based on arguments.
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
- TTI::TargetCostKind CostKind) {
+ TTI::TargetCostKind CostKind) const {
// Check for generically free intrinsics.
if (BaseT::getIntrinsicInstrCost(ICA, CostKind) == 0)
return 0;
@@ -2095,7 +2100,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
/// based on types.
InstructionCost
getTypeBasedIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
- TTI::TargetCostKind CostKind) {
+ TTI::TargetCostKind CostKind) const {
Intrinsic::ID IID = ICA.getID();
Type *RetTy = ICA.getReturnType();
const SmallVectorImpl<Type *> &Tys = ICA.getArgTypes();
@@ -2859,11 +2864,11 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
/// \returns The cost of Call instruction.
InstructionCost getCallInstrCost(Function *F, Type *RetTy,
ArrayRef<Type *> Tys,
- TTI::TargetCostKind CostKind) {
+ TTI::TargetCostKind CostKind) const {
return 10;
}
- unsigned getNumberOfParts(Type *Tp) {
+ unsigned getNumberOfParts(Type *Tp) const {
std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Tp);
if (!LT.first.isValid())
return 0;
@@ -2907,7 +2912,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
/// The cost model should take into account that the actual length of the
/// vector is reduced on each iteration.
InstructionCost getTreeReductionCost(unsigned Opcode, VectorType *Ty,
- TTI::TargetCostKind CostKind) {
+ TTI::TargetCostKind CostKind) const {
// Targets must implement a default value for the scalable case, since
// we don't know how many lanes the vector has.
if (isa<ScalableVectorType>(Ty))
@@ -2983,7 +2988,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
/// fixed-width vectors here because for scalable vectors we do not know the
/// runtime number of operations.
InstructionCost getOrderedReductionCost(unsigned Opcode, VectorType *Ty,
- TTI::TargetCostKind CostKind) {
+ TTI::TargetCostKind CostKind) const {
// Targets must implement a default value for the scalable case, since
// we don't know how many lanes the vector has.
if (isa<ScalableVectorType>(Ty))
@@ -2999,9 +3004,10 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
return ExtractCost + ArithCost;
}
- InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty,
- std::optional<FastMathFlags> FMF,
- TTI::TargetCostKind CostKind) {
+ InstructionCost
+ getArithmeticReductionCost(unsigned Opcode, VectorType *Ty,
+ std::optional<FastMathFlags> FMF,
+ TTI::TargetCostKind CostKind) const {
assert(Ty && "Unknown reduction vector type");
if (TTI::requiresOrderedReduction(FMF))
return getOrderedReductionCost(Opcode, Ty, CostKind);
@@ -3012,7 +3018,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
/// \param CondTy Conditional type for the Select instruction.
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty,
FastMathFlags FMF,
- TTI::TargetCostKind CostKind) {
+ TTI::TargetCostKind CostKind) const {
// Targets must implement a default value for the scalable case, since
// we don't know how many lanes the vector has.
if (isa<ScalableVectorType>(Ty))
@@ -3106,7 +3112,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
return RedCost + MulCost + 2 * ExtCost;
}
- InstructionCost getVectorSplitCost() { return 1; }
+ InstructionCost getVectorSplitCost() const { return 1; }
/// @}
};
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 372b70a4b2d64..51fa5237fcc50 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -371,7 +371,7 @@ bool AArch64TTIImpl::shouldMaximizeVectorBandwidth(
/// Calculate the cost of materializing a 64-bit value. This helper
/// method might only calculate a fraction of a larger immediate. Therefore it
/// is valid to return a cost of ZERO.
-InstructionCost AArch64TTIImpl::getIntImmCost(int64_t Val) {
+InstructionCost AArch64TTIImpl::getIntImmCost(int64_t Val) const {
// Check if the immediate can be encoded within an instruction.
if (Val == 0 || AArch64_AM::isLogicalImmediate(Val, 64))
return 0;
@@ -386,8 +386,9 @@ InstructionCost AArch64TTIImpl::getIntImmCost(int64_t Val) {
}
/// Calculate the cost of materializing the given constant.
-InstructionCost AArch64TTIImpl::getIntImmCost(const APInt &Imm, Type *Ty,
- TTI::TargetCostKind CostKind) {
+InstructionCost
+AArch64TTIImpl::getIntImmCost(const APInt &Imm, Type *Ty,
+ ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/136575
More information about the llvm-commits
mailing list