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 36 const RISCVSubtarget *getST() const { return ST; } 37 const RISCVTargetLowering *getTLI() const { return TLI; } 38 39 public: 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 int getIntImmCost(const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind); 45 int getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm, 46 Type *Ty, TTI::TargetCostKind CostKind, 47 Instruction *Inst = nullptr); 48 int getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, 49 Type *Ty, TTI::TargetCostKind CostKind); 50 51 TargetTransformInfo::PopcntSupportKind getPopcntSupport(unsigned TyWidth); 52 53 bool shouldExpandReduction(const IntrinsicInst *II) const; 54 bool supportsScalableVectors() const { return ST->hasStdExtV(); } 55 Optional<unsigned> getMaxVScale() const; 56 57 TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const { 58 switch (K) { 59 case TargetTransformInfo::RGK_Scalar: 60 return TypeSize::getFixed(ST->getXLen()); 61 case TargetTransformInfo::RGK_FixedWidthVector: 62 return TypeSize::getFixed( 63 ST->hasStdExtV() ? ST->getMinRVVVectorSizeInBits() : 0); 64 case TargetTransformInfo::RGK_ScalableVector: 65 return TypeSize::getScalable( 66 ST->hasStdExtV() ? ST->getMinRVVVectorSizeInBits() : 0); 67 } 68 69 llvm_unreachable("Unsupported register kind"); 70 } 71 72 unsigned getGatherScatterOpCost(unsigned Opcode, Type *DataTy, 73 const Value *Ptr, bool VariableMask, 74 Align Alignment, TTI::TargetCostKind CostKind, 75 const Instruction *I); 76 77 bool isLegalElementTypeForRVV(Type *ScalarTy) { 78 if (ScalarTy->isPointerTy()) 79 return true; 80 81 if (ScalarTy->isIntegerTy(8) || ScalarTy->isIntegerTy(16) || 82 ScalarTy->isIntegerTy(32) || ScalarTy->isIntegerTy(64)) 83 return true; 84 85 if (ScalarTy->isHalfTy()) 86 return ST->hasStdExtZfh(); 87 if (ScalarTy->isFloatTy()) 88 return ST->hasStdExtF(); 89 if (ScalarTy->isDoubleTy()) 90 return ST->hasStdExtD(); 91 92 return false; 93 } 94 95 bool isLegalMaskedLoadStore(Type *DataType, Align Alignment) { 96 if (!ST->hasStdExtV()) 97 return false; 98 99 // Only support fixed vectors if we know the minimum vector size. 100 if (isa<FixedVectorType>(DataType) && ST->getMinRVVVectorSizeInBits() == 0) 101 return false; 102 103 return isLegalElementTypeForRVV(DataType->getScalarType()); 104 } 105 106 bool isLegalMaskedLoad(Type *DataType, Align Alignment) { 107 return isLegalMaskedLoadStore(DataType, Alignment); 108 } 109 bool isLegalMaskedStore(Type *DataType, Align Alignment) { 110 return isLegalMaskedLoadStore(DataType, Alignment); 111 } 112 113 bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) { 114 if (!ST->hasStdExtV()) 115 return false; 116 117 // Only support fixed vectors if we know the minimum vector size. 118 if (isa<FixedVectorType>(DataType) && ST->getMinRVVVectorSizeInBits() == 0) 119 return false; 120 121 return isLegalElementTypeForRVV(DataType->getScalarType()); 122 } 123 124 bool isLegalMaskedGather(Type *DataType, Align Alignment) { 125 return isLegalMaskedGatherScatter(DataType, Alignment); 126 } 127 bool isLegalMaskedScatter(Type *DataType, Align Alignment) { 128 return isLegalMaskedGatherScatter(DataType, Alignment); 129 } 130 }; 131 132 } // end namespace llvm 133 134 #endif // LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H 135