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 *CxtI = 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 && NVPTX::isPackedVectorTy(VT) && VT.is32BitVector()) {
155 // Can be built in a single 32-bit mov (64-bit regs are emulated in SASS
156 // with 2x 32-bit regs)
157 Cost += 1;
158 Insert = false;
159 }
160 if (Insert && VT == MVT::v4i8) {
161 InstructionCost Cost = 3; // 3 x PRMT
162 for (auto Idx : seq(NumElements))
163 if (DemandedElts[Idx])
164 Cost += 1; // zext operand to i32
165 Insert = false;
166 }
167 return Cost + BaseT::getScalarizationOverhead(InTy, DemandedElts, Insert,
168 Extract, CostKind,
169 ForPoisonSrc, VL);
170 }
171
172 void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
174 OptimizationRemarkEmitter *ORE) const override;
175
176 void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
177 TTI::PeelingPreferences &PP) const override;
178
179 bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const override {
180 // Volatile loads/stores are only supported for shared and global address
181 // spaces, or for generic AS that maps to them.
182 if (!(AddrSpace == llvm::ADDRESS_SPACE_GENERIC ||
183 AddrSpace == llvm::ADDRESS_SPACE_GLOBAL ||
184 AddrSpace == llvm::ADDRESS_SPACE_SHARED))
185 return false;
186
187 switch(I->getOpcode()){
188 default:
189 return false;
190 case Instruction::Load:
191 case Instruction::Store:
192 return true;
193 }
194 }
195
197 unsigned DstAS) const override {
198 if (SrcAS != llvm::ADDRESS_SPACE_GENERIC)
199 return BaseT::getAddrSpaceCastPreservedPtrMask(SrcAS, DstAS);
200 if (DstAS != llvm::ADDRESS_SPACE_GLOBAL &&
202 return BaseT::getAddrSpaceCastPreservedPtrMask(SrcAS, DstAS);
203
204 // Address change within 4K size does not change the original address space
205 // and is safe to perform address cast form SrcAS to DstAS.
206 APInt PtrMask(DL.getPointerSizeInBits(llvm::ADDRESS_SPACE_GENERIC), 0xfff);
207 return PtrMask;
208 }
209
211 Intrinsic::ID IID) const override;
212
213 bool isLegalMaskedStore(Type *DataType, Align Alignment, unsigned AddrSpace,
214 TTI::MaskKind MaskKind) const override;
215
216 bool isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddrSpace,
217 TTI::MaskKind MaskKind) const override;
218
219 unsigned getLoadStoreVecRegBitWidth(unsigned AddrSpace) const override;
220
222 Value *NewV) const override;
223 unsigned getAssumedAddrSpace(const Value *V) const override;
224
226 const Function &F,
227 SmallVectorImpl<std::pair<StringRef, int64_t>> &LB) const override;
228
229 bool shouldBuildRelLookupTables() const override {
230 // Self-referential globals are not supported.
231 return false;
232 }
233
235 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
237 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
239 std::optional<FastMathFlags> FMF) const override {
241 }
242
243 ValueUniformity getValueUniformity(const Value *V) const override;
244};
245
246} // end namespace llvm
247
248#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 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)
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
bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const override
InstructionCost getInstructionCost(const User *U, ArrayRef< const Value * > Operands, TTI::TargetCostKind CostKind) 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
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 *CxtI=nullptr) 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.