1//===- RISCVTargetTransformInfo.h - RISC-V specific TTI ---------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file defines a TargetTransformInfoImplBase conforming object specific
10/// to the RISC-V target machine. It uses the target's detailed information to
11/// provide more precise answers to certain TTI queries, while letting the
12/// target independent and default TTI implementations handle the rest.
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H
17#define LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H
18
19#include "RISCVSubtarget.h"
20#include "RISCVTargetMachine.h"
21#include "llvm/Analysis/TargetTransformInfo.h"
22#include "llvm/CodeGen/BasicTTIImpl.h"
23#include "llvm/IR/Function.h"
24#include <optional>
25
26namespace llvm {
27
28class RISCVTTIImpl final : public BasicTTIImplBase<RISCVTTIImpl> {
29 using BaseT = BasicTTIImplBase<RISCVTTIImpl>;
30 using TTI = TargetTransformInfo;
31
32 friend BaseT;
33
34 const RISCVSubtarget *ST;
35 const RISCVTargetLowering *TLI;
36
37 const RISCVSubtarget *getST() const { return ST; }
38 const RISCVTargetLowering *getTLI() const { return TLI; }
39
40 /// This function returns an estimate for VL to be used in VL based terms
41 /// of the cost model. For fixed length vectors, this is simply the
42 /// vector length. For scalable vectors, we return results consistent
43 /// with getVScaleForTuning under the assumption that clients are also
44 /// using that when comparing costs between scalar and vector representation.
45 /// This does unfortunately mean that we can both undershoot and overshot
46 /// the true cost significantly if getVScaleForTuning is wildly off for the
47 /// actual target hardware.
48 unsigned getEstimatedVLFor(VectorType *Ty) const;
49
50 /// This function calculates the costs for one or more RVV opcodes based
51 /// on the vtype and the cost kind.
52 /// \param Opcodes A list of opcodes of the RVV instruction to evaluate.
53 /// \param VT The MVT of vtype associated with the RVV instructions.
54 /// For widening/narrowing instructions where the result and source types
55 /// differ, it is important to check the spec to determine whether the vtype
56 /// refers to the result or source type.
57 /// \param CostKind The type of cost to compute.
58 InstructionCost getRISCVInstructionCost(ArrayRef<unsigned> OpCodes, MVT VT,
59 TTI::TargetCostKind CostKind) const;
60
61 // Return the cost of generating a PC relative address
62 InstructionCost
63 getStaticDataAddrGenerationCost(const TTI::TargetCostKind CostKind) const;
64
65 /// Return the cost of accessing a constant pool entry of the specified
66 /// type.
67 InstructionCost getConstantPoolLoadCost(Type *Ty,
68 TTI::TargetCostKind CostKind) const;
69
70 /// If this shuffle can be lowered as a masked slide pair (at worst),
71 /// return a cost for it.
72 InstructionCost getSlideCost(FixedVectorType *Tp, ArrayRef<int> Mask,
73 TTI::TargetCostKind CostKind) const;
74
75 /// Return the type used to cost vzip.vv, whose LMUL represents the
76 /// interleaved destination EMUL. Return std::nullopt if illegal.
77 std::optional<MVT> getZvzipVZIPCostVT(MVT InterleavedVT) const;
78
79 /// Return the type used to cost vunzipe.v/vunzipo.v, whose LMUL represents
80 /// the interleaved source EMUL. Return std::nullopt if illegal.
81 std::optional<MVT> getZvzipVUNZIPCostVT(MVT InterleavedVT) const;
82
83public:
84 explicit RISCVTTIImpl(const RISCVTargetMachine *TM, const Function &F)
85 : BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl(F)),
86 TLI(ST->getTargetLowering()) {}
87
88 /// Return the cost of materializing an immediate for a value operand of
89 /// a store instruction.
90 InstructionCost getStoreImmCost(Type *VecTy, TTI::OperandValueInfo OpInfo,
91 TTI::TargetCostKind CostKind) const;
92
93 InstructionCost getIntImmCost(const APInt &Imm, Type *Ty,
94 TTI::TargetCostKind CostKind) const override;
95 InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx,
96 const APInt &Imm, Type *Ty,
97 TTI::TargetCostKind CostKind,
98 Instruction *Inst = nullptr) const override;
99 InstructionCost
100 getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
101 Type *Ty, TTI::TargetCostKind CostKind) const override;
102
103 /// \name EVL Support for predicated vectorization.
104 /// Whether the target supports the %evl parameter of VP intrinsic efficiently
105 /// in hardware. (see LLVM Language Reference - "Vector Predication
106 /// Intrinsics",
107 /// https://llvm.org/docs/LangRef.html#vector-predication-intrinsics and
108 /// "IR-level VP intrinsics",
109 /// https://llvm.org/docs/Proposals/VectorPredication.html#ir-level-vp-intrinsics).
110 bool hasActiveVectorLength() const override;
111
112 TargetTransformInfo::PopcntSupportKind
113 getPopcntSupport(unsigned TyWidth) const override;
114
115 InstructionCost getPartialReductionCost(
116 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
117 ElementCount VF, TTI::PartialReductionExtendKind OpAExtend,
118 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
119 TTI::TargetCostKind CostKind,
120 std::optional<FastMathFlags> FMF) const override;
121
122 bool shouldExpandReduction(const IntrinsicInst *II) const override;
123 bool supportsScalableVectors() const override {
124 // VLEN=32 support is incomplete.
125 return ST->hasVInstructions() &&
126 (ST->getRealMinVLen() >= RISCV::RVVBitsPerBlock);
127 }
128 bool enableOrderedReductions() const override { return true; }
129 bool enableScalableVectorization() const override {
130 return ST->hasVInstructions();
131 }
132 bool preferTailFoldingOverEpilogue(TailFoldingInfo *TFI) const override {
133 return ST->hasVInstructions();
134 }
135 TailFoldingStyle getPreferredTailFoldingStyle() const override {
136 return ST->hasVInstructions() ? TailFoldingStyle::DataWithEVL
137 : TailFoldingStyle::None;
138 }
139 std::optional<unsigned> getVScaleForTuning() const override;
140
141 TypeSize
142 getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override;
143
144 unsigned getRegUsageForType(Type *Ty) const override;
145
146 unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const override;
147
148 bool preferAlternateOpcodeVectorization() const override;
149
150 bool preferEpilogueVectorization(ElementCount Iters) const override {
151 // Epilogue vectorization is usually unprofitable - tail folding or
152 // a smaller VF would have been better. This a blunt hammer - we
153 // should re-examine this once vectorization is better tuned.
154 return false;
155 }
156
157 bool shouldConsiderVectorizationRegPressure() const override { return true; }
158
159 InstructionCost
160 getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA,
161 TTI::TargetCostKind CostKind) const override;
162
163 InstructionCost getMaskedMemoryOpCost(const MemIntrinsicCostAttributes &MICA,
164 TTI::TargetCostKind CostKind) const;
165
166 InstructionCost
167 getPointersChainCost(ArrayRef<const Value *> Ptrs, const Value *Base,
168 const TTI::PointersChainInfo &Info, Type *AccessTy,
169 const TTI::TargetCostKind CostKind) const override;
170
171 void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
172 TTI::UnrollingPreferences &UP,
173 OptimizationRemarkEmitter *ORE) const override;
174
175 void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
176 TTI::PeelingPreferences &PP) const override;
177
178 bool getTgtMemIntrinsic(IntrinsicInst *Inst,
179 MemIntrinsicInfo &Info) const override;
180
181 unsigned getMinVectorRegisterBitWidth() const override {
182 return ST->useRVVForFixedLengthVectors() ? 16 : 0;
183 }
184
185 InstructionCost
186 getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,
187 TTI::TargetCostKind CostKind, ArrayRef<int> Mask, int Index,
188 VectorType *SubTp, ArrayRef<const Value *> Args = {},
189 const Instruction *CtxI = nullptr,
190 TTI::VectorInstrContext VIC =
191 TTI::VectorInstrContext::None) const override;
192
193 InstructionCost
194 getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts,
195 bool Insert, bool Extract,
196 TTI::TargetCostKind CostKind,
197 bool ForPoisonSrc = true, ArrayRef<Value *> VL = {},
198 TTI::VectorInstrContext VIC =
199 TTI::VectorInstrContext::None) const override;
200
201 InstructionCost
202 getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
203 TTI::TargetCostKind CostKind) const override;
204
205 InstructionCost
206 getAddressComputationCost(Type *PTy, ScalarEvolution *SE, const SCEV *Ptr,
207 TTI::TargetCostKind CostKind) const override;
208
209 InstructionCost getInterleavedMemoryOpCost(
210 unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
211 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
212 bool UseMaskForCond = false, bool UseMaskForGaps = false) const override;
213
214 InstructionCost getGatherScatterOpCost(const MemIntrinsicCostAttributes &MICA,
215 TTI::TargetCostKind CostKind) const;
216
217 InstructionCost
218 getExpandCompressMemoryOpCost(const MemIntrinsicCostAttributes &MICA,
219 TTI::TargetCostKind CostKind) const;
220
221 InstructionCost getStridedMemoryOpCost(const MemIntrinsicCostAttributes &MICA,
222 TTI::TargetCostKind CostKind) const;
223
224 InstructionCost
225 getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const override;
226
227 InstructionCost
228 getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
229 TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
230 const Instruction *I = nullptr) const override;
231
232 InstructionCost
233 getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF,
234 TTI::TargetCostKind CostKind) const override;
235
236 std::optional<InstructionCost> getCombinedArithmeticInstructionCost(
237 unsigned ISDOpcode, Type *Ty, TTI::TargetCostKind CostKind,
238 TTI::OperandValueInfo Opd1Info, TTI::OperandValueInfo Opd2Info,
239 ArrayRef<const Value *> Args, const Instruction *CtxI) const;
240
241 InstructionCost
242 getArithmeticReductionCost(unsigned Opcode, VectorType *Ty,
243 std::optional<FastMathFlags> FMF,
244 TTI::TargetCostKind CostKind) const override;
245
246 InstructionCost
247 getExtendedReductionCost(unsigned Opcode, bool IsUnsigned, Type *ResTy,
248 VectorType *ValTy, std::optional<FastMathFlags> FMF,
249 TTI::TargetCostKind CostKind) const override;
250
251 InstructionCost getMemoryOpCost(
252 unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
253 TTI::TargetCostKind CostKind,
254 TTI::OperandValueInfo OpdInfo = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
255 const Instruction *I = nullptr) const override;
256
257 InstructionCost getCmpSelInstrCost(
258 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
259 TTI::TargetCostKind CostKind,
260 TTI::OperandValueInfo Op1Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
261 TTI::OperandValueInfo Op2Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
262 const Instruction *I = nullptr) const override;
263
264 InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,
265 const Instruction *I = nullptr) const override;
266
267 using BaseT::getVectorInstrCost;
268 InstructionCost
269 getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind,
270 unsigned Index, const Value *Op0, const Value *Op1,
271 TTI::VectorInstrContext VIC =
272 TTI::VectorInstrContext::None) const override;
273
274 InstructionCost
275 getIndexedVectorInstrCostFromEnd(unsigned Opcode, Type *Val,
276 TTI::TargetCostKind CostKind,
277 unsigned Index) const override;
278
279 InstructionCost getArithmeticInstrCost(
280 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
281 TTI::OperandValueInfo Op1Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
282 TTI::OperandValueInfo Op2Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
283 ArrayRef<const Value *> Args = {},
284 const Instruction *CtxI = nullptr) const override;
285
286 bool isElementTypeLegalForScalableVector(Type *Ty) const override {
287 return TLI->isLegalElementTypeForRVV(ScalarTy: TLI->getValueType(DL, Ty));
288 }
289
290 bool isLegalMaskedLoadStore(Type *DataType, Align Alignment) const {
291 if (!ST->hasVInstructions())
292 return false;
293
294 EVT DataTypeVT = TLI->getValueType(DL, Ty: DataType);
295
296 // Only support fixed vectors if we know the minimum vector size.
297 if (DataTypeVT.isFixedLengthVector() && !ST->useRVVForFixedLengthVectors())
298 return false;
299
300 EVT ElemType = DataTypeVT.getScalarType();
301 if (!ST->enableUnalignedVectorMem() && Alignment < ElemType.getStoreSize())
302 return false;
303
304 return TLI->isLegalElementTypeForRVV(ScalarTy: ElemType);
305 }
306
307 bool isLegalMaskedLoad(Type *DataType, Align Alignment,
308 unsigned /*AddressSpace*/,
309 TTI::MaskKind /*MaskKind*/) const override {
310 return isLegalMaskedLoadStore(DataType, Alignment);
311 }
312 bool isLegalMaskedStore(Type *DataType, Align Alignment,
313 unsigned /*AddressSpace*/,
314 TTI::MaskKind /*MaskKind*/) const override {
315 return isLegalMaskedLoadStore(DataType, Alignment);
316 }
317
318 bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) const {
319 if (!ST->hasVInstructions())
320 return false;
321
322 EVT DataTypeVT = TLI->getValueType(DL, Ty: DataType);
323
324 // Only support fixed vectors if we know the minimum vector size.
325 if (DataTypeVT.isFixedLengthVector() && !ST->useRVVForFixedLengthVectors())
326 return false;
327
328 // We also need to check if the vector of address is valid.
329 EVT PointerTypeVT = EVT(TLI->getPointerTy(DL));
330 if (DataTypeVT.isScalableVector() &&
331 !TLI->isLegalElementTypeForRVV(ScalarTy: PointerTypeVT))
332 return false;
333
334 EVT ElemType = DataTypeVT.getScalarType();
335 if (!ST->enableUnalignedVectorMem() && Alignment < ElemType.getStoreSize())
336 return false;
337
338 return TLI->isLegalElementTypeForRVV(ScalarTy: ElemType);
339 }
340
341 bool isLegalMaskedGather(Type *DataType, Align Alignment) const override {
342 return isLegalMaskedGatherScatter(DataType, Alignment);
343 }
344 bool isLegalMaskedScatter(Type *DataType, Align Alignment) const override {
345 return isLegalMaskedGatherScatter(DataType, Alignment);
346 }
347
348 bool forceScalarizeMaskedGather(VectorType *VTy,
349 Align Alignment) const override {
350 // Scalarize masked gather for RV64 if EEW=64 indices aren't supported.
351 return ST->is64Bit() && !ST->hasVInstructionsI64();
352 }
353
354 bool forceScalarizeMaskedScatter(VectorType *VTy,
355 Align Alignment) const override {
356 // Scalarize masked scatter for RV64 if EEW=64 indices aren't supported.
357 return ST->is64Bit() && !ST->hasVInstructionsI64();
358 }
359
360 bool isLegalStridedLoadStore(Type *DataType, Align Alignment) const override {
361 EVT DataTypeVT = TLI->getValueType(DL, Ty: DataType);
362 return TLI->isLegalStridedLoadStore(DataType: DataTypeVT, Alignment);
363 }
364
365 bool isLegalInterleavedAccessType(VectorType *VTy, unsigned Factor,
366 Align Alignment,
367 unsigned AddrSpace) const override {
368 return TLI->isLegalInterleavedAccessType(VTy, Factor, Alignment, AddrSpace,
369 DL);
370 }
371
372 bool isLegalMaskedExpandLoad(Type *DataType, Align Alignment) const override;
373
374 bool isLegalMaskedCompressStore(Type *DataTy, Align Alignment) const override;
375
376 bool isLegalBroadcastLoad(Type *ElementTy,
377 ElementCount NumElements) const override;
378
379 /// \returns How the target needs this vector-predicated operation to be
380 /// transformed.
381 TargetTransformInfo::VPLegalization
382 getVPLegalizationStrategy(const VPIntrinsic &PI) const override {
383 using VPLegalization = TargetTransformInfo::VPLegalization;
384 static const Intrinsic::ID Supported[] = {
385 Intrinsic::experimental_vp_strided_load,
386 Intrinsic::experimental_vp_strided_store,
387 Intrinsic::experimental_vp_reverse,
388 Intrinsic::experimental_vp_splice,
389 Intrinsic::vp_cttz_elts,
390 Intrinsic::vp_gather,
391 Intrinsic::vp_load,
392 Intrinsic::vp_load_ff,
393 Intrinsic::vp_merge,
394 Intrinsic::vp_reduce_add,
395 Intrinsic::vp_reduce_and,
396 Intrinsic::vp_reduce_fadd,
397 Intrinsic::vp_reduce_fmax,
398 Intrinsic::vp_reduce_fmaximum,
399 Intrinsic::vp_reduce_fmin,
400 Intrinsic::vp_reduce_fminimum,
401 Intrinsic::vp_reduce_fmul,
402 Intrinsic::vp_reduce_mul,
403 Intrinsic::vp_reduce_or,
404 Intrinsic::vp_reduce_smax,
405 Intrinsic::vp_reduce_smin,
406 Intrinsic::vp_reduce_umax,
407 Intrinsic::vp_reduce_umin,
408 Intrinsic::vp_reduce_xor,
409 Intrinsic::vp_scatter,
410 Intrinsic::vp_sdiv,
411 Intrinsic::vp_srem,
412 Intrinsic::vp_store,
413 Intrinsic::vp_udiv,
414 Intrinsic::vp_urem};
415 if (!ST->hasVInstructions() ||
416 (PI.getIntrinsicID() == Intrinsic::vp_reduce_mul &&
417 cast<VectorType>(Val: PI.getArgOperand(i: 1)->getType())
418 ->getElementType()
419 ->getIntegerBitWidth() != 1) ||
420 !is_contained(Range: Supported, Element: PI.getIntrinsicID()))
421 return VPLegalization(VPLegalization::Discard, VPLegalization::Convert);
422 return VPLegalization(VPLegalization::Legal, VPLegalization::Legal);
423 }
424
425 bool isLegalToVectorizeReduction(const RecurrenceDescriptor &RdxDesc,
426 ElementCount VF) const override {
427 if (!VF.isScalable())
428 return true;
429
430 Type *Ty = RdxDesc.getRecurrenceType();
431 if (!TLI->isLegalElementTypeForRVV(ScalarTy: TLI->getValueType(DL, Ty)))
432 return false;
433
434 switch (RdxDesc.getRecurrenceKind()) {
435 case RecurKind::Add:
436 case RecurKind::Sub:
437 case RecurKind::AddChainWithSubs:
438 case RecurKind::And:
439 case RecurKind::Or:
440 case RecurKind::Xor:
441 case RecurKind::SMin:
442 case RecurKind::SMax:
443 case RecurKind::UMin:
444 case RecurKind::UMax:
445 case RecurKind::FMin:
446 case RecurKind::FMax:
447 case RecurKind::FindIV:
448 case RecurKind::FindLast:
449 return true;
450 case RecurKind::AnyOf:
451 case RecurKind::FAdd:
452 case RecurKind::FSub:
453 case RecurKind::FMulAdd:
454 // We can't promote f16/bf16 fadd reductions and scalable vectors can't be
455 // expanded.
456 if (Ty->isBFloatTy() || (Ty->isHalfTy() && !ST->hasVInstructionsF16()))
457 return false;
458 return true;
459 case RecurKind::Mul:
460 case RecurKind::FMul:
461 case RecurKind::FMinNum:
462 case RecurKind::FMaxNum:
463 case RecurKind::FMinimum:
464 case RecurKind::FMaximum:
465 case RecurKind::FMinimumNum:
466 case RecurKind::FMaximumNum:
467 case RecurKind::FAddChainWithSubs:
468 return false;
469 case RecurKind::None:
470 llvm_unreachable("Unknown reduction kind.");
471 }
472 }
473
474 unsigned getMaxInterleaveFactor(ElementCount VF,
475 bool HasUnorderedReductions) const override {
476 // Don't interleave if the loop has been vectorized with scalable vectors.
477 if (VF.isScalable())
478 return 1;
479 // If the loop will not be vectorized, don't interleave the loop.
480 // Let regular unroll to unroll the loop.
481 return VF.isScalar() ? 1 : ST->getMaxInterleaveFactor();
482 }
483
484 bool enableInterleavedAccessVectorization() const override { return true; }
485
486 bool enableMaskedInterleavedAccessVectorization() const override {
487 return ST->hasVInstructions();
488 }
489
490 unsigned getMinTripCountTailFoldingThreshold() const override;
491
492 enum RISCVRegisterClass { GPRRC, FPRRC, VRRC };
493 unsigned getNumberOfRegisters(unsigned ClassID) const override {
494 switch (ClassID) {
495 case RISCVRegisterClass::GPRRC:
496 // 31 = 32 GPR - x0 (zero register)
497 // FIXME: Should we exclude fixed registers like SP, TP or GP?
498 return 31;
499 case RISCVRegisterClass::FPRRC:
500 if (ST->hasStdExtF())
501 return 32;
502 return 0;
503 case RISCVRegisterClass::VRRC:
504 // Although there are 32 vector registers, v0 is special in that it is the
505 // only register that can be used to hold a mask.
506 // FIXME: Should we conservatively return 31 as the number of usable
507 // vector registers?
508 return ST->hasVInstructions() ? 32 : 0;
509 }
510 llvm_unreachable("unknown register class");
511 }
512
513 TTI::AddressingModeKind
514 getPreferredAddressingMode(const Loop *L, ScalarEvolution *SE) const override;
515
516 unsigned getRegisterClassForType(bool Vector,
517 Type *Ty = nullptr) const override {
518 if (Vector)
519 return RISCVRegisterClass::VRRC;
520 if (!Ty)
521 return RISCVRegisterClass::GPRRC;
522
523 Type *ScalarTy = Ty->getScalarType();
524 if ((ScalarTy->isHalfTy() && ST->hasStdExtZfhmin()) ||
525 (ScalarTy->isFloatTy() && ST->hasStdExtF()) ||
526 (ScalarTy->isDoubleTy() && ST->hasStdExtD())) {
527 return RISCVRegisterClass::FPRRC;
528 }
529
530 return RISCVRegisterClass::GPRRC;
531 }
532
533 const char *getRegisterClassName(unsigned ClassID) const override {
534 switch (ClassID) {
535 case RISCVRegisterClass::GPRRC:
536 return "RISCV::GPRRC";
537 case RISCVRegisterClass::FPRRC:
538 return "RISCV::FPRRC";
539 case RISCVRegisterClass::VRRC:
540 return "RISCV::VRRC";
541 }
542 llvm_unreachable("unknown register class");
543 }
544
545 bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
546 const TargetTransformInfo::LSRCost &C2) const override;
547
548 bool shouldConsiderAddressTypePromotion(
549 const Instruction &I,
550 bool &AllowPromotionWithoutCommonHeader) const override;
551 std::optional<unsigned> getMinPageSize() const override { return 4096; }
552 /// Return true if the (vector) instruction I will be lowered to an
553 /// instruction with a scalar splat operand for the given Operand number.
554 bool canSplatOperand(Instruction *I, int Operand) const;
555 /// Return true if a vector instruction will lower to a target instruction
556 /// able to splat the given operand.
557 bool canSplatOperand(unsigned Opcode, int Operand) const;
558
559 TargetTransformInfo::VectorInstrContext getBuildVectorContextHint(
560 ArrayRef<int> Mask, ArrayRef<Value *> Scalars,
561 function_ref<
562 bool(SmallVectorImpl<TargetTransformInfo::BuildVectorUseOp> &)>
563 GatherUseOps) const override;
564
565 bool isProfitableToSinkOperands(Instruction *I,
566 SmallVectorImpl<Use *> &Ops) const override;
567
568 TTI::MemCmpExpansionOptions
569 enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const override;
570
571 bool enableSelectOptimize() const override {
572 return ST->enableSelectOptimize();
573 }
574
575 bool shouldTreatInstructionLikeSelect(const Instruction *I) const override;
576
577 bool
578 shouldCopyAttributeWhenOutliningFrom(const Function *Caller,
579 const Attribute &Attr) const override;
580
581 std::optional<Instruction *>
582 instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const override;
583};
584
585} // end namespace llvm
586
587#endif // LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H
588