LLVM 24.0.0git
NVPTXTargetTransformInfo.h
Go to the documentation of this file.
1//===-- NVPTXTargetTransformInfo.h - NVPTX specific TTI ---------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file a TargetTransformInfoImplBase conforming object specific to the
10/// NVPTX target machine. It uses the target's detailed information to
11/// provide more precise answers to certain TTI queries, while letting the
12/// target independent and default TTI implementations handle the rest.
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_LIB_TARGET_NVPTX_NVPTXTARGETTRANSFORMINFO_H
17#define LLVM_LIB_TARGET_NVPTX_NVPTXTARGETTRANSFORMINFO_H
18
20#include "NVPTXTargetMachine.h"
21#include "NVPTXUtilities.h"
25#include <optional>
26
27namespace llvm {
28
29class NVPTXTTIImpl final : public BasicTTIImplBase<NVPTXTTIImpl> {
31 typedef TargetTransformInfo TTI;
32 friend BaseT;
33
34 const NVPTXSubtarget *ST;
35 const NVPTXTargetLowering *TLI;
36
37 const NVPTXSubtarget *getST() const { return ST; };
38 const NVPTXTargetLowering *getTLI() const { return TLI; };
39
40 /// \returns true if the result of the value could potentially be
41 /// different across threads in a warp.
42 bool isSourceOfDivergence(const Value *V) const;
43
44public:
45 explicit NVPTXTTIImpl(const NVPTXTargetMachine *TM, const Function &F)
46 : BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl()),
47 TLI(ST->getTargetLowering()) {}
48
49 bool hasBranchDivergence(const Function *F = nullptr) const override {
50 return true;
51 }
52
53 unsigned getFlatAddressSpace() const override {
54 return AddressSpace::ADDRESS_SPACE_GENERIC;
55 }
56
57 unsigned getAddressSpaceJoin(unsigned AS1, unsigned AS2) const override {
58 if ((AS1 == AddressSpace::ADDRESS_SPACE_SHARED &&
59 AS2 == AddressSpace::ADDRESS_SPACE_SHARED_CLUSTER) ||
60 (AS2 == AddressSpace::ADDRESS_SPACE_SHARED &&
61 AS1 == AddressSpace::ADDRESS_SPACE_SHARED_CLUSTER))
62 return AddressSpace::ADDRESS_SPACE_SHARED_CLUSTER;
63 return AddressSpace::ADDRESS_SPACE_GENERIC;
64 }
65
66 bool
68 return AS != AddressSpace::ADDRESS_SPACE_SHARED &&
69 AS != AddressSpace::ADDRESS_SPACE_LOCAL &&
70 AS != AddressSpace::ADDRESS_SPACE_ENTRY_PARAM;
71 }
72
73 std::optional<Instruction *>
75
76 // Loads and stores can be vectorized if the alignment is at least as big as
77 // the load/store we want to vectorize.
78 bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes, Align Alignment,
79 unsigned AddrSpace) const override {
80 return Alignment >= ChainSizeInBytes;
81 }
82 bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes, Align Alignment,
83 unsigned AddrSpace) const override {
84 return isLegalToVectorizeLoadChain(ChainSizeInBytes, Alignment, AddrSpace);
85 }
86
87 // NVPTX has infinite registers of all kinds, but the actual machine doesn't.
88 // We conservatively return 1 here which is just enough to enable the
89 // vectorizers but disables heuristics based on the number of registers.
90 // FIXME: Return a more reasonable number, while keeping an eye on
91 // LoopVectorizer's unrolling heuristics.
92 unsigned getNumberOfRegisters(unsigned ClassID) const override { return 1; }
93
94 // Only <2 x half> should be vectorized, so always return 32 for the vector
95 // register size.
100 unsigned getMinVectorRegisterBitWidth() const override { return 32; }
101
102 bool shouldExpandReduction(const IntrinsicInst *II) const override {
103 // Turn off ExpandReductions pass for NVPTX, which doesn't have advanced
104 // swizzling operations. Our backend/Selection DAG can expand these
105 // reductions with less movs.
106 return false;
107 }
108
109 // We don't want to prevent inlining because of target-cpu and -features
110 // attributes that were added to newer versions of LLVM/Clang: There are
111 // no incompatible functions in PTX, ptxas will throw errors in such cases.
112 bool areInlineCompatible(const Function *Caller,
113 const Function *Callee) const override {
114 return true;
115 }
116
117 // Increase the inlining cost threshold by a factor of 11, reflecting that
118 // calls are particularly expensive in NVPTX.
119 unsigned getInliningThresholdMultiplier() const override { return 11; }
120
123 TTI::TargetCostKind CostKind) const override;
124
126 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
130 const Instruction *CtxI = nullptr) const override;
131
133 getScalarizationOverhead(VectorType *InTy, const APInt &DemandedElts,
134 bool Insert, bool Extract,
136 bool ForPoisonSrc = true, ArrayRef<Value *> VL = {},
138 TTI::VectorInstrContext::None) const override {
139 if (!InTy->getElementCount().isFixed())
141
142 auto VT = getTLI()->getValueType(DL, InTy);
143 auto NumElements = InTy->getElementCount().getFixedValue();
145 if (Insert && !VL.empty()) {
146 bool AllConstant = all_of(seq(NumElements), [&](int Idx) {
147 return !DemandedElts[Idx] || isa<Constant>(VL[Idx]);
148 });
149 if (AllConstant) {
150 Cost += TTI::TCC_Free;
151 Insert = false;
152 }
153 }
154 if (Insert && VT == MVT::v4i8) {
155 Cost += 3; // 3 x PRMT
156 for (auto Idx : seq(NumElements))
157 if (DemandedElts[Idx])
158 Cost += 1; // zext operand to i32
159 Insert = false;
160 } else if (Insert && NVPTX::isPackedVectorTy(VT) && VT.is32BitVector()) {
161 // Can be built in a single 32-bit mov (64-bit regs are emulated in SASS
162 // with 2x 32-bit regs)
163 Cost += 1;
164 Insert = false;
165 }
166 return Cost + BaseT::getScalarizationOverhead(InTy, DemandedElts, Insert,
167 Extract, CostKind,
168 ForPoisonSrc, VL);
169 }
170
171 void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
173 OptimizationRemarkEmitter *ORE) const override;
174
175 void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
176 TTI::PeelingPreferences &PP) const override;
177
178 bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const override {
180 return false;
181
182 switch (AddrSpace) {
183 default:
184 return false;
189 return true;
191 return ST->hasLocalVolatile();
192 }
193 }
194
196 unsigned DstAS) const override {
197 if (SrcAS != llvm::ADDRESS_SPACE_GENERIC)
198 return BaseT::getAddrSpaceCastPreservedPtrMask(SrcAS, DstAS);
199 if (DstAS != llvm::ADDRESS_SPACE_GLOBAL &&
201 return BaseT::getAddrSpaceCastPreservedPtrMask(SrcAS, DstAS);
202
203 // Address change within 4K size does not change the original address space
204 // and is safe to perform address cast form SrcAS to DstAS.
205 APInt PtrMask(DL.getPointerSizeInBits(llvm::ADDRESS_SPACE_GENERIC), 0xfff);
206 return PtrMask;
207 }
208
210 Intrinsic::ID IID) const override;
211
212 bool isLegalMaskedStore(Type *DataType, Align Alignment, unsigned AddrSpace,
213 TTI::MaskKind MaskKind) const override;
214
215 bool isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddrSpace,
216 TTI::MaskKind MaskKind) const override;
217
218 unsigned getLoadStoreVecRegBitWidth(unsigned AddrSpace) const override;
219
221 Value *NewV) const override;
222 unsigned getAssumedAddrSpace(const Value *V) const override;
223
225 const Function &F,
226 SmallVectorImpl<std::pair<StringRef, int64_t>> &LB) const override;
227
228 bool shouldBuildRelLookupTables() const override {
229 // Self-referential globals are not supported.
230 return false;
231 }
232
233 bool shouldBuildLookupTablesForConstant(Constant *C) const override;
234
236 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
238 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
240 std::optional<FastMathFlags> FMF) const override {
242 }
243
244 ValueUniformity getValueUniformity(const Value *V) const override;
245};
246
247} // end namespace llvm
248
249#endif
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file provides a helper that implements much of the TTI interface in terms of the target-independ...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
uint64_t IntrinsicInst * II
SI Fold Operands
This file describes how to lower LLVM code to machine code.
This pass exposes codegen information to IR-level passes.
Class for arbitrary precision integers.
Definition APInt.h:78
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
InstructionCost getScalarizationOverhead(VectorType *InTy, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
BasicTTIImplBase(const TargetMachine *TM, const DataLayout &DL)
This is an important base class in LLVM.
Definition Constant.h:43
The core instruction combiner logic.
static InstructionCost getInvalid(CostType Val=0)
A wrapper class for inspecting calls to intrinsic functions.
unsigned getNumberOfRegisters(unsigned ClassID) const override
unsigned getFlatAddressSpace() const override
TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override
bool isLegalMaskedStore(Type *DataType, Align Alignment, unsigned AddrSpace, TTI::MaskKind MaskKind) const override
Value * rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV, Value *NewV) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr) const override
bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const override
InstructionCost getInstructionCost(const User *U, ArrayRef< const Value * > Operands, TTI::TargetCostKind CostKind) const override
bool shouldBuildLookupTablesForConstant(Constant *C) const override
unsigned getLoadStoreVecRegBitWidth(unsigned AddrSpace) const override
InstructionCost getScalarizationOverhead(VectorType *InTy, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
Estimate the overhead of scalarizing an instruction.
bool areInlineCompatible(const Function *Caller, const Function *Callee) const override
std::optional< Instruction * > instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const override
bool shouldBuildRelLookupTables() const override
unsigned getInliningThresholdMultiplier() const override
bool canHaveNonUndefGlobalInitializerInAddressSpace(unsigned AS) const override
bool shouldExpandReduction(const IntrinsicInst *II) const override
bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const override
ValueUniformity getValueUniformity(const Value *V) const override
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP, OptimizationRemarkEmitter *ORE) const override
NVPTXTTIImpl(const NVPTXTargetMachine *TM, const Function &F)
unsigned getAddressSpaceJoin(unsigned AS1, unsigned AS2) const override
void getPeelingPreferences(Loop *L, ScalarEvolution &SE, TTI::PeelingPreferences &PP) const override
APInt getAddrSpaceCastPreservedPtrMask(unsigned SrcAS, unsigned DstAS) const override
InstructionCost getPartialReductionCost(unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType, ElementCount VF, TTI::PartialReductionExtendKind OpAExtend, TTI::PartialReductionExtendKind OpBExtend, std::optional< unsigned > BinOp, TTI::TargetCostKind CostKind, std::optional< FastMathFlags > FMF) const override
bool collectFlatAddressOperands(SmallVectorImpl< int > &OpIndexes, Intrinsic::ID IID) const override
bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const override
unsigned getAssumedAddrSpace(const Value *V) const override
void collectKernelLaunchBounds(const Function &F, SmallVectorImpl< std::pair< StringRef, int64_t > > &LB) const override
bool isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddrSpace, TTI::MaskKind MaskKind) const override
unsigned getMinVectorRegisterBitWidth() const override
bool hasBranchDivergence(const Function *F=nullptr) const override
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual const DataLayout & getDataLayout() const
virtual APInt getAddrSpaceCastPreservedPtrMask(unsigned SrcAS, unsigned DstAS) const
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
MaskKind
Some targets only support masked load/store with a constant mask.
TargetCostKind
The kind of cost model.
llvm::VectorInstrContext VectorInstrContext
@ TCC_Free
Expected to fold away in lowering.
@ None
The cast is not used with a load/store of any kind.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:339
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM Value Representation.
Definition Value.h:75
Base class of all SIMD vector types.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isFixed() const
Returns true if the quantity is not scaled by vscale.
Definition TypeSize.h:171
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
bool isPackedVectorTy(EVT VT)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
InstructionCost Cost
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
ValueUniformity
Enum describing how values behave with respect to uniformity and divergence, to answer the question: ...
Definition Uniformity.h:18
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Parameters that control the generic loop unrolling transformation.