LLVM 22.0.0git
WebAssemblyTargetTransformInfo.cpp
Go to the documentation of this file.
1//===-- WebAssemblyTargetTransformInfo.cpp - WebAssembly-specific TTI -----===//
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///
9/// \file
10/// This file defines the WebAssembly-specific TargetTransformInfo
11/// implementation.
12///
13//===----------------------------------------------------------------------===//
14
16
18using namespace llvm;
19
20#define DEBUG_TYPE "wasmtti"
21
23WebAssemblyTTIImpl::getPopcntSupport(unsigned TyWidth) const {
24 assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
26}
27
28unsigned WebAssemblyTTIImpl::getNumberOfRegisters(unsigned ClassID) const {
29 unsigned Result = BaseT::getNumberOfRegisters(ClassID);
30
31 // For SIMD, use at least 16 registers, as a rough guess.
32 bool Vector = (ClassID == 1);
33 if (Vector)
34 Result = std::max(Result, 16u);
35
36 return Result;
37}
38
41 switch (K) {
43 return TypeSize::getFixed(64);
45 return TypeSize::getFixed(getST()->hasSIMD128() ? 128 : 64);
47 return TypeSize::getScalable(0);
48 }
49
50 llvm_unreachable("Unsupported register kind");
51}
52
54 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
56 ArrayRef<const Value *> Args, const Instruction *CxtI) const {
57
60 Opcode, Ty, CostKind, Op1Info, Op2Info);
61
62 if (auto *VTy = dyn_cast<VectorType>(Ty)) {
63 switch (Opcode) {
64 case Instruction::LShr:
65 case Instruction::AShr:
66 case Instruction::Shl:
67 // SIMD128's shifts currently only accept a scalar shift count. For each
68 // element, we'll need to extract, op, insert. The following is a rough
69 // approximation.
70 if (!Op2Info.isUniform())
71 Cost =
72 cast<FixedVectorType>(VTy)->getNumElements() *
74 getArithmeticInstrCost(Opcode, VTy->getElementType(), CostKind) +
76 break;
77 }
78 }
79 return Cost;
80}
81
83 unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH,
85 int ISD = TLI->InstructionOpcodeToISD(Opcode);
86 auto SrcTy = TLI->getValueType(DL, Src);
87 auto DstTy = TLI->getValueType(DL, Dst);
88
89 if (!SrcTy.isSimple() || !DstTy.isSimple()) {
90 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
91 }
92
93 if (!ST->hasSIMD128()) {
94 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
95 }
96
97 auto DstVT = DstTy.getSimpleVT();
98 auto SrcVT = SrcTy.getSimpleVT();
99
100 if (I && I->hasOneUser()) {
101 auto *SingleUser = cast<Instruction>(*I->user_begin());
102 int UserISD = TLI->InstructionOpcodeToISD(SingleUser->getOpcode());
103
104 // extmul_low support
105 if (UserISD == ISD::MUL &&
107 // Free low extensions.
108 if ((SrcVT == MVT::v8i8 && DstVT == MVT::v8i16) ||
109 (SrcVT == MVT::v4i16 && DstVT == MVT::v4i32) ||
110 (SrcVT == MVT::v2i32 && DstVT == MVT::v2i64)) {
111 return 0;
112 }
113 // Will require an additional extlow operation for the intermediate
114 // i16/i32 value.
115 if ((SrcVT == MVT::v4i8 && DstVT == MVT::v4i32) ||
116 (SrcVT == MVT::v2i16 && DstVT == MVT::v2i64)) {
117 return 1;
118 }
119 }
120 }
121
122 // extend_low
123 static constexpr TypeConversionCostTblEntry ConversionTbl[] = {
124 {ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i32, 1},
125 {ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i32, 1},
126 {ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i16, 1},
127 {ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i16, 1},
128 {ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i8, 1},
129 {ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i8, 1},
130 {ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i16, 2},
131 {ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i16, 2},
132 {ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i8, 2},
133 {ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i8, 2},
134 };
135
136 if (const auto *Entry =
137 ConvertCostTableLookup(ConversionTbl, ISD, DstVT, SrcVT)) {
138 return Entry->Cost;
139 }
140
141 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
142}
143
145WebAssemblyTTIImpl::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
147
148 Options.AllowOverlappingLoads = true;
149
150 if (ST->hasSIMD128())
151 Options.LoadSizes.push_back(16);
152
153 Options.LoadSizes.append({8, 4, 2, 1});
154 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
155 Options.NumLoadsPerBlock = Options.MaxNumLoads;
156
157 return Options;
158}
159
161 unsigned Opcode, Type *Ty, Align Alignment, unsigned AddressSpace,
163 const Instruction *I) const {
164 if (!ST->hasSIMD128() || !isa<FixedVectorType>(Ty)) {
165 return BaseT::getMemoryOpCost(Opcode, Ty, Alignment, AddressSpace,
166 CostKind);
167 }
168
169 EVT VT = TLI->getValueType(DL, Ty, true);
170 // Type legalization can't handle structs
171 if (VT == MVT::Other)
172 return BaseT::getMemoryOpCost(Opcode, Ty, Alignment, AddressSpace,
173 CostKind);
174
175 auto LT = getTypeLegalizationCost(Ty);
176 if (!LT.first.isValid())
178
179 int ISD = TLI->InstructionOpcodeToISD(Opcode);
180 unsigned width = VT.getSizeInBits();
181 if (ISD == ISD::LOAD) {
182 // 128-bit loads are a single instruction. 32-bit and 64-bit vector loads
183 // can be lowered to load32_zero and load64_zero respectively. Assume SIMD
184 // loads are twice as expensive as scalar.
185 switch (width) {
186 default:
187 break;
188 case 32:
189 case 64:
190 case 128:
191 return 2;
192 }
193 } else if (ISD == ISD::STORE) {
194 // For stores, we can use store lane operations.
195 switch (width) {
196 default:
197 break;
198 case 8:
199 case 16:
200 case 32:
201 case 64:
202 case 128:
203 return 2;
204 }
205 }
206
207 return BaseT::getMemoryOpCost(Opcode, Ty, Alignment, AddressSpace, CostKind);
208}
209
211 unsigned Opcode, Type *Ty, unsigned Factor, ArrayRef<unsigned> Indices,
212 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
213 bool UseMaskForCond, bool UseMaskForGaps) const {
214 assert(Factor >= 2 && "Invalid interleave factor");
215
216 auto *VecTy = cast<VectorType>(Ty);
217 if (!ST->hasSIMD128() || !isa<FixedVectorType>(VecTy)) {
219 }
220
221 if (UseMaskForCond || UseMaskForGaps)
222 return BaseT::getInterleavedMemoryOpCost(Opcode, Ty, Factor, Indices,
223 Alignment, AddressSpace, CostKind,
224 UseMaskForCond, UseMaskForGaps);
225
226 constexpr unsigned MaxInterleaveFactor = 4;
227 if (Factor <= MaxInterleaveFactor) {
228 unsigned MinElts = VecTy->getElementCount().getKnownMinValue();
229 // Ensure the number of vector elements is greater than 1.
230 if (MinElts < 2 || MinElts % Factor != 0)
232
233 unsigned ElSize = DL.getTypeSizeInBits(VecTy->getElementType());
234 // Ensure the element type is legal.
235 if (ElSize != 8 && ElSize != 16 && ElSize != 32 && ElSize != 64)
237
238 auto *SubVecTy =
239 VectorType::get(VecTy->getElementType(),
240 VecTy->getElementCount().divideCoefficientBy(Factor));
241 InstructionCost MemCost =
242 getMemoryOpCost(Opcode, SubVecTy, Alignment, AddressSpace, CostKind);
243
244 unsigned VecSize = DL.getTypeSizeInBits(SubVecTy);
245 unsigned MaxVecSize = 128;
246 unsigned NumAccesses =
247 std::max<unsigned>(1, (MinElts * ElSize + MaxVecSize - 1) / VecSize);
248
249 // A stride of two is commonly supported via dedicated instructions, so it
250 // should be relatively cheap for all element sizes. A stride of four is
251 // more expensive as it will likely require more shuffles. Using two
252 // simd128 inputs is considered more expensive and we mainly account for
253 // shuffling two inputs (32 bytes), but we do model 4 x v4i32 to enable
254 // arithmetic kernels.
255 static const CostTblEntry ShuffleCostTbl[] = {
256 // One reg.
257 {2, MVT::v2i8, 1}, // interleave 2 x 2i8 into 4i8
258 {2, MVT::v4i8, 1}, // interleave 2 x 4i8 into 8i8
259 {2, MVT::v8i8, 1}, // interleave 2 x 8i8 into 16i8
260 {2, MVT::v2i16, 1}, // interleave 2 x 2i16 into 4i16
261 {2, MVT::v4i16, 1}, // interleave 2 x 4i16 into 8i16
262 {2, MVT::v2i32, 1}, // interleave 2 x 2i32 into 4i32
263
264 // Two regs.
265 {2, MVT::v16i8, 2}, // interleave 2 x 16i8 into 32i8
266 {2, MVT::v8i16, 2}, // interleave 2 x 8i16 into 16i16
267 {2, MVT::v4i32, 2}, // interleave 2 x 4i32 into 8i32
268
269 // One reg.
270 {4, MVT::v2i8, 4}, // interleave 4 x 2i8 into 8i8
271 {4, MVT::v4i8, 4}, // interleave 4 x 4i8 into 16i8
272 {4, MVT::v2i16, 4}, // interleave 4 x 2i16 into 8i16
273
274 // Two regs.
275 {4, MVT::v8i8, 16}, // interleave 4 x 8i8 into 32i8
276 {4, MVT::v4i16, 8}, // interleave 4 x 4i16 into 16i16
277 {4, MVT::v2i32, 4}, // interleave 4 x 2i32 into 8i32
278
279 // Four regs.
280 {4, MVT::v4i32, 16}, // interleave 4 x 4i32 into 16i32
281 };
282
283 EVT ETy = TLI->getValueType(DL, SubVecTy);
284 if (const auto *Entry =
285 CostTableLookup(ShuffleCostTbl, Factor, ETy.getSimpleVT()))
286 return Entry->Cost + (NumAccesses * MemCost);
287 }
288
289 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
290 Alignment, AddressSpace, CostKind,
291 UseMaskForCond, UseMaskForGaps);
292}
293
295 unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
296 const Value *Op0, const Value *Op1) const {
298 Opcode, Val, CostKind, Index, Op0, Op1);
299
300 // SIMD128's insert/extract currently only take constant indices.
301 if (Index == -1u)
303
304 return Cost;
305}
306
308 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
310 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
313 if (!VF.isFixed() || !ST->hasSIMD128())
314 return Invalid;
315
317 return Invalid;
318
319 if (Opcode != Instruction::Add)
320 return Invalid;
321
322 EVT AccumEVT = EVT::getEVT(AccumType);
323 // TODO: Add i64 accumulator.
324 if (AccumEVT != MVT::i32)
325 return Invalid;
326
327 // Possible options:
328 // - i16x8.extadd_pairwise_i8x16_sx
329 // - i32x4.extadd_pairwise_i16x8_sx
330 // - i32x4.dot_i16x8_s
331 // Only try to support dot, for now.
332
333 EVT InputEVT = EVT::getEVT(InputTypeA);
334 if (!((InputEVT == MVT::i16 && VF.getFixedValue() == 8) ||
335 (InputEVT == MVT::i8 && VF.getFixedValue() == 16))) {
336 return Invalid;
337 }
338
339 if (OpAExtend == TTI::PR_None)
340 return Invalid;
341
343 if (!BinOp)
344 return Cost;
345
346 if (OpAExtend != OpBExtend)
347 return Invalid;
348
349 if (*BinOp != Instruction::Mul)
350 return Invalid;
351
352 if (InputTypeA != InputTypeB)
353 return Invalid;
354
355 // Signed inputs can lower to dot
356 if (InputEVT == MVT::i16 && VF.getFixedValue() == 8)
357 return OpAExtend == TTI::PR_SignExtend ? Cost : Cost * 2;
358
359 // Double the size of the lowered sequence.
360 if (InputEVT == MVT::i8 && VF.getFixedValue() == 16)
361 return OpAExtend == TTI::PR_SignExtend ? Cost * 2 : Cost * 4;
362
363 return Invalid;
364}
365
367 const IntrinsicInst *II) const {
368
369 switch (II->getIntrinsicID()) {
370 default:
371 break;
372 case Intrinsic::vector_reduce_fadd:
374 }
376}
377
380 OptimizationRemarkEmitter *ORE) const {
381 // Scan the loop: don't unroll loops with calls. This is a standard approach
382 // for most (all?) targets.
383 for (BasicBlock *BB : L->blocks())
384 for (Instruction &I : *BB)
387 if (isLoweredToCall(F))
388 return;
389
390 // The chosen threshold is within the range of 'LoopMicroOpBufferSize' of
391 // the various microarchitectures that use the BasicTTI implementation and
392 // has been selected through heuristics across multiple cores and runtimes.
393 UP.Partial = UP.Runtime = UP.UpperBound = true;
394 UP.PartialThreshold = 30;
395
396 // Avoid unrolling when optimizing for size.
397 UP.OptSizeThreshold = 0;
399
400 // Set number of instructions optimized when "back edge"
401 // becomes "fall through" to default value of 2.
402 UP.BEInsns = 2;
403}
404
406 return getST()->hasTailCall();
407}
408
411 using namespace llvm::PatternMatch;
412
413 if (!I->getType()->isVectorTy() || !I->isShift())
414 return false;
415
416 Value *V = I->getOperand(1);
417 // We dont need to sink constant splat.
418 if (isa<Constant>(V))
419 return false;
420
422 m_Value(), m_ZeroMask()))) {
423 // Sink insert
424 Ops.push_back(&cast<Instruction>(V)->getOperandUse(0));
425 // Sink shuffle
426 Ops.push_back(&I->getOperandUse(1));
427 return true;
428 }
429
430 return false;
431}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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")))
Cost tables and simple lookup functions.
static const int MaxVecSize
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static LVOptions Options
Definition LVOptions.cpp:25
static const unsigned MaxInterleaveFactor
Maximum vectorization interleave count.
#define F(x, y, z)
Definition MD5.cpp:55
#define I(x, y, z)
Definition MD5.cpp:58
static const Function * getCalledFunction(const Value *V)
uint64_t IntrinsicInst * II
This file a TargetTransformInfoImplBase conforming object specific to the WebAssembly target machine.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
LLVM Basic Block Representation.
Definition BasicBlock.h:62
InstructionCost getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1) const override
InstructionCost getArithmeticInstrCost(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) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
std::pair< InstructionCost, MVT > getTypeLegalizationCost(Type *Ty) const
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
static InstructionCost getInvalid(CostType Val=0)
A wrapper class for inspecting calls to intrinsic functions.
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
The optimization diagnostic interface.
The main scalar evolution driver.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
virtual unsigned getNumberOfRegisters(unsigned ClassID) const
virtual bool isLoweredToCall(const Function *F) const
TargetCostKind
The kind of cost model.
@ TCK_RecipThroughput
Reciprocal throughput.
PopcntSupportKind
Flags indicating the kind of support for population count.
@ TCC_Expensive
The cost of a 'div' instruction on x86.
@ TCC_Basic
The cost of a typical 'add' instruction.
CastContextHint
Represents a hint about the context in which a cast is used.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:343
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
Definition TypeSize.h:346
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
LLVM Value Representation.
Definition Value.h:75
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
InstructionCost getInterleavedMemoryOpCost(unsigned Opcode, Type *Ty, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond, bool UseMaskForGaps) const override
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth) const override
TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) 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 isProfitableToSinkOperands(Instruction *I, SmallVectorImpl< Use * > &Ops) 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) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1) const override
TTI::ReductionShuffle getPreferredExpandedReductionShuffle(const IntrinsicInst *II) const override
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP, OptimizationRemarkEmitter *ORE) const override
TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
unsigned getNumberOfRegisters(unsigned ClassID) const override
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:172
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ISD namespace - This namespace contains an enum which represents all of the SelectionDAG node types a...
Definition ISDOpcodes.h:24
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:826
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:832
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
bool match(Val *V, const Pattern &P)
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
This is an optimization pass for GlobalISel generic memory operations.
const CostTblEntryT< CostType > * CostTableLookup(ArrayRef< CostTblEntryT< CostType > > Tbl, int ISD, MVT Ty)
Find in cost table.
Definition CostTable.h:35
InstructionCost Cost
TypeConversionCostTblEntryT< unsigned > TypeConversionCostTblEntry
Definition CostTable.h:61
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:288
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:548
CostTblEntryT< unsigned > CostTblEntry
Definition CostTable.h:30
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
const TypeConversionCostTblEntryT< CostType > * ConvertCostTableLookup(ArrayRef< TypeConversionCostTblEntryT< CostType > > Tbl, int ISD, MVT Dst, MVT Src)
Find in type conversion cost table.
Definition CostTable.h:66
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:373
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:316
Returns options for expansion of memcmp. IsZeroCmp is.
Parameters that control the generic loop unrolling transformation.
bool UpperBound
Allow using trip count upper bound to unroll loops.
unsigned PartialOptSizeThreshold
The cost threshold for the unrolled loop when optimizing for size, like OptSizeThreshold,...
unsigned PartialThreshold
The cost threshold for the unrolled loop, like Threshold, but used for partial/runtime unrolling (set...
bool Runtime
Allow runtime unrolling (unrolling of loops to expand the size of the loop body even when the number ...
bool Partial
Allow partial unrolling (unrolling of loops to expand the size of the loop body, not only to eliminat...
unsigned OptSizeThreshold
The cost threshold for the unrolled loop when optimizing for size (set to UINT_MAX to disable).