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->hasStdExtV(); } 59 Optional<unsigned> getMaxVScale() const; 60 61 TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const { 62 switch (K) { 63 case TargetTransformInfo::RGK_Scalar: 64 return TypeSize::getFixed(ST->getXLen()); 65 case TargetTransformInfo::RGK_FixedWidthVector: 66 return TypeSize::getFixed( 67 ST->hasStdExtV() ? ST->getMinRVVVectorSizeInBits() : 0); 68 case TargetTransformInfo::RGK_ScalableVector: 69 return TypeSize::getScalable( 70 ST->hasStdExtV() ? RISCV::RVVBitsPerBlock : 0); 71 } 72 73 llvm_unreachable("Unsupported register kind"); 74 } 75 76 unsigned getMinVectorRegisterBitWidth() const { 77 return ST->hasStdExtV() ? ST->getMinRVVVectorSizeInBits() : 0; 78 } 79 80 InstructionCost getGatherScatterOpCost(unsigned Opcode, Type *DataTy, 81 const Value *Ptr, bool VariableMask, 82 Align Alignment, 83 TTI::TargetCostKind CostKind, 84 const Instruction *I); 85 86 bool isLegalMaskedLoadStore(Type *DataType, Align Alignment) { 87 if (!ST->hasStdExtV()) 88 return false; 89 90 // Only support fixed vectors if we know the minimum vector size. 91 if (isa<FixedVectorType>(DataType) && ST->getMinRVVVectorSizeInBits() == 0) 92 return false; 93 94 // Don't allow elements larger than the ELEN. 95 // FIXME: How to limit for scalable vectors? 96 if (isa<FixedVectorType>(DataType) && 97 DataType->getScalarSizeInBits() > ST->getMaxELENForFixedLengthVectors()) 98 return false; 99 100 if (Alignment < 101 DL.getTypeStoreSize(DataType->getScalarType()).getFixedSize()) 102 return false; 103 104 return TLI->isLegalElementTypeForRVV(DataType->getScalarType()); 105 } 106 107 bool isLegalMaskedLoad(Type *DataType, Align Alignment) { 108 return isLegalMaskedLoadStore(DataType, Alignment); 109 } 110 bool isLegalMaskedStore(Type *DataType, Align Alignment) { 111 return isLegalMaskedLoadStore(DataType, Alignment); 112 } 113 114 bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) { 115 if (!ST->hasStdExtV()) 116 return false; 117 118 // Only support fixed vectors if we know the minimum vector size. 119 if (isa<FixedVectorType>(DataType) && ST->getMinRVVVectorSizeInBits() == 0) 120 return false; 121 122 // Don't allow elements larger than the ELEN. 123 // FIXME: How to limit for scalable vectors? 124 if (isa<FixedVectorType>(DataType) && 125 DataType->getScalarSizeInBits() > ST->getMaxELENForFixedLengthVectors()) 126 return false; 127 128 if (Alignment < 129 DL.getTypeStoreSize(DataType->getScalarType()).getFixedSize()) 130 return false; 131 132 return TLI->isLegalElementTypeForRVV(DataType->getScalarType()); 133 } 134 135 bool isLegalMaskedGather(Type *DataType, Align Alignment) { 136 return isLegalMaskedGatherScatter(DataType, Alignment); 137 } 138 bool isLegalMaskedScatter(Type *DataType, Align Alignment) { 139 return isLegalMaskedGatherScatter(DataType, Alignment); 140 } 141 142 /// \returns How the target needs this vector-predicated operation to be 143 /// transformed. 144 TargetTransformInfo::VPLegalization 145 getVPLegalizationStrategy(const VPIntrinsic &PI) const { 146 using VPLegalization = TargetTransformInfo::VPLegalization; 147 return VPLegalization(VPLegalization::Legal, VPLegalization::Legal); 148 } 149 150 bool isLegalToVectorizeReduction(const RecurrenceDescriptor &RdxDesc, 151 ElementCount VF) const { 152 if (!ST->hasStdExtV()) 153 return false; 154 155 if (!VF.isScalable()) 156 return true; 157 158 Type *Ty = RdxDesc.getRecurrenceType(); 159 if (!TLI->isLegalElementTypeForRVV(Ty)) 160 return false; 161 162 switch (RdxDesc.getRecurrenceKind()) { 163 case RecurKind::Add: 164 case RecurKind::FAdd: 165 case RecurKind::And: 166 case RecurKind::Or: 167 case RecurKind::Xor: 168 case RecurKind::SMin: 169 case RecurKind::SMax: 170 case RecurKind::UMin: 171 case RecurKind::UMax: 172 case RecurKind::FMin: 173 case RecurKind::FMax: 174 return true; 175 default: 176 return false; 177 } 178 } 179 180 unsigned getMaxInterleaveFactor(unsigned VF) { 181 return ST->getMaxInterleaveFactor(); 182 } 183 }; 184 185 } // end namespace llvm 186 187 #endif // LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H 188