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/TargetTransformInfo.h" 22 #include "llvm/CodeGen/BasicTTIImpl.h" 23 #include "llvm/IR/Function.h" 24 25 namespace llvm { 26 27 class RISCVTTIImpl : public BasicTTIImplBase<RISCVTTIImpl> { 28 using BaseT = BasicTTIImplBase<RISCVTTIImpl>; 29 using TTI = TargetTransformInfo; 30 31 friend BaseT; 32 33 const RISCVSubtarget *ST; 34 const RISCVTargetLowering *TLI; 35 getST()36 const RISCVSubtarget *getST() const { return ST; } getTLI()37 const RISCVTargetLowering *getTLI() const { return TLI; } 38 39 public: RISCVTTIImpl(const RISCVTargetMachine * TM,const Function & F)40 explicit RISCVTTIImpl(const RISCVTargetMachine *TM, const Function &F) 41 : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)), 42 TLI(ST->getTargetLowering()) {} 43 44 InstructionCost getIntImmCost(const APInt &Imm, Type *Ty, 45 TTI::TargetCostKind CostKind); 46 InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx, 47 const APInt &Imm, Type *Ty, 48 TTI::TargetCostKind CostKind, 49 Instruction *Inst = nullptr); 50 InstructionCost getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, 51 const APInt &Imm, Type *Ty, 52 TTI::TargetCostKind CostKind); 53 54 TargetTransformInfo::PopcntSupportKind getPopcntSupport(unsigned TyWidth); 55 56 bool shouldExpandReduction(const IntrinsicInst *II) const; supportsScalableVectors()57 bool supportsScalableVectors() const { return ST->hasStdExtV(); } 58 Optional<unsigned> getMaxVScale() const; 59 getRegisterBitWidth(TargetTransformInfo::RegisterKind K)60 TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const { 61 switch (K) { 62 case TargetTransformInfo::RGK_Scalar: 63 return TypeSize::getFixed(ST->getXLen()); 64 case TargetTransformInfo::RGK_FixedWidthVector: 65 return TypeSize::getFixed( 66 ST->hasStdExtV() ? ST->getMinRVVVectorSizeInBits() : 0); 67 case TargetTransformInfo::RGK_ScalableVector: 68 return TypeSize::getScalable( 69 ST->hasStdExtV() ? ST->getMinRVVVectorSizeInBits() : 0); 70 } 71 72 llvm_unreachable("Unsupported register kind"); 73 } 74 75 InstructionCost getGatherScatterOpCost(unsigned Opcode, Type *DataTy, 76 const Value *Ptr, bool VariableMask, 77 Align Alignment, 78 TTI::TargetCostKind CostKind, 79 const Instruction *I); 80 isLegalElementTypeForRVV(Type * ScalarTy)81 bool isLegalElementTypeForRVV(Type *ScalarTy) const { 82 if (ScalarTy->isPointerTy()) 83 return true; 84 85 if (ScalarTy->isIntegerTy(8) || ScalarTy->isIntegerTy(16) || 86 ScalarTy->isIntegerTy(32) || ScalarTy->isIntegerTy(64)) 87 return true; 88 89 if (ScalarTy->isHalfTy()) 90 return ST->hasStdExtZfh(); 91 if (ScalarTy->isFloatTy()) 92 return ST->hasStdExtF(); 93 if (ScalarTy->isDoubleTy()) 94 return ST->hasStdExtD(); 95 96 return false; 97 } 98 isLegalMaskedLoadStore(Type * DataType,Align Alignment)99 bool isLegalMaskedLoadStore(Type *DataType, Align Alignment) { 100 if (!ST->hasStdExtV()) 101 return false; 102 103 // Only support fixed vectors if we know the minimum vector size. 104 if (isa<FixedVectorType>(DataType) && ST->getMinRVVVectorSizeInBits() == 0) 105 return false; 106 107 return isLegalElementTypeForRVV(DataType->getScalarType()); 108 } 109 isLegalMaskedLoad(Type * DataType,Align Alignment)110 bool isLegalMaskedLoad(Type *DataType, Align Alignment) { 111 return isLegalMaskedLoadStore(DataType, Alignment); 112 } isLegalMaskedStore(Type * DataType,Align Alignment)113 bool isLegalMaskedStore(Type *DataType, Align Alignment) { 114 return isLegalMaskedLoadStore(DataType, Alignment); 115 } 116 isLegalMaskedGatherScatter(Type * DataType,Align Alignment)117 bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) { 118 if (!ST->hasStdExtV()) 119 return false; 120 121 // Only support fixed vectors if we know the minimum vector size. 122 if (isa<FixedVectorType>(DataType) && ST->getMinRVVVectorSizeInBits() == 0) 123 return false; 124 125 return isLegalElementTypeForRVV(DataType->getScalarType()); 126 } 127 isLegalMaskedGather(Type * DataType,Align Alignment)128 bool isLegalMaskedGather(Type *DataType, Align Alignment) { 129 return isLegalMaskedGatherScatter(DataType, Alignment); 130 } isLegalMaskedScatter(Type * DataType,Align Alignment)131 bool isLegalMaskedScatter(Type *DataType, Align Alignment) { 132 return isLegalMaskedGatherScatter(DataType, Alignment); 133 } 134 135 /// \returns How the target needs this vector-predicated operation to be 136 /// transformed. 137 TargetTransformInfo::VPLegalization getVPLegalizationStrategy(const VPIntrinsic & PI)138 getVPLegalizationStrategy(const VPIntrinsic &PI) const { 139 using VPLegalization = TargetTransformInfo::VPLegalization; 140 return VPLegalization(VPLegalization::Legal, VPLegalization::Legal); 141 } 142 isLegalToVectorizeReduction(RecurrenceDescriptor RdxDesc,ElementCount VF)143 bool isLegalToVectorizeReduction(RecurrenceDescriptor RdxDesc, 144 ElementCount VF) const { 145 if (!ST->hasStdExtV()) 146 return false; 147 148 if (!VF.isScalable()) 149 return true; 150 151 Type *Ty = RdxDesc.getRecurrenceType(); 152 if (!isLegalElementTypeForRVV(Ty)) 153 return false; 154 155 switch (RdxDesc.getRecurrenceKind()) { 156 case RecurKind::Add: 157 case RecurKind::FAdd: 158 case RecurKind::And: 159 case RecurKind::Or: 160 case RecurKind::Xor: 161 case RecurKind::SMin: 162 case RecurKind::SMax: 163 case RecurKind::UMin: 164 case RecurKind::UMax: 165 case RecurKind::FMin: 166 case RecurKind::FMax: 167 return true; 168 default: 169 return false; 170 } 171 } 172 }; 173 174 } // end namespace llvm 175 176 #endif // LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H 177