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 isLegalElementTypeForRVV(Type *ScalarTy) const { 87 if (ScalarTy->isPointerTy()) 88 return true; 89 90 if (ScalarTy->isIntegerTy(8) || ScalarTy->isIntegerTy(16) || 91 ScalarTy->isIntegerTy(32) || ScalarTy->isIntegerTy(64)) 92 return true; 93 94 if (ScalarTy->isHalfTy()) 95 return ST->hasStdExtZfh(); 96 if (ScalarTy->isFloatTy()) 97 return ST->hasStdExtF(); 98 if (ScalarTy->isDoubleTy()) 99 return ST->hasStdExtD(); 100 101 return false; 102 } 103 104 bool isLegalMaskedLoadStore(Type *DataType, Align Alignment) { 105 if (!ST->hasStdExtV()) 106 return false; 107 108 // Only support fixed vectors if we know the minimum vector size. 109 if (isa<FixedVectorType>(DataType) && ST->getMinRVVVectorSizeInBits() == 0) 110 return false; 111 112 // Don't allow elements larger than the ELEN. 113 // FIXME: How to limit for scalable vectors? 114 if (isa<FixedVectorType>(DataType) && 115 DataType->getScalarSizeInBits() > ST->getMaxELENForFixedLengthVectors()) 116 return false; 117 118 if (Alignment < 119 DL.getTypeStoreSize(DataType->getScalarType()).getFixedSize()) 120 return false; 121 122 return isLegalElementTypeForRVV(DataType->getScalarType()); 123 } 124 125 bool isLegalMaskedLoad(Type *DataType, Align Alignment) { 126 return isLegalMaskedLoadStore(DataType, Alignment); 127 } 128 bool isLegalMaskedStore(Type *DataType, Align Alignment) { 129 return isLegalMaskedLoadStore(DataType, Alignment); 130 } 131 132 bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) { 133 if (!ST->hasStdExtV()) 134 return false; 135 136 // Only support fixed vectors if we know the minimum vector size. 137 if (isa<FixedVectorType>(DataType) && ST->getMinRVVVectorSizeInBits() == 0) 138 return false; 139 140 // Don't allow elements larger than the ELEN. 141 // FIXME: How to limit for scalable vectors? 142 if (isa<FixedVectorType>(DataType) && 143 DataType->getScalarSizeInBits() > ST->getMaxELENForFixedLengthVectors()) 144 return false; 145 146 if (Alignment < 147 DL.getTypeStoreSize(DataType->getScalarType()).getFixedSize()) 148 return false; 149 150 return isLegalElementTypeForRVV(DataType->getScalarType()); 151 } 152 153 bool isLegalMaskedGather(Type *DataType, Align Alignment) { 154 return isLegalMaskedGatherScatter(DataType, Alignment); 155 } 156 bool isLegalMaskedScatter(Type *DataType, Align Alignment) { 157 return isLegalMaskedGatherScatter(DataType, Alignment); 158 } 159 160 /// \returns How the target needs this vector-predicated operation to be 161 /// transformed. 162 TargetTransformInfo::VPLegalization 163 getVPLegalizationStrategy(const VPIntrinsic &PI) const { 164 using VPLegalization = TargetTransformInfo::VPLegalization; 165 return VPLegalization(VPLegalization::Legal, VPLegalization::Legal); 166 } 167 168 bool isLegalToVectorizeReduction(const RecurrenceDescriptor &RdxDesc, 169 ElementCount VF) const { 170 if (!ST->hasStdExtV()) 171 return false; 172 173 if (!VF.isScalable()) 174 return true; 175 176 Type *Ty = RdxDesc.getRecurrenceType(); 177 if (!isLegalElementTypeForRVV(Ty)) 178 return false; 179 180 switch (RdxDesc.getRecurrenceKind()) { 181 case RecurKind::Add: 182 case RecurKind::FAdd: 183 case RecurKind::And: 184 case RecurKind::Or: 185 case RecurKind::Xor: 186 case RecurKind::SMin: 187 case RecurKind::SMax: 188 case RecurKind::UMin: 189 case RecurKind::UMax: 190 case RecurKind::FMin: 191 case RecurKind::FMax: 192 return true; 193 default: 194 return false; 195 } 196 } 197 198 unsigned getMaxInterleaveFactor(unsigned VF) { 199 return ST->getMaxInterleaveFactor(); 200 } 201 }; 202 203 } // end namespace llvm 204 205 #endif // LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H 206