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 TargetTransformInfo::Concept 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/IVDescriptors.h" 22 #include "llvm/Analysis/TargetTransformInfo.h" 23 #include "llvm/CodeGen/BasicTTIImpl.h" 24 #include "llvm/IR/Function.h" 25 26 namespace llvm { 27 28 class RISCVTTIImpl : 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 public: 41 explicit RISCVTTIImpl(const RISCVTargetMachine *TM, const Function &F) 42 : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)), 43 TLI(ST->getTargetLowering()) {} 44 45 InstructionCost getIntImmCost(const APInt &Imm, Type *Ty, 46 TTI::TargetCostKind CostKind); 47 InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx, 48 const APInt &Imm, Type *Ty, 49 TTI::TargetCostKind CostKind, 50 Instruction *Inst = nullptr); 51 InstructionCost getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, 52 const APInt &Imm, Type *Ty, 53 TTI::TargetCostKind CostKind); 54 55 TargetTransformInfo::PopcntSupportKind getPopcntSupport(unsigned TyWidth); 56 57 bool shouldExpandReduction(const IntrinsicInst *II) const; 58 bool supportsScalableVectors() const { return ST->hasVInstructions(); } 59 Optional<unsigned> getMaxVScale() const; 60 61 TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const; 62 63 InstructionCost getRegUsageForType(Type *Ty); 64 65 void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, 66 TTI::UnrollingPreferences &UP, 67 OptimizationRemarkEmitter *ORE); 68 69 void getPeelingPreferences(Loop *L, ScalarEvolution &SE, 70 TTI::PeelingPreferences &PP); 71 72 unsigned getMinVectorRegisterBitWidth() const { 73 return ST->useRVVForFixedLengthVectors() ? 16 : 0; 74 } 75 76 InstructionCost getGatherScatterOpCost(unsigned Opcode, Type *DataTy, 77 const Value *Ptr, bool VariableMask, 78 Align Alignment, 79 TTI::TargetCostKind CostKind, 80 const Instruction *I); 81 82 bool isLegalMaskedLoadStore(Type *DataType, Align Alignment) { 83 if (!ST->hasVInstructions()) 84 return false; 85 86 // Only support fixed vectors if we know the minimum vector size. 87 if (isa<FixedVectorType>(DataType) && ST->getMinRVVVectorSizeInBits() == 0) 88 return false; 89 90 // Don't allow elements larger than the ELEN. 91 // FIXME: How to limit for scalable vectors? 92 if (isa<FixedVectorType>(DataType) && 93 DataType->getScalarSizeInBits() > ST->getMaxELENForFixedLengthVectors()) 94 return false; 95 96 if (Alignment < 97 DL.getTypeStoreSize(DataType->getScalarType()).getFixedSize()) 98 return false; 99 100 return TLI->isLegalElementTypeForRVV(DataType->getScalarType()); 101 } 102 103 bool isLegalMaskedLoad(Type *DataType, Align Alignment) { 104 return isLegalMaskedLoadStore(DataType, Alignment); 105 } 106 bool isLegalMaskedStore(Type *DataType, Align Alignment) { 107 return isLegalMaskedLoadStore(DataType, Alignment); 108 } 109 110 bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) { 111 if (!ST->hasVInstructions()) 112 return false; 113 114 // Only support fixed vectors if we know the minimum vector size. 115 if (isa<FixedVectorType>(DataType) && ST->getMinRVVVectorSizeInBits() == 0) 116 return false; 117 118 // Don't allow elements larger than the ELEN. 119 // FIXME: How to limit for scalable vectors? 120 if (isa<FixedVectorType>(DataType) && 121 DataType->getScalarSizeInBits() > ST->getMaxELENForFixedLengthVectors()) 122 return false; 123 124 if (Alignment < 125 DL.getTypeStoreSize(DataType->getScalarType()).getFixedSize()) 126 return false; 127 128 return TLI->isLegalElementTypeForRVV(DataType->getScalarType()); 129 } 130 131 bool isLegalMaskedGather(Type *DataType, Align Alignment) { 132 return isLegalMaskedGatherScatter(DataType, Alignment); 133 } 134 bool isLegalMaskedScatter(Type *DataType, Align Alignment) { 135 return isLegalMaskedGatherScatter(DataType, Alignment); 136 } 137 138 /// \returns How the target needs this vector-predicated operation to be 139 /// transformed. 140 TargetTransformInfo::VPLegalization 141 getVPLegalizationStrategy(const VPIntrinsic &PI) const { 142 using VPLegalization = TargetTransformInfo::VPLegalization; 143 return VPLegalization(VPLegalization::Legal, VPLegalization::Legal); 144 } 145 146 bool isLegalToVectorizeReduction(const RecurrenceDescriptor &RdxDesc, 147 ElementCount VF) const { 148 if (!ST->hasVInstructions()) 149 return false; 150 151 if (!VF.isScalable()) 152 return true; 153 154 Type *Ty = RdxDesc.getRecurrenceType(); 155 if (!TLI->isLegalElementTypeForRVV(Ty)) 156 return false; 157 158 switch (RdxDesc.getRecurrenceKind()) { 159 case RecurKind::Add: 160 case RecurKind::FAdd: 161 case RecurKind::And: 162 case RecurKind::Or: 163 case RecurKind::Xor: 164 case RecurKind::SMin: 165 case RecurKind::SMax: 166 case RecurKind::UMin: 167 case RecurKind::UMax: 168 case RecurKind::FMin: 169 case RecurKind::FMax: 170 return true; 171 default: 172 return false; 173 } 174 } 175 176 unsigned getMaxInterleaveFactor(unsigned VF) { 177 // If the loop will not be vectorized, don't interleave the loop. 178 // Let regular unroll to unroll the loop. 179 return VF == 1 ? 1 : ST->getMaxInterleaveFactor(); 180 } 181 182 // TODO: We should define RISC-V's own register classes. 183 // e.g. register class for FPR. 184 unsigned getNumberOfRegisters(unsigned ClassID) const { 185 bool Vector = (ClassID == 1); 186 if (Vector) { 187 if (ST->hasVInstructions()) 188 return 32; 189 return 0; 190 } 191 // 31 = 32 GPR - x0 (zero register) 192 // FIXME: Should we exclude fixed registers like SP, TP or GP? 193 return 31; 194 } 195 }; 196 197 } // end namespace llvm 198 199 #endif // LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H 200