LLVM 24.0.0git
AMDGPUTargetTransformInfo.cpp
Go to the documentation of this file.
1//===- AMDGPUTargetTransformInfo.cpp - AMDGPU specific TTI pass -----------===//
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 implements a TargetTransformInfo analysis pass specific to the
11// AMDGPU target machine. It uses the target's detailed information to provide
12// more precise answers to certain TTI queries, while letting the target
13// independent and default TTI implementations handle the rest.
14//
15//===----------------------------------------------------------------------===//
16
18#include "AMDGPUSubtarget.h"
19#include "AMDGPUTargetMachine.h"
27#include "llvm/IR/Function.h"
28#include "llvm/IR/IRBuilder.h"
29#include "llvm/IR/IntrinsicsAMDGPU.h"
32#include <optional>
33
34using namespace llvm;
35
36#define DEBUG_TYPE "AMDGPUtti"
37
39 "amdgpu-unroll-threshold-private",
40 cl::desc("Unroll threshold for AMDGPU if private memory used in a loop"),
41 cl::init(2700), cl::Hidden);
42
44 "amdgpu-unroll-threshold-local",
45 cl::desc("Unroll threshold for AMDGPU if local memory used in a loop"),
46 cl::init(1000), cl::Hidden);
47
49 "amdgpu-unroll-threshold-if",
50 cl::desc("Unroll threshold increment for AMDGPU for each if statement inside loop"),
51 cl::init(200), cl::Hidden);
52
54 "amdgpu-unroll-runtime-local",
55 cl::desc("Allow runtime unroll for AMDGPU if local memory used in a loop"),
56 cl::init(true), cl::Hidden);
57
59 "amdgpu-unroll-max-block-to-analyze",
60 cl::desc("Inner loop block size threshold to analyze in unroll for AMDGPU"),
61 cl::init(32), cl::Hidden);
62
63static cl::opt<unsigned> ArgAllocaCost("amdgpu-inline-arg-alloca-cost",
64 cl::Hidden, cl::init(4000),
65 cl::desc("Cost of alloca argument"));
66
67// If the amount of scratch memory to eliminate exceeds our ability to allocate
68// it into registers we gain nothing by aggressively inlining functions for that
69// heuristic.
71 ArgAllocaCutoff("amdgpu-inline-arg-alloca-cutoff", cl::Hidden,
72 cl::init(256),
73 cl::desc("Maximum alloca size to use for inline cost"));
74
75// Inliner constraint to achieve reasonable compilation time.
77 "amdgpu-inline-max-bb", cl::Hidden, cl::init(1100),
78 cl::desc("Maximum number of BBs allowed in a function after inlining"
79 " (compile time constraint)"));
80
81// This default unroll factor is based on microbenchmarks on gfx1030.
83 "amdgpu-memcpy-loop-unroll",
84 cl::desc("Unroll factor (affecting 4x32-bit operations) to use for memory "
85 "operations when lowering statically-sized memcpy, memmove, or"
86 "memset as a loop"),
87 cl::init(16), cl::Hidden);
88
89static bool dependsOnLocalPhi(const Loop *L, const Value *Cond,
90 unsigned Depth = 0) {
92 if (!I)
93 return false;
94
95 if (!L->contains(I))
96 return false;
97 for (const Value *V : I->operand_values()) {
98 if (const PHINode *PHI = dyn_cast<PHINode>(V)) {
99 if (llvm::none_of(L->getSubLoops(), [PHI](const Loop* SubLoop) {
100 return SubLoop->contains(PHI); }))
101 return true;
102 } else if (Depth < 10 && dependsOnLocalPhi(L, V, Depth+1))
103 return true;
104 }
105 return false;
106}
107
109 : BaseT(TM, F.getDataLayout()),
110 TargetTriple(TM->getTargetTriple()),
111 ST(static_cast<const GCNSubtarget *>(TM->getSubtargetImpl(F))),
112 TLI(ST->getTargetLowering()) {}
113
116 OptimizationRemarkEmitter *ORE) const {
117 const Function &F = *L->getHeader()->getParent();
118 UP.Threshold =
119 F.getFnAttributeAsParsedInteger("amdgpu-unroll-threshold", 300);
121 F.getFnAttributeAsParsedInteger("amdgpu-partial-unroll-threshold", 150);
122 UP.MaxCount = std::numeric_limits<unsigned>::max();
123 UP.Partial = true;
124
125 // Conditional branch in a loop back edge needs 3 additional exec
126 // manipulations in average.
127 UP.BEInsns += 3;
128
129 // We want to run unroll even for the loops which have been vectorized.
130 UP.UnrollVectorizedLoop = true;
131
132 // Enable runtime unrolling for loops whose trip count is not known at
133 // compile time.
134 UP.Runtime = true;
135
136 // Maximum alloca size than can fit registers. Reserve 16 registers.
137 const unsigned MaxAlloca = (256 - 16) * 4;
138 unsigned ThresholdPrivate = UnrollThresholdPrivate;
139 unsigned ThresholdLocal = UnrollThresholdLocal;
140
141 // If this loop has the amdgpu.loop.unroll.threshold metadata we will use the
142 // provided threshold value as the default for Threshold
143 if (MDNode *LoopUnrollThreshold =
144 findOptionMDForLoop(L, "amdgpu.loop.unroll.threshold")) {
145 if (LoopUnrollThreshold->getNumOperands() == 2) {
147 LoopUnrollThreshold->getOperand(1));
148 if (MetaThresholdValue) {
149 // We will also use the supplied value for PartialThreshold for now.
150 // We may introduce additional metadata if it becomes necessary in the
151 // future.
152 UP.Threshold = MetaThresholdValue->getSExtValue();
154 ThresholdPrivate = std::min(ThresholdPrivate, UP.Threshold);
155 ThresholdLocal = std::min(ThresholdLocal, UP.Threshold);
156 }
157 }
158 }
159
160 unsigned MaxBoost = std::max(ThresholdPrivate, ThresholdLocal);
161 for (const BasicBlock *BB : L->getBlocks()) {
162 const DataLayout &DL = BB->getDataLayout();
163 unsigned LocalGEPsSeen = 0;
164
165 if (llvm::any_of(L->getSubLoops(), [BB](const Loop* SubLoop) {
166 return SubLoop->contains(BB); }))
167 continue; // Block belongs to an inner loop.
168
169 for (const Instruction &I : *BB) {
170 // Unroll a loop which contains an "if" statement whose condition
171 // defined by a PHI belonging to the loop. This may help to eliminate
172 // if region and potentially even PHI itself, saving on both divergence
173 // and registers used for the PHI.
174 // Add a small bonus for each of such "if" statements.
175 if (const CondBrInst *Br = dyn_cast<CondBrInst>(&I)) {
176 if (UP.Threshold < MaxBoost) {
177 BasicBlock *Succ0 = Br->getSuccessor(0);
178 BasicBlock *Succ1 = Br->getSuccessor(1);
179 if ((L->contains(Succ0) && L->isLoopExiting(Succ0)) ||
180 (L->contains(Succ1) && L->isLoopExiting(Succ1)))
181 continue;
182 if (dependsOnLocalPhi(L, Br->getCondition())) {
184 LLVM_DEBUG(dbgs() << "Set unroll threshold " << UP.Threshold
185 << " for loop:\n"
186 << *L << " due to " << *Br << '\n');
187 if (UP.Threshold >= MaxBoost)
188 return;
189 }
190 }
191 continue;
192 }
193
195 if (!GEP)
196 continue;
197
198 unsigned AS = GEP->getAddressSpace();
199 unsigned Threshold = 0;
201 Threshold = ThresholdPrivate;
203 Threshold = ThresholdLocal;
204 else
205 continue;
206
207 if (UP.Threshold >= Threshold)
208 continue;
209
210 if (AS == AMDGPUAS::PRIVATE_ADDRESS) {
211 const Value *Ptr = GEP->getPointerOperand();
212 const AllocaInst *Alloca =
214 if (!Alloca || !Alloca->isStaticAlloca())
215 continue;
216 auto AllocaSize = Alloca->getAllocationSize(DL);
217 if (!AllocaSize || AllocaSize->getFixedValue() > MaxAlloca)
218 continue;
219 } else if (AS == AMDGPUAS::LOCAL_ADDRESS ||
221 LocalGEPsSeen++;
222 // Inhibit unroll for local memory if we have seen addressing not to
223 // a variable, most likely we will be unable to combine it.
224 // Do not unroll too deep inner loops for local memory to give a chance
225 // to unroll an outer loop for a more important reason.
226 if (LocalGEPsSeen > 1 || L->getLoopDepth() > 2 ||
227 (!isa<GlobalVariable>(GEP->getPointerOperand()) &&
228 !isa<Argument>(GEP->getPointerOperand())))
229 continue;
230 LLVM_DEBUG(dbgs() << "Allow unroll runtime for loop:\n"
231 << *L << " due to LDS use.\n");
233 }
234
235 // Check if GEP depends on a value defined by this loop itself.
236 bool HasLoopDef = false;
237 for (const Value *Op : GEP->operands()) {
238 const Instruction *Inst = dyn_cast<Instruction>(Op);
239 if (!Inst || L->isLoopInvariant(Op))
240 continue;
241
242 if (llvm::any_of(L->getSubLoops(), [Inst](const Loop* SubLoop) {
243 return SubLoop->contains(Inst); }))
244 continue;
245 HasLoopDef = true;
246 break;
247 }
248 if (!HasLoopDef)
249 continue;
250
251 // We want to do whatever we can to limit the number of alloca
252 // instructions that make it through to the code generator. allocas
253 // require us to use indirect addressing, which is slow and prone to
254 // compiler bugs. If this loop does an address calculation on an
255 // alloca ptr, then we want to use a higher than normal loop unroll
256 // threshold. This will give SROA a better chance to eliminate these
257 // allocas.
258 //
259 // We also want to have more unrolling for local memory to let ds
260 // instructions with different offsets combine.
261 //
262 // Don't use the maximum allowed value here as it will make some
263 // programs way too big.
264 UP.Threshold = Threshold;
265 LLVM_DEBUG(dbgs() << "Set unroll threshold " << Threshold
266 << " for loop:\n"
267 << *L << " due to " << *GEP << '\n');
268 if (UP.Threshold >= MaxBoost)
269 return;
270 }
271
272 // If we got a GEP in a small BB from inner loop then increase max trip
273 // count to analyze for better estimation cost in unroll
274 if (L->isInnermost() && BB->size() < UnrollMaxBlockToAnalyze)
276 }
277}
278
283
285 return 1024;
286}
287
289 : BaseT(TM, F.getDataLayout()),
290 ST(static_cast<const GCNSubtarget *>(TM->getSubtargetImpl(F))),
291 TLI(ST->getTargetLowering()), CommonTTI(TM, F),
292 IsGraphics(AMDGPU::isGraphics(F.getCallingConv())) {
294 HasFP32Denormals = Mode.FP32Denormals != DenormalMode::getPreserveSign();
295}
296
298 return !F || !ST->isSingleLaneExecution(*F);
299}
300
301unsigned GCNTTIImpl::getNumberOfRegisters(unsigned RCID) const {
302 // NB: RCID is not an RCID. In fact it is 0 or 1 for scalar or vector
303 // registers. See getRegisterClassForType for the implementation.
304 // In this case vector registers are not vector in terms of
305 // VGPRs, but those which can hold multiple values.
306
307 // This is really the number of registers to fill when vectorizing /
308 // interleaving loops, so we lie to avoid trying to use all registers.
309 return 4;
310}
311
314 switch (K) {
316 return TypeSize::getFixed(32);
318 return TypeSize::getFixed(
319 (ST->hasAnyPackedFP64Ops() || ST->hasAnyPackedU64Ops()) ? 128
320 : ST->hasAnyPackedFP32Ops() ? 64
321 : 32);
323 return TypeSize::getScalable(0);
324 }
325 llvm_unreachable("Unsupported register kind");
326}
327
329 return 32;
330}
331
332unsigned GCNTTIImpl::getMaximumVF(unsigned ElemWidth, unsigned Opcode) const {
333 if (Opcode == Instruction::Load || Opcode == Instruction::Store)
334 return 32 * 4 / ElemWidth;
335 // For a given width return the max 0number of elements that can be combined
336 // into a wider bit value:
337 return (ElemWidth == 8 && ST->has16BitInsts()) ? 4
338 : (ElemWidth == 16 && ST->has16BitInsts()) ? 2
339 : (ElemWidth == 32 && ST->hasAnyPackedFP32Ops()) ? 2
340 : (ElemWidth == 64 &&
341 (ST->hasAnyPackedFP64Ops() || ST->hasAnyPackedU64Ops()))
342 ? 2
343 : 1;
344}
345
347 // The integer inst-count heuristic causes regressions on gfx94x and gfx950
348 // because 2-element vector trees that pass the scalar/vector instruction
349 // count comparison still widen scalar moves (e.g. v_mov_b32 to v_mov_b64)
350 // after codegen, increasing register pressure and throughput cost without
351 // reducing the total instruction count.
352 return !ST->hasGFX940Insts() && !ST->hasGFX950Insts();
353}
354
355unsigned GCNTTIImpl::getLoadVectorFactor(unsigned VF, unsigned LoadSize,
356 unsigned ChainSizeInBytes,
357 VectorType *VecTy) const {
358 unsigned VecRegBitWidth = VF * LoadSize;
359 if (VecRegBitWidth > 128 && VecTy->getScalarSizeInBits() < 32)
360 // TODO: Support element-size less than 32bit?
361 return 128 / LoadSize;
362
363 return VF;
364}
365
366unsigned GCNTTIImpl::getStoreVectorFactor(unsigned VF, unsigned StoreSize,
367 unsigned ChainSizeInBytes,
368 VectorType *VecTy) const {
369 unsigned VecRegBitWidth = VF * StoreSize;
370 if (VecRegBitWidth > 128)
371 return 128 / StoreSize;
372
373 return VF;
374}
375
376unsigned GCNTTIImpl::getLoadStoreVecRegBitWidth(unsigned AddrSpace) const {
377 if (AddrSpace == AMDGPUAS::GLOBAL_ADDRESS ||
378 AddrSpace == AMDGPUAS::CONSTANT_ADDRESS ||
380 AddrSpace == AMDGPUAS::BUFFER_FAT_POINTER ||
381 AddrSpace == AMDGPUAS::BUFFER_RESOURCE ||
383 return 512;
384 }
385
386 if (AddrSpace == AMDGPUAS::PRIVATE_ADDRESS)
387 return 8 * ST->getMaxPrivateElementSize();
388
389 // Common to flat, global, local and region. Assume for unknown addrspace.
390 return 128;
391}
392
393bool GCNTTIImpl::isLegalToVectorizeMemChain(unsigned ChainSizeInBytes,
394 Align Alignment,
395 unsigned AddrSpace) const {
396 // We allow vectorization of flat stores, even though we may need to decompose
397 // them later if they may access private memory. We don't have enough context
398 // here, and legalization can handle it.
399 if (AddrSpace == AMDGPUAS::PRIVATE_ADDRESS) {
400 return (Alignment >= 4 || ST->hasUnalignedScratchAccessEnabled()) &&
401 ChainSizeInBytes <= ST->getMaxPrivateElementSize();
402 }
403 return true;
404}
405
406bool GCNTTIImpl::isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes,
407 Align Alignment,
408 unsigned AddrSpace) const {
409 return isLegalToVectorizeMemChain(ChainSizeInBytes, Alignment, AddrSpace);
410}
411
412bool GCNTTIImpl::isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes,
413 Align Alignment,
414 unsigned AddrSpace) const {
415 return isLegalToVectorizeMemChain(ChainSizeInBytes, Alignment, AddrSpace);
416}
417
419 return 1024;
420}
421
423 LLVMContext &Context, Value *Length, unsigned SrcAddrSpace,
424 unsigned DestAddrSpace, Align SrcAlign, Align DestAlign,
425 std::optional<uint32_t> AtomicElementSize) const {
426
427 if (AtomicElementSize)
428 return Type::getIntNTy(Context, *AtomicElementSize * 8);
429
430 // 16-byte accesses achieve the highest copy throughput.
431 // If the operation has a fixed known length that is large enough, it is
432 // worthwhile to return an even wider type and let legalization lower it into
433 // multiple accesses, effectively unrolling the memcpy loop.
434 // We also rely on legalization to decompose into smaller accesses for
435 // subtargets and address spaces where it is necessary.
436 //
437 // Don't unroll if Length is not a constant, since unrolling leads to worse
438 // performance for length values that are smaller or slightly larger than the
439 // total size of the type returned here. Mitigating that would require a more
440 // complex lowering for variable-length memcpy and memmove.
441 unsigned I32EltsInVector = 4;
444 MemcpyLoopUnroll * I32EltsInVector);
445
446 return FixedVectorType::get(Type::getInt32Ty(Context), I32EltsInVector);
447}
448
450 SmallVectorImpl<Type *> &OpsOut, LLVMContext &Context,
451 unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace,
452 Align SrcAlign, Align DestAlign,
453 std::optional<uint32_t> AtomicCpySize) const {
454
455 if (AtomicCpySize)
457 OpsOut, Context, RemainingBytes, SrcAddrSpace, DestAddrSpace, SrcAlign,
458 DestAlign, AtomicCpySize);
459
460 Type *I32x4Ty = FixedVectorType::get(Type::getInt32Ty(Context), 4);
461 while (RemainingBytes >= 16) {
462 OpsOut.push_back(I32x4Ty);
463 RemainingBytes -= 16;
464 }
465
466 Type *I64Ty = Type::getInt64Ty(Context);
467 while (RemainingBytes >= 8) {
468 OpsOut.push_back(I64Ty);
469 RemainingBytes -= 8;
470 }
471
472 Type *I32Ty = Type::getInt32Ty(Context);
473 while (RemainingBytes >= 4) {
474 OpsOut.push_back(I32Ty);
475 RemainingBytes -= 4;
476 }
477
478 Type *I16Ty = Type::getInt16Ty(Context);
479 while (RemainingBytes >= 2) {
480 OpsOut.push_back(I16Ty);
481 RemainingBytes -= 2;
482 }
483
484 Type *I8Ty = Type::getInt8Ty(Context);
485 while (RemainingBytes) {
486 OpsOut.push_back(I8Ty);
487 --RemainingBytes;
488 }
489}
490
492 bool HasUnorderedReductions) const {
493 // Disable unrolling if the loop is not vectorized.
494 // TODO: Enable this again.
495 if (VF.isScalar())
496 return 1;
497
498 return 8;
499}
500
502 MemIntrinsicInfo &Info) const {
503 switch (Inst->getIntrinsicID()) {
504 case Intrinsic::amdgcn_ds_ordered_add:
505 case Intrinsic::amdgcn_ds_ordered_swap: {
506 auto *Ordering = dyn_cast<ConstantInt>(Inst->getArgOperand(2));
507 auto *Volatile = dyn_cast<ConstantInt>(Inst->getArgOperand(4));
508 if (!Ordering || !Volatile)
509 return false; // Invalid.
510
511 unsigned OrderingVal = Ordering->getZExtValue();
512 if (OrderingVal > static_cast<unsigned>(AtomicOrdering::SequentiallyConsistent))
513 return false;
514
515 Info.PtrVal = Inst->getArgOperand(0);
516 Info.Ordering = static_cast<AtomicOrdering>(OrderingVal);
517 Info.ReadMem = true;
518 Info.WriteMem = true;
519 Info.IsVolatile = !Volatile->isZero();
520 return true;
521 }
522 default:
523 return false;
524 }
525}
526
527/// \returns true if \p FMul and its single fadd/fsub user \p FAddSub are
528/// expected to fuse during instruction selection. \p Ty is the type the fused
529/// operation runs on.
530static bool canFuseFMulWithFAddSub(const SITargetLowering &TLI, Type *Ty,
531 const Instruction *FMul,
532 const Instruction *FAddSub) {
533 assert((FAddSub->getOpcode() == Instruction::FAdd ||
534 FAddSub->getOpcode() == Instruction::FSub) &&
535 "Expected an fadd or an fsub");
536
537 // The mad forms fuse exactly without fast-math flags but flush denormals.
538 // An fma forms only when it is not slower than the separate operations.
539 const Function &F = *FAddSub->getFunction();
540 const bool HasFMAD = TLI.isFMADLegal(F, Ty);
541 const bool HasFMA = TLI.isFMAFasterThanFMulAndFAdd(F, Ty);
542 if (!HasFMAD && !HasFMA)
543 return false;
544
545 // Without a mad the pair fuses only when both carry contract.
546 return HasFMAD || (FAddSub->hasAllowContract() && FMul->hasAllowContract());
547}
548
549/// An fma holds one multiply, so only one fmul operand fuses with \p FAddSub.
550static const Instruction *getFusedFMul(const SITargetLowering &TLI, Type *Ty,
551 const Instruction *FAddSub) {
552 for (const Value *Op : FAddSub->operands()) {
553 const auto *FMul = dyn_cast<Instruction>(Op);
554 if (FMul && FMul->getOpcode() == Instruction::FMul && FMul->hasOneUse() &&
555 canFuseFMulWithFAddSub(TLI, Ty, FMul, FAddSub))
556 return FMul;
557 }
558 return nullptr;
559}
560
561static bool isFusedFMul(const SITargetLowering &TLI, Type *Ty,
562 const Instruction *FMul, const Instruction *FAddSub) {
563 const Instruction *Fused = getFusedFMul(TLI, Ty, FAddSub);
564 if (Fused == FMul)
565 return true;
566 // (a * b + c * d) + e becomes fma(a, b, fma(c, d, e)) if the outer fadd has
567 // reassoc.
568 if (!Fused || FAddSub->getOpcode() != Instruction::FAdd ||
569 !FAddSub->hasOneUse())
570 return false;
571 const auto *Outer = dyn_cast<BinaryOperator>(*FAddSub->user_begin());
572 return Outer && Outer->getOpcode() == Instruction::FAdd &&
573 Outer->hasAllowReassoc() &&
574 canFuseFMulWithFAddSub(TLI, Ty, FMul, Outer);
575}
576
578 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
580 ArrayRef<const Value *> Args, const Instruction *CxtI) const {
581
582 // Legalize the type.
583 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
584 int ISD = TLI->InstructionOpcodeToISD(Opcode);
585
586 // Because we don't have any legal vector operations, but the legal types, we
587 // need to account for split vectors.
588 unsigned NElts = LT.second.isVector() ?
589 LT.second.getVectorNumElements() : 1;
590
591 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
592
593 switch (ISD) {
594 case ISD::SHL:
595 case ISD::SRL:
596 case ISD::SRA:
597 if (SLT == MVT::i64)
598 return get64BitInstrCost(CostKind) * LT.first * NElts;
599
600 if (ST->has16BitInsts() && SLT == MVT::i16)
601 NElts = (NElts + 1) / 2;
602
603 // i32
604 return getFullRateInstrCost() * LT.first * NElts;
605 case ISD::ADD:
606 case ISD::SUB:
607 if (SLT == MVT::i64 && ST->hasAnyPackedU64Ops())
608 NElts = (NElts + 1) / 2;
609 [[fallthrough]];
610 case ISD::AND:
611 case ISD::OR:
612 case ISD::XOR:
613 if (SLT == MVT::i64) {
614 // and, or and xor are typically split into 2 VALU instructions.
615 return 2 * getFullRateInstrCost() * LT.first * NElts;
616 }
617
618 if (ST->has16BitInsts() && SLT == MVT::i16)
619 NElts = (NElts + 1) / 2;
620
621 return LT.first * NElts * getFullRateInstrCost();
622 case ISD::MUL: {
623 const int QuarterRateCost = getQuarterRateInstrCost(CostKind);
624 if (SLT == MVT::i64) {
625 const int FullRateCost = getFullRateInstrCost();
626 return (4 * QuarterRateCost + (2 * 2) * FullRateCost) * LT.first * NElts;
627 }
628
629 if (ST->has16BitInsts() && SLT == MVT::i16)
630 NElts = (NElts + 1) / 2;
631
632 // i32
633 return QuarterRateCost * NElts * LT.first;
634 }
635 case ISD::FMUL:
636 // Check possible fuse {fadd|fsub}(a,fmul(b,c)) and return zero cost for
637 // fmul(b,c) supposing the fadd|fsub will get estimated cost for the whole
638 // fused operation.
639 if (CxtI && CxtI->hasOneUse()) {
640 const auto *FAddSub = dyn_cast<BinaryOperator>(*CxtI->user_begin());
641 if (FAddSub &&
642 (FAddSub->getOpcode() == Instruction::FAdd ||
643 FAddSub->getOpcode() == Instruction::FSub) &&
644 isFusedFMul(*TLI, Ty, CxtI, FAddSub))
646 }
647 [[fallthrough]];
648 case ISD::FADD:
649 case ISD::FSUB:
650 if (ST->hasAnyPackedFP32Ops() && SLT == MVT::f32)
651 NElts = (NElts + 1) / 2;
652 if (ST->hasBF16PackedInsts() && SLT == MVT::bf16)
653 NElts = (NElts + 1) / 2;
654 if (SLT == MVT::f64) {
655 if (ST->hasAnyPackedFP64Ops())
656 NElts = (NElts + 1) / 2;
657 return LT.first * NElts * get64BitInstrCost(CostKind);
658 }
659
660 if (ST->has16BitInsts() && SLT == MVT::f16)
661 NElts = (NElts + 1) / 2;
662
663 if (SLT == MVT::f32 || SLT == MVT::f16 || SLT == MVT::bf16)
664 return LT.first * NElts * getFullRateInstrCost();
665 break;
666 case ISD::FDIV:
667 case ISD::FREM:
668 // FIXME: frem should be handled separately. The fdiv in it is most of it,
669 // but the current lowering is also not entirely correct.
670 if (SLT == MVT::f64) {
671 int Cost = 7 * get64BitInstrCost(CostKind) +
672 getQuarterRateInstrCost(CostKind) +
673 3 * getHalfRateInstrCost(CostKind);
674 // Add cost of workaround.
675 if (!ST->hasUsableDivScaleConditionOutput())
676 Cost += 3 * getFullRateInstrCost();
677
678 return LT.first * Cost * NElts;
679 }
680
681 if (!Args.empty() && match(Args[0], PatternMatch::m_FPOne())) {
682 // TODO: This is more complicated, unsafe flags etc.
683 if ((SLT == MVT::f32 && !HasFP32Denormals) ||
684 (SLT == MVT::f16 && ST->has16BitInsts())) {
685 return LT.first * getTransInstrCost(CostKind) * NElts;
686 }
687 }
688
689 if (SLT == MVT::f16 && ST->has16BitInsts()) {
690 // 2 x v_cvt_f32_f16
691 // f32 rcp
692 // f32 fmul
693 // v_cvt_f16_f32
694 // f16 div_fixup
695 int Cost = 4 * getFullRateInstrCost() + 2 * getTransInstrCost(CostKind);
696 return LT.first * Cost * NElts;
697 }
698
699 if (SLT == MVT::f32 && (CxtI && CxtI->hasApproxFunc())) {
700 // Fast unsafe fdiv lowering:
701 // f32 rcp
702 // f32 fmul
703 int Cost = getTransInstrCost(CostKind) + getFullRateInstrCost();
704 return LT.first * Cost * NElts;
705 }
706
707 if (SLT == MVT::f32 || SLT == MVT::f16) {
708 // 4 more v_cvt_* insts without f16 insts support
709 int Cost = (SLT == MVT::f16 ? 14 : 10) * getFullRateInstrCost() +
710 1 * getTransInstrCost(CostKind);
711
712 if (!HasFP32Denormals) {
713 // FP mode switches.
714 Cost += 2 * getFullRateInstrCost();
715 }
716
717 return LT.first * NElts * Cost;
718 }
719 break;
720 case ISD::FNEG:
721 // Use the backend' estimation. If fneg is not free each element will cost
722 // one additional instruction.
723 return TLI->isFNegFree(SLT) ? 0 : NElts;
724 default:
725 break;
726 }
727
728 return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
729 Args, CxtI);
730}
731
732// Return true if there's a potential benefit from using v2f16/v2i16
733// instructions for an intrinsic, even if it requires nontrivial legalization.
735 switch (ID) {
736 case Intrinsic::fma:
737 case Intrinsic::fmuladd:
738 case Intrinsic::copysign:
739 case Intrinsic::minimumnum:
740 case Intrinsic::maximumnum:
741 case Intrinsic::canonicalize:
742 // There's a small benefit to using vector ops in the legalized code.
743 case Intrinsic::round:
744 case Intrinsic::uadd_sat:
745 case Intrinsic::usub_sat:
746 case Intrinsic::sadd_sat:
747 case Intrinsic::ssub_sat:
748 case Intrinsic::abs:
749 return true;
750 default:
751 return false;
752 }
753}
754
758 switch (ICA.getID()) {
759 case Intrinsic::fabs:
760 // Free source modifier in the common case.
761 return 0;
762 case Intrinsic::amdgcn_workitem_id_x:
763 case Intrinsic::amdgcn_workitem_id_y:
764 case Intrinsic::amdgcn_workitem_id_z:
765 // TODO: If hasPackedTID, or if the calling context is not an entry point
766 // there may be a bit instruction.
767 return 0;
768 case Intrinsic::amdgcn_workgroup_id_x:
769 case Intrinsic::amdgcn_workgroup_id_y:
770 case Intrinsic::amdgcn_workgroup_id_z:
771 case Intrinsic::amdgcn_lds_kernel_id:
772 case Intrinsic::amdgcn_dispatch_ptr:
773 case Intrinsic::amdgcn_dispatch_id:
774 case Intrinsic::amdgcn_implicitarg_ptr:
775 case Intrinsic::amdgcn_queue_ptr:
776 // Read from an argument register.
777 return 0;
778 default:
779 break;
780 }
781
782 Type *RetTy = ICA.getReturnType();
783
784 Intrinsic::ID IID = ICA.getID();
785 switch (IID) {
786 case Intrinsic::exp:
787 case Intrinsic::exp2:
788 case Intrinsic::exp10: {
789 // Legalize the type.
790 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
791 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
792 unsigned NElts =
793 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
794
795 if (SLT == MVT::f64) {
796 unsigned NumOps = 20;
797 if (IID == Intrinsic::exp)
798 ++NumOps;
799 else if (IID == Intrinsic::exp10)
800 NumOps += 3;
801
802 return LT.first * NElts * NumOps * get64BitInstrCost(CostKind);
803 }
804
805 if (SLT == MVT::f32) {
806 unsigned NumFullRateOps = 0;
807 // v_exp_f32 (transcendental).
808 unsigned NumTransOps = 1;
809
810 if (!ICA.getFlags().approxFunc() && IID != Intrinsic::exp2) {
811 // Non-AFN exp/exp10: range reduction + v_exp_f32 + ldexp +
812 // overflow/underflow checks (lowerFEXP). Denorm is also handled.
813 // FMA preamble: ~13 full-rate ops; non-FMA: ~17.
814 NumFullRateOps = ST->hasFastFMAF32() ? 13 : 17;
815 } else {
816 if (IID == Intrinsic::exp) {
817 // lowerFEXPUnsafe: fmul (base conversion) + v_exp_f32.
818 NumFullRateOps = 1;
819 } else if (IID == Intrinsic::exp10) {
820 // lowerFEXP10Unsafe: 3 fmul + 2 v_exp_f32 (double-exp2).
821 NumFullRateOps = 3;
822 NumTransOps = 2;
823 }
824 // Denorm scaling adds setcc + select + fadd + select + fmul.
825 if (HasFP32Denormals)
826 NumFullRateOps += 5;
827 }
828
829 InstructionCost Cost = NumFullRateOps * getFullRateInstrCost() +
830 NumTransOps * getTransInstrCost(CostKind);
831 return LT.first * NElts * Cost;
832 }
833
834 break;
835 }
836 case Intrinsic::log:
837 case Intrinsic::log2:
838 case Intrinsic::log10: {
839 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
840 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
841 unsigned NElts =
842 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
843
844 if (SLT == MVT::f32) {
845 unsigned NumFullRateOps = 0;
846
847 if (IID == Intrinsic::log2) {
848 // LowerFLOG2: just v_log_f32.
849 } else if (ICA.getFlags().approxFunc()) {
850 // LowerFLOGUnsafe: v_log_f32 + fmul (base conversion).
851 NumFullRateOps = 1;
852 } else {
853 // LowerFLOGCommon non-AFN: v_log_f32 + extended-precision
854 // multiply + finite check.
855 NumFullRateOps = ST->hasFastFMAF32() ? 8 : 11;
856 }
857
858 if (HasFP32Denormals)
859 NumFullRateOps += 5;
860
862 NumFullRateOps * getFullRateInstrCost() + getTransInstrCost(CostKind);
863 return LT.first * NElts * Cost;
864 }
865
866 break;
867 }
868 case Intrinsic::sin:
869 case Intrinsic::cos: {
870 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
871 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
872 unsigned NElts =
873 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
874
875 if (SLT == MVT::f32) {
876 // LowerTrig: fmul(1/2pi) + v_sin/v_cos.
877 unsigned NumFullRateOps = ST->hasTrigReducedRange() ? 2 : 1;
878
880 NumFullRateOps * getFullRateInstrCost() + getTransInstrCost(CostKind);
881 return LT.first * NElts * Cost;
882 }
883
884 break;
885 }
886 case Intrinsic::sqrt: {
887 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
888 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
889 unsigned NElts =
890 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
891
892 if (SLT == MVT::f32) {
893 unsigned NumFullRateOps = 0;
894
895 if (!ICA.getFlags().approxFunc()) {
896 // lowerFSQRTF32 non-AFN: v_sqrt_f32 + refinement + scale fixup.
897 NumFullRateOps = HasFP32Denormals ? 17 : 16;
898 }
899
901 NumFullRateOps * getFullRateInstrCost() + getTransInstrCost(CostKind);
902 return LT.first * NElts * Cost;
903 }
904
905 break;
906 }
907 default:
908 break;
909 }
910
913
914 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
915 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
916 unsigned NElts = LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
917
918 if ((ST->hasVOP3PInsts() &&
919 (SLT == MVT::f16 || SLT == MVT::i16 ||
920 (SLT == MVT::bf16 && ST->hasBF16PackedInsts()))) ||
921 (ST->hasAnyPackedFP64Ops() && SLT == MVT::f64) ||
922 (ST->hasAnyPackedU64Ops() && SLT == MVT::i64)) {
923 NElts = (NElts + 1) / 2;
924 } else if (SLT == MVT::f32) {
925 bool HasPk2FP32Op = ST->hasAnyPackedFP32Ops() &&
926 IID != Intrinsic::minimumnum &&
927 IID != Intrinsic::maximumnum;
928 NElts = HasPk2FP32Op ? (NElts + 1) / 2 : NElts;
929 }
930
931 // TODO: Get more refined intrinsic costs?
932 unsigned InstRate = getQuarterRateInstrCost(CostKind);
933
934 switch (ICA.getID()) {
935 case Intrinsic::fma:
936 case Intrinsic::fmuladd:
937 if (SLT == MVT::f64) {
938 InstRate = get64BitInstrCost(CostKind);
939 break;
940 }
941
942 if ((SLT == MVT::f32 && ST->hasFastFMAF32()) || SLT == MVT::f16)
943 InstRate = getFullRateInstrCost();
944 else {
945 InstRate = ST->hasFastFMAF32() ? getHalfRateInstrCost(CostKind)
946 : getQuarterRateInstrCost(CostKind);
947 }
948 break;
949 case Intrinsic::copysign:
950 return NElts * getFullRateInstrCost();
951 case Intrinsic::minimumnum:
952 case Intrinsic::maximumnum: {
953 // Instruction + 2 canonicalizes. For cases that need type promotion, we the
954 // promotion takes the place of the canonicalize.
955 unsigned NumOps = 3;
956 if (const IntrinsicInst *II = ICA.getInst()) {
957 // Directly legal with ieee=0
958 // TODO: Not directly legal with strictfp
960 NumOps = 1;
961 }
962
963 unsigned BaseRate =
964 SLT == MVT::f64 ? get64BitInstrCost(CostKind) : getFullRateInstrCost();
965 InstRate = BaseRate * NumOps;
966 break;
967 }
968 case Intrinsic::canonicalize: {
969 InstRate =
970 SLT == MVT::f64 ? get64BitInstrCost(CostKind) : getFullRateInstrCost();
971 break;
972 }
973 case Intrinsic::uadd_sat:
974 case Intrinsic::usub_sat:
975 case Intrinsic::sadd_sat:
976 case Intrinsic::ssub_sat: {
977 if (SLT == MVT::i16 || SLT == MVT::i32)
978 InstRate = getFullRateInstrCost();
979
980 static const auto ValidSatTys = {MVT::v2i16, MVT::v4i16};
981 if (any_of(ValidSatTys, equal_to(LT.second)))
982 NElts = 1;
983 break;
984 }
985 case Intrinsic::abs:
986 // Expansion takes 2 instructions for VALU
987 if (SLT == MVT::i16 || SLT == MVT::i32)
988 InstRate = 2 * getFullRateInstrCost();
989 break;
990 default:
991 break;
992 }
993
994 return LT.first * NElts * InstRate;
995}
996
999 const Instruction *I) const {
1000 assert((I == nullptr || I->getOpcode() == Opcode) &&
1001 "Opcode should reflect passed instruction.");
1002 const bool SCost =
1004 const int CBrCost = SCost ? 5 : 7;
1005 switch (Opcode) {
1006 case Instruction::UncondBr:
1007 // Branch instruction takes about 4 slots on gfx900.
1008 return SCost ? 1 : 4;
1009 case Instruction::CondBr:
1010 // Suppose conditional branch takes additional 3 exec manipulations
1011 // instructions in average.
1012 return CBrCost;
1013 case Instruction::Switch: {
1014 const auto *SI = dyn_cast_or_null<SwitchInst>(I);
1015 // Each case (including default) takes 1 cmp + 1 cbr instructions in
1016 // average.
1017 return (SI ? (SI->getNumCases() + 1) : 4) * (CBrCost + 1);
1018 }
1019 case Instruction::Ret:
1020 return SCost ? 1 : 10;
1021 }
1022 return BaseT::getCFInstrCost(Opcode, CostKind, I);
1023}
1024
1025// Measured packing cost of i1 for gfx9-12 is 4.0 to 4.8, up to 5.4 with
1026// true16; unpacking is 2.6 to 2.9.
1027static constexpr unsigned MaskPackCostPerElt = 4;
1028static constexpr unsigned MaskUnpackCostPerElt = 3;
1029
1030static std::optional<unsigned> getNumberOfPackedMaskElts(Type *Ty) {
1031 auto *FVT = dyn_cast<FixedVectorType>(Ty);
1032 if (FVT && FVT->getElementType()->isIntegerTy(1) && FVT->getNumElements() > 1)
1033 return FVT->getNumElements();
1034 return std::nullopt;
1035}
1036
1038 Type *Src,
1041 const Instruction *I) const {
1042 // A bitcast between a vector of i1 and an integer packs or unpacks a mask.
1043 if (Opcode == Instruction::BitCast) {
1044 if (std::optional<unsigned> Elts = getNumberOfPackedMaskElts(Src);
1045 Elts && Dst->isIntegerTy(*Elts))
1046 return InstructionCost(MaskPackCostPerElt) * *Elts *
1047 getFullRateInstrCost();
1048 if (std::optional<unsigned> Elts = getNumberOfPackedMaskElts(Dst);
1049 Elts && Src->isIntegerTy(*Elts))
1050 return InstructionCost(MaskUnpackCostPerElt) * *Elts *
1051 getFullRateInstrCost();
1052 }
1053
1054 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
1055}
1056
1059 std::optional<FastMathFlags> FMF,
1062 return BaseT::getArithmeticReductionCost(Opcode, Ty, FMF, CostKind);
1063
1064 // An add or xor reduction over a vector of i1 becomes a bit count over the
1065 // packed mask; the generic model prices a shuffle tree and misses that.
1066 if (Opcode == Instruction::Add || Opcode == Instruction::Xor) {
1067 if (std::optional<unsigned> Elts = getNumberOfPackedMaskElts(Ty))
1068 return InstructionCost(MaskPackCostPerElt) * *Elts *
1069 getFullRateInstrCost();
1070 }
1071
1072 EVT OrigTy = TLI->getValueType(DL, Ty);
1073
1074 // Computes cost on targets that have packed math instructions(which support
1075 // 16-bit types only).
1076 if (!ST->hasVOP3PInsts() || OrigTy.getScalarSizeInBits() != 16)
1077 return BaseT::getArithmeticReductionCost(Opcode, Ty, FMF, CostKind);
1078
1079 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
1080 return LT.first * getFullRateInstrCost();
1081}
1082
1085 FastMathFlags FMF,
1087 EVT OrigTy = TLI->getValueType(DL, Ty);
1088
1089 // Computes cost on targets that have packed math instructions(which support
1090 // 16-bit types only).
1091 if (!ST->hasVOP3PInsts() || OrigTy.getScalarSizeInBits() != 16)
1092 return BaseT::getMinMaxReductionCost(IID, Ty, FMF, CostKind);
1093
1094 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
1095 return LT.first * getHalfRateInstrCost(CostKind);
1096}
1097
1099 unsigned Opcode, Type *ValTy, TTI::TargetCostKind CostKind, unsigned Index,
1100 const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC) const {
1101 switch (Opcode) {
1102 case Instruction::ExtractElement:
1103 case Instruction::InsertElement: {
1104 unsigned EltSize
1105 = DL.getTypeSizeInBits(cast<VectorType>(ValTy)->getElementType());
1106 // Dynamic indexing isn't free and is best avoided.
1107 if (Index == ~0u)
1108 return 2;
1109 if (EltSize < 32) {
1110 if (EltSize == 16 && Index == 0 && ST->has16BitInsts())
1111 return 0;
1112 // Inserts of booleans are free.
1113 // TODO: Extracts are free too.
1114 if (EltSize == 1 && Opcode == Instruction::InsertElement)
1116 // Extract element sequences of consecutive i8 values that match a
1117 // register size are free most likely. It is not possible to know
1118 // if this extract is part of a consecutive sequence so this may
1119 // apply more generally.
1120 if (Opcode == Instruction::ExtractElement && EltSize == 8) {
1121 if (auto *FVTy = dyn_cast<FixedVectorType>(ValTy)) {
1122 unsigned NumElts = FVTy->getNumElements();
1123 if (NumElts >= 4 && isPowerOf2_32(NumElts))
1124 return 0;
1125 }
1126 }
1127 return BaseT::getVectorInstrCost(Opcode, ValTy, CostKind, Index, Op0, Op1,
1128 VIC);
1129 }
1130
1131 // Extracts are just reads of a subregister, so are free. Inserts are
1132 // considered free because we don't want to have any cost for scalarizing
1133 // operations, and we don't have to copy into a different register class.
1134 return 0;
1135 }
1136 default:
1137 return BaseT::getVectorInstrCost(Opcode, ValTy, CostKind, Index, Op0, Op1,
1138 VIC);
1139 }
1140}
1141
1142/// Analyze if the results of inline asm are divergent. If \p Indices is empty,
1143/// this is analyzing the collective result of all output registers. Otherwise,
1144/// this is only querying a specific result index if this returns multiple
1145/// registers in a struct.
1147 const CallInst *CI, ArrayRef<unsigned> Indices) const {
1148 // TODO: Handle complex extract indices
1149 if (Indices.size() > 1)
1150 return true;
1151
1152 const DataLayout &DL = CI->getDataLayout();
1153 const SIRegisterInfo *TRI = ST->getRegisterInfo();
1154 TargetLowering::AsmOperandInfoVector TargetConstraints =
1155 TLI->ParseConstraints(DL, ST->getRegisterInfo(), *CI);
1156
1157 const int TargetOutputIdx = Indices.empty() ? -1 : Indices[0];
1158
1159 int OutputIdx = 0;
1160 for (auto &TC : TargetConstraints) {
1161 if (TC.Type != InlineAsm::isOutput)
1162 continue;
1163
1164 // Skip outputs we don't care about.
1165 if (TargetOutputIdx != -1 && TargetOutputIdx != OutputIdx++)
1166 continue;
1167
1168 TLI->ComputeConstraintToUse(TC, SDValue());
1169
1170 const TargetRegisterClass *RC = TLI->getRegForInlineAsmConstraint(
1171 TRI, TC.ConstraintCode, TC.ConstraintVT).second;
1172
1173 // For AGPR constraints null is returned on subtargets without AGPRs, so
1174 // assume divergent for null.
1175 if (!RC || !TRI->isSGPRClass(RC))
1176 return true;
1177 }
1178
1179 return false;
1180}
1181
1183 const IntrinsicInst *ReadReg) const {
1184 Metadata *MD =
1185 cast<MetadataAsValue>(ReadReg->getArgOperand(0))->getMetadata();
1187 cast<MDString>(cast<MDNode>(MD)->getOperand(0))->getString();
1188
1189 // Special case registers that look like VCC.
1190 MVT VT = MVT::getVT(ReadReg->getType());
1191 if (VT == MVT::i1)
1192 return true;
1193
1194 // Special case scalar registers that start with 'v'.
1195 if (RegName.starts_with("vcc") || RegName.empty())
1196 return false;
1197
1198 // VGPR or AGPR is divergent. There aren't any specially named vector
1199 // registers.
1200 return RegName[0] == 'v' || RegName[0] == 'a';
1201}
1202
1203/// \returns true if the result of the value could potentially be
1204/// different across workitems in a wavefront.
1205bool GCNTTIImpl::isSourceOfDivergence(const Value *V) const {
1206 if (const Argument *A = dyn_cast<Argument>(V))
1208
1209 // Loads from the private and flat address spaces are divergent, because
1210 // threads can execute the load instruction with the same inputs and get
1211 // different results.
1212 //
1213 // All other loads are not divergent, because if threads issue loads with the
1214 // same arguments, they will always get the same result.
1215 if (const LoadInst *Load = dyn_cast<LoadInst>(V))
1216 return Load->getPointerAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS ||
1217 Load->getPointerAddressSpace() == AMDGPUAS::FLAT_ADDRESS;
1218
1219 // Atomics are divergent because they are executed sequentially: when an
1220 // atomic operation refers to the same address in each thread, then each
1221 // thread after the first sees the value written by the previous thread as
1222 // original value.
1224 return true;
1225
1227 Intrinsic::ID IID = Intrinsic->getIntrinsicID();
1228 switch (IID) {
1229 case Intrinsic::read_register:
1231 case Intrinsic::amdgcn_workitem_id_y:
1232 case Intrinsic::amdgcn_workitem_id_z: {
1233 const Function *F = Intrinsic->getFunction();
1234 bool HasUniformYZ =
1235 ST->hasWavefrontsEvenlySplittingXDim(*F, /*RequitezUniformYZ=*/true);
1236 std::optional<unsigned> ThisDimSize = ST->getReqdWorkGroupSize(
1237 *F, IID == Intrinsic::amdgcn_workitem_id_y ? 1 : 2);
1238 return !HasUniformYZ && (!ThisDimSize || *ThisDimSize != 1);
1239 }
1240 default:
1242 }
1243 }
1244
1245 // Assume all function calls are a source of divergence.
1246 if (const CallInst *CI = dyn_cast<CallInst>(V)) {
1247 if (CI->isInlineAsm())
1249 return true;
1250 }
1251
1252 // Assume all function calls are a source of divergence.
1253 if (isa<InvokeInst>(V))
1254 return true;
1255
1256 // If the target supports globally addressable scratch, the mapping from
1257 // scratch memory to the flat aperture changes therefore an address space cast
1258 // is no longer uniform.
1259 if (auto *CastI = dyn_cast<AddrSpaceCastInst>(V)) {
1260 return CastI->getSrcAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS &&
1261 CastI->getDestAddressSpace() == AMDGPUAS::FLAT_ADDRESS &&
1262 ST->hasGloballyAddressableScratch();
1263 }
1264
1265 return false;
1266}
1267
1268bool GCNTTIImpl::isAlwaysUniform(const Value *V) const {
1269 if (const IntrinsicInst *Intrinsic = dyn_cast<IntrinsicInst>(V))
1270 return AMDGPU::isIntrinsicAlwaysUniform(Intrinsic->getIntrinsicID());
1271
1272 if (const CallInst *CI = dyn_cast<CallInst>(V)) {
1273 if (CI->isInlineAsm())
1275 return false;
1276 }
1277
1278 // In most cases TID / wavefrontsize is uniform.
1279 //
1280 // However, if a kernel has uneven dimesions we can have a value of
1281 // workitem-id-x divided by the wavefrontsize non-uniform. For example
1282 // dimensions (65, 2) will have workitems with address (64, 0) and (0, 1)
1283 // packed into a same wave which gives 1 and 0 after the division by 64
1284 // respectively.
1285 //
1286 // The X dimension doesn't reset within a wave if either both the Y
1287 // and Z dimensions are of length 1, or if the X dimension's required
1288 // size is a power of 2. Note, however, if the X dimension's maximum
1289 // size is a power of 2 < the wavefront size, division by the wavefront
1290 // size is guaranteed to yield 0, so this is also a no-reset case.
1291 bool XDimDoesntResetWithinWaves = false;
1292 if (auto *I = dyn_cast<Instruction>(V)) {
1293 const Function *F = I->getFunction();
1294 XDimDoesntResetWithinWaves = ST->hasWavefrontsEvenlySplittingXDim(*F);
1295 }
1296 using namespace llvm::PatternMatch;
1297 uint64_t C;
1299 m_ConstantInt(C))) ||
1301 m_ConstantInt(C)))) {
1302 return C >= ST->getWavefrontSizeLog2() && XDimDoesntResetWithinWaves;
1303 }
1304
1305 Value *Mask;
1307 m_Value(Mask)))) {
1308 return computeKnownBits(Mask, DL).countMinTrailingZeros() >=
1309 ST->getWavefrontSizeLog2() &&
1310 XDimDoesntResetWithinWaves;
1311 }
1312
1313 const ExtractValueInst *ExtValue = dyn_cast<ExtractValueInst>(V);
1314 if (!ExtValue)
1315 return false;
1316
1317 const CallInst *CI = dyn_cast<CallInst>(ExtValue->getOperand(0));
1318 if (!CI)
1319 return false;
1320
1321 if (const IntrinsicInst *Intrinsic = dyn_cast<IntrinsicInst>(CI)) {
1322 switch (Intrinsic->getIntrinsicID()) {
1323 default:
1324 return false;
1325 case Intrinsic::amdgcn_if:
1326 case Intrinsic::amdgcn_else: {
1327 ArrayRef<unsigned> Indices = ExtValue->getIndices();
1328 return Indices.size() == 1 && Indices[0] == 1;
1329 }
1330 }
1331 }
1332
1333 // If we have inline asm returning mixed SGPR and VGPR results, we inferred
1334 // divergent for the overall struct return. We need to override it in the
1335 // case we're extracting an SGPR component here.
1336 if (CI->isInlineAsm())
1337 return !isInlineAsmSourceOfDivergence(CI, ExtValue->getIndices());
1338
1339 return false;
1340}
1341
1343 Intrinsic::ID IID) const {
1344 switch (IID) {
1345 case Intrinsic::amdgcn_is_shared:
1346 case Intrinsic::amdgcn_is_private:
1347 case Intrinsic::amdgcn_flat_atomic_fmax_num:
1348 case Intrinsic::amdgcn_flat_atomic_fmin_num:
1349 case Intrinsic::amdgcn_load_to_lds:
1350 case Intrinsic::amdgcn_make_buffer_rsrc:
1351 OpIndexes.push_back(0);
1352 return true;
1353 default:
1354 return false;
1355 }
1356}
1357
1359 Value *OldV,
1360 Value *NewV) const {
1361 auto IntrID = II->getIntrinsicID();
1362 switch (IntrID) {
1363 case Intrinsic::amdgcn_is_shared:
1364 case Intrinsic::amdgcn_is_private: {
1365 unsigned TrueAS = IntrID == Intrinsic::amdgcn_is_shared ?
1367 unsigned NewAS = NewV->getType()->getPointerAddressSpace();
1368 LLVMContext &Ctx = NewV->getType()->getContext();
1369 ConstantInt *NewVal = (TrueAS == NewAS) ?
1371 return NewVal;
1372 }
1373 case Intrinsic::amdgcn_flat_atomic_fmax_num:
1374 case Intrinsic::amdgcn_flat_atomic_fmin_num: {
1375 Type *DestTy = II->getType();
1376 Type *SrcTy = NewV->getType();
1377 unsigned NewAS = SrcTy->getPointerAddressSpace();
1379 return nullptr;
1380 Module *M = II->getModule();
1382 M, II->getIntrinsicID(), {DestTy, SrcTy, DestTy});
1383 II->setArgOperand(0, NewV);
1384 II->setCalledFunction(NewDecl);
1385 return II;
1386 }
1387 case Intrinsic::amdgcn_load_to_lds: {
1388 Type *SrcTy = NewV->getType();
1389 Module *M = II->getModule();
1390 Function *NewDecl =
1391 Intrinsic::getOrInsertDeclaration(M, II->getIntrinsicID(), {SrcTy});
1392 II->setArgOperand(0, NewV);
1393 II->setCalledFunction(NewDecl);
1394 return II;
1395 }
1396 case Intrinsic::amdgcn_make_buffer_rsrc: {
1397 Type *SrcTy = NewV->getType();
1398 Type *DstTy = II->getType();
1399 Type *NumRecordsTy = II->getArgOperand(2)->getType();
1400 Module *M = II->getModule();
1402 M, II->getIntrinsicID(), {DstTy, SrcTy, NumRecordsTy});
1403 II->setArgOperand(0, NewV);
1404 II->setCalledFunction(NewDecl);
1405 return II;
1406 }
1407 default:
1408 return nullptr;
1409 }
1410}
1411
1413 TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,
1415 VectorType *SubTp, ArrayRef<const Value *> Args, const Instruction *CxtI,
1416 TTI::VectorInstrContext VIC) const {
1417 if (!isa<FixedVectorType>(SrcTy))
1418 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index,
1419 SubTp);
1420
1421 Kind = improveShuffleKindFromMask(Kind, Mask, SrcTy, Index, SubTp);
1422
1423 unsigned ScalarSize = DL.getTypeSizeInBits(SrcTy->getElementType());
1424 if (ST->getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS &&
1425 (ScalarSize == 16 || ScalarSize == 8)) {
1426 // Larger vector widths may require additional instructions, but are
1427 // typically cheaper than scalarized versions.
1428 //
1429 // We assume that shuffling at a register granularity can be done for free.
1430 // This is not true for vectors fed into memory instructions, but it is
1431 // effectively true for all other shuffling. The emphasis of the logic here
1432 // is to assist generic transform in cleaning up / canonicalizing those
1433 // shuffles.
1434
1435 // With op_sel VOP3P instructions freely can access the low half or high
1436 // half of a register, so any swizzle of two elements is free.
1437 if (auto *SrcVecTy = dyn_cast<FixedVectorType>(SrcTy)) {
1438 unsigned NumSrcElts = SrcVecTy->getNumElements();
1439 if (ST->hasVOP3PInsts() && ScalarSize == 16 && NumSrcElts == 2 &&
1440 (Kind == TTI::SK_Broadcast || Kind == TTI::SK_Reverse ||
1441 Kind == TTI::SK_PermuteSingleSrc))
1442 return 0;
1443 }
1444
1445 unsigned EltsPerReg = 32 / ScalarSize;
1446 switch (Kind) {
1447 case TTI::SK_Broadcast:
1448 // A single v_perm_b32 can be re-used for all destination registers.
1449 return 1;
1450 case TTI::SK_Reverse:
1451 // One instruction per register.
1452 if (auto *DstVecTy = dyn_cast<FixedVectorType>(DstTy))
1453 return divideCeil(DstVecTy->getNumElements(), EltsPerReg);
1456 if (Index % EltsPerReg == 0)
1457 return 0; // Shuffling at register granularity
1458 if (auto *DstVecTy = dyn_cast<FixedVectorType>(DstTy))
1459 return divideCeil(DstVecTy->getNumElements(), EltsPerReg);
1462 auto *DstVecTy = dyn_cast<FixedVectorType>(DstTy);
1463 if (!DstVecTy)
1465 unsigned NumDstElts = DstVecTy->getNumElements();
1466 unsigned NumInsertElts = cast<FixedVectorType>(SubTp)->getNumElements();
1467 unsigned EndIndex = Index + NumInsertElts;
1468 unsigned BeginSubIdx = Index % EltsPerReg;
1469 unsigned EndSubIdx = EndIndex % EltsPerReg;
1470 unsigned Cost = 0;
1471
1472 if (BeginSubIdx != 0) {
1473 // Need to shift the inserted vector into place. The cost is the number
1474 // of destination registers overlapped by the inserted vector.
1475 Cost = divideCeil(EndIndex, EltsPerReg) - (Index / EltsPerReg);
1476 }
1477
1478 // If the last register overlap is partial, there may be three source
1479 // registers feeding into it; that takes an extra instruction.
1480 if (EndIndex < NumDstElts && BeginSubIdx < EndSubIdx)
1481 Cost += 1;
1482
1483 return Cost;
1484 }
1485 case TTI::SK_Splice: {
1486 auto *DstVecTy = dyn_cast<FixedVectorType>(DstTy);
1487 if (!DstVecTy)
1489 unsigned NumElts = DstVecTy->getNumElements();
1490 assert(NumElts == cast<FixedVectorType>(SrcTy)->getNumElements());
1491 // Determine the sub-region of the result vector that requires
1492 // sub-register shuffles / mixing.
1493 unsigned EltsFromLHS = NumElts - Index;
1494 bool LHSIsAligned = (Index % EltsPerReg) == 0;
1495 bool RHSIsAligned = (EltsFromLHS % EltsPerReg) == 0;
1496 if (LHSIsAligned && RHSIsAligned)
1497 return 0;
1498 if (LHSIsAligned && !RHSIsAligned)
1499 return divideCeil(NumElts, EltsPerReg) - (EltsFromLHS / EltsPerReg);
1500 if (!LHSIsAligned && RHSIsAligned)
1501 return divideCeil(EltsFromLHS, EltsPerReg);
1502 return divideCeil(NumElts, EltsPerReg);
1503 }
1504 default:
1505 break;
1506 }
1507
1508 if (!Mask.empty()) {
1509 unsigned NumSrcElts = cast<FixedVectorType>(SrcTy)->getNumElements();
1510
1511 // Generically estimate the cost by assuming that each destination
1512 // register is derived from sources via v_perm_b32 instructions if it
1513 // can't be copied as-is.
1514 //
1515 // For each destination register, derive the cost of obtaining it based
1516 // on the number of source registers that feed into it.
1517 unsigned Cost = 0;
1518 for (unsigned DstIdx = 0; DstIdx < Mask.size(); DstIdx += EltsPerReg) {
1520 bool Aligned = true;
1521 for (unsigned I = 0; I < EltsPerReg && DstIdx + I < Mask.size(); ++I) {
1522 int SrcIdx = Mask[DstIdx + I];
1523 if (SrcIdx == -1)
1524 continue;
1525 int Reg;
1526 if (SrcIdx < (int)NumSrcElts) {
1527 Reg = SrcIdx / EltsPerReg;
1528 if (SrcIdx % EltsPerReg != I)
1529 Aligned = false;
1530 } else {
1531 Reg = NumSrcElts + (SrcIdx - NumSrcElts) / EltsPerReg;
1532 if ((SrcIdx - NumSrcElts) % EltsPerReg != I)
1533 Aligned = false;
1534 }
1535 if (!llvm::is_contained(Regs, Reg))
1536 Regs.push_back(Reg);
1537 }
1538 if (Regs.size() >= 2)
1539 Cost += Regs.size() - 1;
1540 else if (!Aligned)
1541 Cost += 1;
1542 }
1543 return Cost;
1544 }
1545 }
1546
1547 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index,
1548 SubTp);
1549}
1550
1551/// Whether it is profitable to sink the operands of an
1552/// Instruction I to the basic block of I.
1553/// This helps using several modifiers (like abs and neg) more often.
1555 SmallVectorImpl<Use *> &Ops) const {
1556 using namespace PatternMatch;
1557
1558 // The cost model prices this fmul as free assuming it fuses with its
1559 // fadd/fsub user, which needs them in one block. Sink a stranded
1560 // loop-invariant fmul back to the user when they would fuse. Single use only,
1561 // so this stays a move.
1562 if (I->getOpcode() == Instruction::FAdd ||
1563 I->getOpcode() == Instruction::FSub) {
1564 const Instruction *FMul = getFusedFMul(*TLI, I->getType(), I);
1565 if (FMul && FMul->getParent() != I->getParent())
1566 Ops.push_back(&I->getOperandUse(I->getOperand(0) == FMul ? 0 : 1));
1567 }
1568
1569 for (auto &Op : I->operands()) {
1570 // Ensure we are not already sinking this operand.
1571 if (any_of(Ops, [&](Use *U) { return U->get() == Op.get(); }))
1572 continue;
1573
1574 if (match(&Op, m_FAbs(m_Value())) || match(&Op, m_FNeg(m_Value()))) {
1575 Ops.push_back(&Op);
1576 continue;
1577 }
1578
1579 // Check for zero-cost multiple use InsertElement/ExtractElement
1580 // instructions
1581 if (Instruction *OpInst = dyn_cast<Instruction>(Op.get())) {
1582 if (OpInst->getType()->isVectorTy() && OpInst->getNumOperands() > 1) {
1583 Instruction *VecOpInst = dyn_cast<Instruction>(OpInst->getOperand(0));
1584 if (VecOpInst && VecOpInst->hasOneUse())
1585 continue;
1586
1587 if (getVectorInstrCost(OpInst->getOpcode(), OpInst->getType(),
1589 OpInst->getOperand(0),
1590 OpInst->getOperand(1)) == 0) {
1591 Ops.push_back(&Op);
1592 continue;
1593 }
1594 }
1595 }
1596
1597 if (auto *Shuffle = dyn_cast<ShuffleVectorInst>(Op.get())) {
1598
1599 unsigned EltSize = DL.getTypeSizeInBits(
1600 cast<VectorType>(Shuffle->getType())->getElementType());
1601
1602 // For i32 (or greater) shufflevectors, these will be lowered into a
1603 // series of insert / extract elements, which will be coalesced away.
1604 if (EltSize < 16 || !ST->has16BitInsts())
1605 continue;
1606
1607 int NumSubElts, SubIndex;
1608 if (Shuffle->changesLength()) {
1609 if (Shuffle->increasesLength() && Shuffle->isIdentityWithPadding()) {
1610 Ops.push_back(&Op);
1611 continue;
1612 }
1613
1614 if ((Shuffle->isExtractSubvectorMask(SubIndex) ||
1615 Shuffle->isInsertSubvectorMask(NumSubElts, SubIndex)) &&
1616 !(SubIndex & 0x1)) {
1617 Ops.push_back(&Op);
1618 continue;
1619 }
1620 }
1621
1622 if (Shuffle->isReverse() || Shuffle->isZeroEltSplat() ||
1623 Shuffle->isSingleSource()) {
1624 Ops.push_back(&Op);
1625 continue;
1626 }
1627 }
1628 }
1629
1630 return !Ops.empty();
1631}
1632
1634 const Function *Callee) const {
1635 const TargetMachine &TM = getTLI()->getTargetMachine();
1636 const GCNSubtarget *CallerST
1637 = static_cast<const GCNSubtarget *>(TM.getSubtargetImpl(*Caller));
1638 const GCNSubtarget *CalleeST
1639 = static_cast<const GCNSubtarget *>(TM.getSubtargetImpl(*Callee));
1640
1641 if (!BaseT::areInlineCompatible(Caller, Callee))
1642 return false;
1643
1644 // FIXME: dx10_clamp can just take the caller setting, but there seems to be
1645 // no way to support merge for backend defined attributes.
1646 SIModeRegisterDefaults CallerMode(*Caller, *CallerST);
1647 SIModeRegisterDefaults CalleeMode(*Callee, *CalleeST);
1648 if (!CallerMode.isInlineCompatible(CalleeMode))
1649 return false;
1650
1651 if (Callee->hasFnAttribute(Attribute::AlwaysInline) ||
1652 Callee->hasFnAttribute(Attribute::InlineHint))
1653 return true;
1654
1655 // Hack to make compile times reasonable.
1656 if (InlineMaxBB) {
1657 // Single BB does not increase total BB amount.
1658 if (Callee->size() == 1)
1659 return true;
1660 size_t BBSize = Caller->size() + Callee->size() - 1;
1661 if (BBSize > InlineMaxBB) {
1662 LLVM_DEBUG(dbgs() << "AMDGPU inline max-BB rejected inlining "
1663 << Callee->getName() << " into " << Caller->getName()
1664 << ": caller BBs=" << Caller->size() << ", callee BBs="
1665 << Callee->size() << ", combined BBs=" << BBSize
1666 << ", max BBs=" << InlineMaxBB << '\n');
1667 return false;
1668 }
1669 }
1670
1671 return true;
1672}
1673
1675 const SITargetLowering *TLI,
1676 const GCNTTIImpl *TTIImpl) {
1677 const int NrOfSGPRUntilSpill = 26;
1678 const int NrOfVGPRUntilSpill = 32;
1679
1680 const DataLayout &DL = TTIImpl->getDataLayout();
1681
1682 unsigned adjustThreshold = 0;
1683 int SGPRsInUse = 0;
1684 int VGPRsInUse = 0;
1685 for (const Use &A : CB->args()) {
1686 SmallVector<EVT, 4> ValueVTs;
1687 ComputeValueVTs(*TLI, DL, A.get()->getType(), ValueVTs);
1688 for (auto ArgVT : ValueVTs) {
1689 unsigned CCRegNum = TLI->getNumRegistersForCallingConv(
1690 CB->getContext(), CB->getCallingConv(), ArgVT);
1692 SGPRsInUse += CCRegNum;
1693 else
1694 VGPRsInUse += CCRegNum;
1695 }
1696 }
1697
1698 // The cost of passing function arguments through the stack:
1699 // 1 instruction to put a function argument on the stack in the caller.
1700 // 1 instruction to take a function argument from the stack in callee.
1701 // 1 instruction is explicitly take care of data dependencies in callee
1702 // function.
1703 InstructionCost ArgStackCost(1);
1704 ArgStackCost += const_cast<GCNTTIImpl *>(TTIImpl)->getMemoryOpCost(
1705 Instruction::Store, Type::getInt32Ty(CB->getContext()), Align(4),
1707 ArgStackCost += const_cast<GCNTTIImpl *>(TTIImpl)->getMemoryOpCost(
1708 Instruction::Load, Type::getInt32Ty(CB->getContext()), Align(4),
1710
1711 // The penalty cost is computed relative to the cost of instructions and does
1712 // not model any storage costs.
1713 adjustThreshold += std::max(0, SGPRsInUse - NrOfSGPRUntilSpill) *
1714 ArgStackCost.getValue() * InlineConstants::getInstrCost();
1715 adjustThreshold += std::max(0, VGPRsInUse - NrOfVGPRUntilSpill) *
1716 ArgStackCost.getValue() * InlineConstants::getInstrCost();
1717 return adjustThreshold;
1718}
1719
1720static unsigned getCallArgsTotalAllocaSize(const CallBase *CB,
1721 const DataLayout &DL) {
1722 // If we have a pointer to a private array passed into a function
1723 // it will not be optimized out, leaving scratch usage.
1724 // This function calculates the total size in bytes of the memory that would
1725 // end in scratch if the call was not inlined.
1726 unsigned AllocaSize = 0;
1728 for (Value *PtrArg : CB->args()) {
1729 PointerType *Ty = dyn_cast<PointerType>(PtrArg->getType());
1730 if (!Ty)
1731 continue;
1732
1733 unsigned AddrSpace = Ty->getAddressSpace();
1734 if (AddrSpace != AMDGPUAS::FLAT_ADDRESS &&
1735 AddrSpace != AMDGPUAS::PRIVATE_ADDRESS)
1736 continue;
1737
1739 if (!AI || !AI->isStaticAlloca() || !AIVisited.insert(AI).second)
1740 continue;
1741
1742 if (auto Size = AI->getAllocationSize(DL))
1743 AllocaSize += Size->getFixedValue();
1744 }
1745 return AllocaSize;
1746}
1747
1752
1754 unsigned Threshold = adjustInliningThresholdUsingCallee(CB, TLI, this);
1755
1756 // Private object passed as arguments may end up in scratch usage if the call
1757 // is not inlined. Increase the inline threshold to promote inlining.
1758 unsigned AllocaSize = getCallArgsTotalAllocaSize(CB, DL);
1759 if (AllocaSize > 0)
1760 Threshold += ArgAllocaCost;
1761 return Threshold;
1762}
1763
1765 const AllocaInst *AI) const {
1766
1767 // Below the cutoff, assume that the private memory objects would be
1768 // optimized
1769 auto AllocaSize = getCallArgsTotalAllocaSize(CB, DL);
1770 if (AllocaSize <= ArgAllocaCutoff)
1771 return 0;
1772
1773 // Above the cutoff, we give a cost to each private memory object
1774 // depending its size. If the array can be optimized by SROA this cost is not
1775 // added to the total-cost in the inliner cost analysis.
1776 //
1777 // We choose the total cost of the alloca such that their sum cancels the
1778 // bonus given in the threshold (ArgAllocaCost).
1779 //
1780 // Cost_Alloca_0 + ... + Cost_Alloca_N == ArgAllocaCost
1781 //
1782 // Awkwardly, the ArgAllocaCost bonus is multiplied by threshold-multiplier,
1783 // the single-bb bonus and the vector-bonus.
1784 //
1785 // We compensate the first two multipliers, by repeating logic from the
1786 // inliner-cost in here. The vector-bonus is 0 on AMDGPU.
1787 static_assert(InlinerVectorBonusPercent == 0, "vector bonus assumed to be 0");
1788 unsigned Threshold = ArgAllocaCost * getInliningThresholdMultiplier();
1789
1790 bool SingleBB = none_of(*CB->getCalledFunction(), [](const BasicBlock &BB) {
1791 return BB.getTerminator()->getNumSuccessors() > 1;
1792 });
1793 if (SingleBB) {
1794 Threshold += Threshold / 2;
1795 }
1796
1797 auto ArgAllocaSize = AI->getAllocationSize(DL);
1798 if (!ArgAllocaSize)
1799 return 0;
1800
1801 // Attribute the bonus proportionally to the alloca size
1802 unsigned AllocaThresholdBonus =
1803 (Threshold * ArgAllocaSize->getFixedValue()) / AllocaSize;
1804
1805 return AllocaThresholdBonus;
1806}
1807
1810 OptimizationRemarkEmitter *ORE) const {
1811 CommonTTI.getUnrollingPreferences(L, SE, UP, ORE);
1812}
1813
1815 TTI::PeelingPreferences &PP) const {
1816 CommonTTI.getPeelingPreferences(L, SE, PP);
1817}
1818
1819int GCNTTIImpl::getTransInstrCost(TTI::TargetCostKind CostKind) const {
1820 return getQuarterRateInstrCost(CostKind);
1821}
1822
1823int GCNTTIImpl::get64BitInstrCost(TTI::TargetCostKind CostKind) const {
1824 return ST->hasFullRate64Ops()
1825 ? getFullRateInstrCost()
1826 : ST->hasHalfRate64Ops() ? getHalfRateInstrCost(CostKind)
1827 : getQuarterRateInstrCost(CostKind);
1828}
1829
1830std::pair<InstructionCost, MVT>
1831GCNTTIImpl::getTypeLegalizationCost(Type *Ty) const {
1832 std::pair<InstructionCost, MVT> Cost = BaseT::getTypeLegalizationCost(Ty);
1833 auto Size = DL.getTypeSizeInBits(Ty);
1834 // Maximum load or store can handle 8 dwords for scalar and 4 for
1835 // vector ALU. Let's assume anything above 8 dwords is expensive
1836 // even if legal.
1837 if (Size <= 256)
1838 return Cost;
1839
1840 Cost.first += (Size + 255) / 256;
1841 return Cost;
1842}
1843
1845 if (ST->hasVmemPrefInsts() || ST->hasSmemPrefetchInsts())
1846 return ST->getDataCacheLineSize();
1847 return 0;
1848}
1849
1851 return ST->hasPrefetch() ? 128 : 0;
1852}
1853
1856}
1857
1859 const Function &F,
1860 SmallVectorImpl<std::pair<StringRef, int64_t>> &LB) const {
1862 LB.push_back({"amdgpu-max-num-workgroups[0]", MaxNumWorkgroups[0]});
1863 LB.push_back({"amdgpu-max-num-workgroups[1]", MaxNumWorkgroups[1]});
1864 LB.push_back({"amdgpu-max-num-workgroups[2]", MaxNumWorkgroups[2]});
1865 std::pair<unsigned, unsigned> FlatWorkGroupSize =
1866 ST->getFlatWorkGroupSizes(F);
1867 LB.push_back({"amdgpu-flat-work-group-size[0]", FlatWorkGroupSize.first});
1868 LB.push_back({"amdgpu-flat-work-group-size[1]", FlatWorkGroupSize.second});
1869 std::pair<unsigned, unsigned> WavesPerEU = ST->getWavesPerEU(F);
1870 LB.push_back({"amdgpu-waves-per-eu[0]", WavesPerEU.first});
1871 LB.push_back({"amdgpu-waves-per-eu[1]", WavesPerEU.second});
1872}
1873
1876 if (!ST->hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
1877 return KnownIEEEMode::On; // Only mode on gfx1170+
1878
1879 const Function *F = I.getFunction();
1880 if (!F)
1882
1883 Attribute IEEEAttr = F->getFnAttribute("amdgpu-ieee");
1884 if (IEEEAttr.isValid())
1886
1887 return AMDGPU::isShader(F->getCallingConv()) ? KnownIEEEMode::Off
1889}
1890
1892 Align Alignment,
1893 unsigned AddressSpace,
1895 TTI::OperandValueInfo OpInfo,
1896 const Instruction *I) const {
1897 if (VectorType *VecTy = dyn_cast<VectorType>(Src)) {
1898 if ((Opcode == Instruction::Load || Opcode == Instruction::Store) &&
1900 VecTy->getElementType()->isIntegerTy(8)) {
1901 return divideCeil(DL.getTypeSizeInBits(VecTy) - 1,
1903 }
1904 }
1905 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace, CostKind,
1906 OpInfo, I);
1907}
1908
1910 if (VectorType *VecTy = dyn_cast<VectorType>(Tp)) {
1911 if (VecTy->getElementType()->isIntegerTy(8)) {
1912 unsigned ElementCount = VecTy->getElementCount().getFixedValue();
1913 return divideCeil(ElementCount - 1, 4);
1914 }
1915 }
1916 return BaseT::getNumberOfParts(Tp);
1917}
1918
1921 switch (Intrinsic->getIntrinsicID()) {
1922 case Intrinsic::amdgcn_wave_shuffle:
1924 default:
1925 break;
1926 }
1927 }
1928
1929 if (isAlwaysUniform(V))
1931
1932 if (isSourceOfDivergence(V))
1934
1936}
1937
1939 StackOffset BaseOffset,
1940 bool HasBaseReg, int64_t Scale,
1941 unsigned AddrSpace) const {
1942 if (HasBaseReg && Scale != 0) {
1943 // gfx1250+ can fold base+scale*index when scale matches the memory access
1944 // size (scale_offset bit). Supported for flat/global/constant/scratch
1945 // (VMEM, max 128 bits) and constant_32bit (SMRD, capped to 128 bits here).
1946 if (getST()->hasScaleOffset() && Ty && Ty->isSized() &&
1948 AddrSpace == AMDGPUAS::FLAT_ADDRESS ||
1949 AddrSpace == AMDGPUAS::PRIVATE_ADDRESS)) {
1950 TypeSize StoreSize = getDataLayout().getTypeStoreSize(Ty);
1951 if (TypeSize::isKnownLE(StoreSize, TypeSize::getFixed(16)) &&
1952 static_cast<int64_t>(StoreSize.getFixedValue()) == Scale)
1953 return 0;
1954 }
1955 return 1;
1956 }
1957 return BaseT::getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg, Scale,
1958 AddrSpace);
1959}
1960
1962 const TTI::LSRCost &B) const {
1963 // Favor lower per-iteration work over preheader/setup costs.
1964 // AMDGPU lacks rich addressing modes, so ScaleCost is folded into the
1965 // effective instruction count (base+scale*index requires a separate ADD).
1966 unsigned EffInsnsA = A.Insns + A.ScaleCost;
1967 unsigned EffInsnsB = B.Insns + B.ScaleCost;
1968
1969 return std::tie(EffInsnsA, A.NumIVMuls, A.AddRecCost, A.NumBaseAdds,
1970 A.SetupCost, A.ImmCost, A.NumRegs) <
1971 std::tie(EffInsnsB, B.NumIVMuls, B.AddRecCost, B.NumBaseAdds,
1972 B.SetupCost, B.ImmCost, B.NumRegs);
1973}
1974
1976 // isLSRCostLess de-prioritizes register count; keep consistent.
1977 return false;
1978}
1979
1981 // Prefer the baseline when LSR cannot clearly reduce per-iteration work.
1982 return true;
1983}
1984
1986 const SmallBitVector &UniformArgs) const {
1988 switch (Intrinsic->getIntrinsicID()) {
1989 case Intrinsic::amdgcn_wave_shuffle:
1990 // wave_shuffle(Value, Index): result is uniform when either Value or Index
1991 // is uniform.
1992 return UniformArgs[0] || UniformArgs[1];
1993 default:
1994 llvm_unreachable("unexpected intrinsic in isUniform");
1995 }
1996}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
unsigned uint64_t
Provides AMDGPU specific target descriptions.
Rewrite undef for PHI
Base class for AMDGPU specific classes of TargetSubtarget.
The AMDGPU TargetMachine interface definition for hw codegen targets.
static constexpr unsigned MaskPackCostPerElt
static cl::opt< unsigned > MemcpyLoopUnroll("amdgpu-memcpy-loop-unroll", cl::desc("Unroll factor (affecting 4x32-bit operations) to use for memory " "operations when lowering statically-sized memcpy, memmove, or" "memset as a loop"), cl::init(16), cl::Hidden)
static cl::opt< unsigned > UnrollThresholdIf("amdgpu-unroll-threshold-if", cl::desc("Unroll threshold increment for AMDGPU for each if statement inside loop"), cl::init(200), cl::Hidden)
static cl::opt< unsigned > ArgAllocaCost("amdgpu-inline-arg-alloca-cost", cl::Hidden, cl::init(4000), cl::desc("Cost of alloca argument"))
static bool canFuseFMulWithFAddSub(const SITargetLowering &TLI, Type *Ty, const Instruction *FMul, const Instruction *FAddSub)
static bool dependsOnLocalPhi(const Loop *L, const Value *Cond, unsigned Depth=0)
static cl::opt< bool > UnrollRuntimeLocal("amdgpu-unroll-runtime-local", cl::desc("Allow runtime unroll for AMDGPU if local memory used in a loop"), cl::init(true), cl::Hidden)
static unsigned adjustInliningThresholdUsingCallee(const CallBase *CB, const SITargetLowering *TLI, const GCNTTIImpl *TTIImpl)
static cl::opt< unsigned > ArgAllocaCutoff("amdgpu-inline-arg-alloca-cutoff", cl::Hidden, cl::init(256), cl::desc("Maximum alloca size to use for inline cost"))
static cl::opt< size_t > InlineMaxBB("amdgpu-inline-max-bb", cl::Hidden, cl::init(1100), cl::desc("Maximum number of BBs allowed in a function after inlining" " (compile time constraint)"))
static bool isFusedFMul(const SITargetLowering &TLI, Type *Ty, const Instruction *FMul, const Instruction *FAddSub)
static std::optional< unsigned > getNumberOfPackedMaskElts(Type *Ty)
static constexpr unsigned MaskUnpackCostPerElt
static const Instruction * getFusedFMul(const SITargetLowering &TLI, Type *Ty, const Instruction *FAddSub)
An fma holds one multiply, so only one fmul operand fuses with FAddSub.
static bool intrinsicHasPackedVectorBenefit(Intrinsic::ID ID)
static cl::opt< unsigned > UnrollMaxBlockToAnalyze("amdgpu-unroll-max-block-to-analyze", cl::desc("Inner loop block size threshold to analyze in unroll for AMDGPU"), cl::init(32), cl::Hidden)
static unsigned getCallArgsTotalAllocaSize(const CallBase *CB, const DataLayout &DL)
static cl::opt< unsigned > UnrollThresholdPrivate("amdgpu-unroll-threshold-private", cl::desc("Unroll threshold for AMDGPU if private memory used in a loop"), cl::init(2700), cl::Hidden)
static cl::opt< unsigned > UnrollThresholdLocal("amdgpu-unroll-threshold-local", cl::desc("Unroll threshold for AMDGPU if local memory used in a loop"), cl::init(1000), cl::Hidden)
This file a TargetTransformInfoImplBase conforming object specific to the AMDGPU target machine.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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")))
Hexagon Common GEP
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define RegName(no)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file implements the SmallBitVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
std::optional< unsigned > getReqdWorkGroupSize(const Function &F, unsigned Dim) const
bool hasWavefrontsEvenlySplittingXDim(const Function &F, bool REquiresUniformYZ=false) const
uint64_t getMaxMemIntrinsicInlineSizeThreshold() const override
AMDGPUTTIImpl(const AMDGPUTargetMachine *TM, const Function &F)
void getPeelingPreferences(Loop *L, ScalarEvolution &SE, TTI::PeelingPreferences &PP) const override
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP, OptimizationRemarkEmitter *ORE) const override
an instruction to allocate memory on the stack
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:106
LLVM_ABI bool getValueAsBool() const
Return the attribute's value as a boolean.
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:266
LLVM Basic Block Representation.
Definition BasicBlock.h:62
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 getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
unsigned getNumberOfParts(Type *Tp) const override
TTI::ShuffleKind improveShuffleKindFromMask(TTI::ShuffleKind Kind, ArrayRef< int > Mask, VectorType *SrcTy, int &Index, VectorType *&SubTy) const
bool areInlineCompatible(const Function *Caller, const Function *Callee) const override
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, StackOffset BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace) const override
void getPeelingPreferences(Loop *L, ScalarEvolution &SE, TTI::PeelingPreferences &PP) 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 getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) 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
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
CallingConv::ID getCallingConv() const
Value * getArgOperand(unsigned i) const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
This class represents a function call, abstracting a target machine's calling convention.
Conditional Branch instruction.
This is the shared class of boolean and integer constants.
Definition Constants.h:87
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
Definition Constants.h:174
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
TypeSize getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type.
Definition DataLayout.h:579
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:316
ArrayRef< unsigned > getIndices() const
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
bool approxFunc() const
Definition FMF.h:70
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
GCNTTIImpl(const AMDGPUTargetMachine *TM, const Function &F)
unsigned getLoadStoreVecRegBitWidth(unsigned AddrSpace) const override
InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, StackOffset BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace) 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
Account for loads of i8 vector types to have reduced cost.
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
void collectKernelLaunchBounds(const Function &F, SmallVectorImpl< std::pair< StringRef, int64_t > > &LB) const override
bool isUniform(const Instruction *I, const SmallBitVector &UniformArgs) const override
bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const override
bool isInlineAsmSourceOfDivergence(const CallInst *CI, ArrayRef< unsigned > Indices={}) const
Analyze if the results of inline asm are divergent.
bool isReadRegisterSourceOfDivergence(const IntrinsicInst *ReadReg) const
unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const override
unsigned getNumberOfRegisters(unsigned RCID) const override
bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const override
unsigned getCacheLineSize() const override
Data cache line size for LoopDataPrefetch pass. Has no use before GFX12.
unsigned getStoreVectorFactor(unsigned VF, unsigned StoreSize, unsigned ChainSizeInBytes, VectorType *VecTy) const override
bool isLegalToVectorizeMemChain(unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const
bool isLSRCostLess(const TTI::LSRCost &A, const TTI::LSRCost &B) const override
bool shouldPrefetchAddressSpace(unsigned AS) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *ValTy, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
bool hasBranchDivergence(const Function *F=nullptr) const override
Value * rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV, Value *NewV) const override
unsigned getCallerAllocaCost(const CallBase *CB, const AllocaInst *AI) const override
void getMemcpyLoopResidualLoweringType(SmallVectorImpl< Type * > &OpsOut, LLVMContext &Context, unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace, Align SrcAlign, Align DestAlign, std::optional< uint32_t > AtomicCpySize) const override
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
Get intrinsic cost based on arguments.
unsigned getInliningThresholdMultiplier() const override
unsigned getLoadVectorFactor(unsigned VF, unsigned LoadSize, unsigned ChainSizeInBytes, VectorType *VecTy) const override
unsigned getPrefetchDistance() const override
How much before a load we should place the prefetch instruction.
InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
KnownIEEEMode fpenvIEEEMode(const Instruction &I) const
Return KnownIEEEMode::On if we know if the use context can assume "amdgpu-ieee"="true" and KnownIEEEM...
unsigned adjustInliningThreshold(const CallBase *CB) const override
bool isProfitableToSinkOperands(Instruction *I, SmallVectorImpl< Use * > &Ops) const override
Whether it is profitable to sink the operands of an Instruction I to the basic block of I.
bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info) const override
bool areInlineCompatible(const Function *Caller, const Function *Callee) const override
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
Try to calculate op costs for min/max reduction operations.
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
bool shouldDropLSRSolutionIfLessProfitable() const override
unsigned getMaxInterleaveFactor(ElementCount VF, bool HasUnorderedReductions) const override
int getInliningLastCallToStaticBonus() const override
bool collectFlatAddressOperands(SmallVectorImpl< int > &OpIndexes, Intrinsic::ID IID) const override
ValueUniformity getValueUniformity(const Value *V) const override
unsigned getNumberOfParts(Type *Tp) const override
When counting parts on AMD GPUs, account for i8s being grouped together under a single i32 value.
bool preferSLPInstCountCheck() const override
void getPeelingPreferences(Loop *L, ScalarEvolution &SE, TTI::PeelingPreferences &PP) const override
unsigned getMinVectorRegisterBitWidth() const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind Vector) const override
bool isNumRegsMajorCostOfLSR() const override
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP, OptimizationRemarkEmitter *ORE) const override
Type * getMemcpyLoopLoweringType(LLVMContext &Context, Value *Length, unsigned SrcAddrSpace, unsigned DestAddrSpace, Align SrcAlign, Align DestAlign, std::optional< uint32_t > AtomicElementSize) const override
uint64_t getMaxMemIntrinsicInlineSizeThreshold() const override
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static InstructionCost getInvalid(CostType Val=0)
CostType getValue() const
This function is intended to be used as sparingly as possible, since the class provides the full rang...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI bool hasApproxFunc() const LLVM_READONLY
Determine whether the approximate-math-functions flag is set.
user_iterator user_begin()
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI bool hasAllowContract() const LLVM_READONLY
Determine whether the allow-contract flag is set.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
const IntrinsicInst * getInst() const
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
An instruction for reading from memory.
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1081
Machine Value Type.
static LLVM_ABI MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
Root of the metadata hierarchy.
Definition Metadata.h:64
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
The optimization diagnostic interface.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
bool isFMADLegal(const SelectionDAG &DAG, const SDNode *N) const override
Returns true if be combined with to form an ISD::FMAD.
unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain targets require unusual breakdowns of certain types.
The main scalar evolution driver.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:30
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::vector< AsmOperandInfo > AsmOperandInfoVector
Primary interface to the complete machine description for the target machine.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
virtual const DataLayout & getDataLayout() const
virtual void getMemcpyLoopResidualLoweringType(SmallVectorImpl< Type * > &OpsOut, LLVMContext &Context, unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace, Align SrcAlign, Align DestAlign, std::optional< uint32_t > AtomicCpySize) const
TargetCostKind
The kind of cost model.
@ TCK_RecipThroughput
Reciprocal throughput.
@ TCK_CodeSize
Instruction code size.
@ TCK_SizeAndLatency
The weighted sum of size and latency.
@ TCK_Latency
The latency of instruction.
static bool requiresOrderedReduction(std::optional< FastMathFlags > FMF)
A helper function to determine the type of reduction algorithm used for a given Opcode and set of Fas...
llvm::VectorInstrContext VectorInstrContext
@ TCC_Free
Expected to fold away in lowering.
ShuffleKind
The various kinds of shuffle patterns for vector queries.
@ SK_InsertSubvector
InsertSubvector. Index indicates start offset.
@ SK_PermuteSingleSrc
Shuffle elements of single source vector with any shuffle mask.
@ SK_Splice
Concatenates elements from the first input vector with elements of the second input vector.
@ SK_Broadcast
Broadcast element 0 to all other elements.
@ SK_Reverse
Reverse the order of the vector.
@ SK_ExtractSubvector
ExtractSubvector Index indicates start offset.
CastContextHint
Represents a hint about the context in which a cast is used.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:339
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
Definition TypeSize.h:342
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:300
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
Definition Type.cpp:298
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:303
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
op_range operands()
Definition User.h:267
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
Base class of all SIMD vector types.
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition TypeSize.h:230
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CONSTANT_ADDRESS_32BIT
Address space for 32-bit constant memory.
@ BUFFER_STRIDED_POINTER
Address space for 192-bit fat buffer pointers with an additional index.
@ REGION_ADDRESS
Address space for region memory. (GDS)
@ LOCAL_ADDRESS
Address space for local memory.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
@ FLAT_ADDRESS
Address space for flat memory.
@ GLOBAL_ADDRESS
Address space for global memory (RAT0, VTX0).
@ BUFFER_FAT_POINTER
Address space for 160-bit buffer fat pointers.
@ PRIVATE_ADDRESS
Address space for private memory.
@ BUFFER_RESOURCE
Address space for 128-bit buffer resources.
LLVM_READNONE constexpr bool isShader(CallingConv::ID CC)
bool isFlatGlobalAddrSpace(unsigned AS)
bool isArgPassedInSGPR(const Argument *A)
bool isIntrinsicAlwaysUniform(unsigned IntrID)
bool isIntrinsicSourceOfDivergence(unsigned IntrID)
SmallVector< unsigned > getMaxNumWorkGroups(const Function &F)
bool isExtendedGlobalAddrSpace(unsigned AS)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
ISD namespace - This namespace contains an enum which represents all of the SelectionDAG node types a...
Definition ISDOpcodes.h:24
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:418
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:772
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:742
LLVM_ABI int getInstrCost()
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
specific_fpval m_FPOne()
Match a float 1.0 or vector with all elements equal to 1.0.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
auto m_FAbs(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
initializer< Ty > init(const Ty &Val)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)
Extract a Value from Metadata, allowing null.
Definition Metadata.h:694
This is an optimization pass for GlobalISel generic memory operations.
@ Length
Definition DWP.cpp:577
InstructionCost Cost
LLVM_ABI void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< EVT > *MemVTs=nullptr, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
Definition Analysis.cpp:119
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Load
The value being inserted comes from a load (InsertElement only).
LLVM_ABI MDNode * findOptionMDForLoop(const Loop *TheLoop, StringRef Name)
Find string metadata for a loop.
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
Definition STLExtras.h:2189
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1769
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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
AtomicOrdering
Atomic ordering for LLVM's memory model.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:389
@ FMul
Product of floats.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
ValueUniformity
Enum describing how values behave with respect to uniformity and divergence, to answer the question: ...
Definition Uniformity.h:18
@ AlwaysUniform
The result value is always uniform.
Definition Uniformity.h:23
@ NeverUniform
The result value can never be assumed to be uniform.
Definition Uniformity.h:26
@ Default
The result value is uniform if and only if all operands are uniform.
Definition Uniformity.h:20
@ Custom
The result value requires a custom uniformity check.
Definition Uniformity.h:31
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static constexpr DenormalMode getPreserveSign()
Extended Value Type.
Definition ValueTypes.h:35
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:408
Information about a load/store intrinsic defined by the target.
bool isInlineCompatible(SIModeRegisterDefaults CalleeMode) const
Parameters that control the generic loop unrolling transformation.
unsigned Threshold
The cost threshold for the unrolled loop.
bool UnrollVectorizedLoop
Disable runtime unrolling by default for vectorized loops.
unsigned MaxIterationsCountToAnalyze
Don't allow loop unrolling to simulate more than this number of iterations when checking full unroll ...
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...