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 &&
106 (ISD == ISD::ZERO_EXTEND || ISD == ISD::SIGN_EXTEND)) {
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
320
321 // Possible options:
322 // - i16x8.extadd_pairwise_i8x16_sx
323 // - i32x4.extadd_pairwise_i16x8_sx
324 // - i32x4.dot_i16x8_s
325 // Only try to support dot, for now.
326
327 if (Opcode != Instruction::Add)
328 return Invalid;
329
330 if (!BinOp || *BinOp != Instruction::Mul)
331 return Invalid;
332
333 if (InputTypeA != InputTypeB)
334 return Invalid;
335
336 if (OpAExtend != OpBExtend)
337 return Invalid;
338
339 EVT InputEVT = EVT::getEVT(InputTypeA);
340 EVT AccumEVT = EVT::getEVT(AccumType);
341
342 // TODO: Add i64 accumulator.
343 if (AccumEVT != MVT::i32)
344 return Invalid;
345
346 // Signed inputs can lower to dot
347 if (InputEVT == MVT::i16 && VF.getFixedValue() == 8)
348 return OpAExtend == TTI::PR_SignExtend ? Cost : Cost * 2;
349
350 // Double the size of the lowered sequence.
351 if (InputEVT == MVT::i8 && VF.getFixedValue() == 16)
352 return OpAExtend == TTI::PR_SignExtend ? Cost * 2 : Cost * 4;
353
354 return Invalid;
355}
356
358 const IntrinsicInst *II) const {
359
360 switch (II->getIntrinsicID()) {
361 default:
362 break;
363 case Intrinsic::vector_reduce_fadd:
365 }
367}
368
371 OptimizationRemarkEmitter *ORE) const {
372 // Scan the loop: don't unroll loops with calls. This is a standard approach
373 // for most (all?) targets.
374 for (BasicBlock *BB : L->blocks())
375 for (Instruction &I : *BB)
376 if (isa<CallInst>(I) || isa<InvokeInst>(I))
377 if (const Function *F = cast<CallBase>(I).getCalledFunction())
378 if (isLoweredToCall(F))
379 return;
380
381 // The chosen threshold is within the range of 'LoopMicroOpBufferSize' of
382 // the various microarchitectures that use the BasicTTI implementation and
383 // has been selected through heuristics across multiple cores and runtimes.
384 UP.Partial = UP.Runtime = UP.UpperBound = true;
385 UP.PartialThreshold = 30;
386
387 // Avoid unrolling when optimizing for size.
388 UP.OptSizeThreshold = 0;
390
391 // Set number of instructions optimized when "back edge"
392 // becomes "fall through" to default value of 2.
393 UP.BEInsns = 2;
394}
395
397 return getST()->hasTailCall();
398}
399
401 Instruction *I, SmallVectorImpl<Use *> &Ops) const {
402 using namespace llvm::PatternMatch;
403
404 if (!I->getType()->isVectorTy() || !I->isShift())
405 return false;
406
407 Value *V = I->getOperand(1);
408 // We dont need to sink constant splat.
409 if (isa<Constant>(V))
410 return false;
411
413 m_Value(), m_ZeroMask()))) {
414 // Sink insert
415 Ops.push_back(&cast<Instruction>(V)->getOperandUse(0));
416 // Sink shuffle
417 Ops.push_back(&I->getOperandUse(1));
418 return true;
419 }
420
421 return false;
422}
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
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
Estimate the cost of type-legalization and the legalized type.
Definition: BasicTTIImpl.h:997
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
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
Definition: DataLayout.h:674
static InstructionCost getInvalid(CostType Val=0)
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:49
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...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
int InstructionOpcodeToISD(unsigned Opcode) const
Get the ISD node that corresponds to the Instruction class opcode.
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
unsigned getMaxExpandSizeMemcmp(bool OptSize) const
Get maximum # of load operations permitted for memcmp.
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:346
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
Definition: TypeSize.h:349
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:203
constexpr bool isFixed() const
Returns true if the quantity is not scaled by vscale.
Definition: TypeSize.h:175
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:1141
@ 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)
Definition: PatternMatch.h:49
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.
Definition: PatternMatch.h:92
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.
Definition: AddressRanges.h:18
const CostTblEntryT< CostType > * CostTableLookup(ArrayRef< CostTblEntryT< CostType > > Tbl, int ISD, MVT Ty)
Find in cost table.
Definition: CostTable.h:35
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:288
InstructionCost Cost
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
Cost Table Entry.
Definition: CostTable.h:25
Extended Value Type.
Definition: ValueTypes.h:35
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:368
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
Definition: ValueTypes.cpp:299
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:311
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).
Type Conversion Cost Table.
Definition: CostTable.h:55