1 //===- VETargetTransformInfo.h - VE 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 a TargetTransformInfo::Concept conforming object specific to the 10 /// VE 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_VE_VETARGETTRANSFORMINFO_H 17 #define LLVM_LIB_TARGET_VE_VETARGETTRANSFORMINFO_H 18 19 #include "VE.h" 20 #include "VETargetMachine.h" 21 #include "llvm/Analysis/TargetTransformInfo.h" 22 #include "llvm/CodeGen/BasicTTIImpl.h" 23 24 static llvm::Type *getVectorElementType(llvm::Type *Ty) { 25 return llvm::cast<llvm::FixedVectorType>(Ty)->getElementType(); 26 } 27 28 static llvm::Type *getLaneType(llvm::Type *Ty) { 29 using namespace llvm; 30 if (!isa<VectorType>(Ty)) 31 return Ty; 32 return getVectorElementType(Ty); 33 } 34 35 static bool isVectorLaneType(llvm::Type &ElemTy) { 36 // check element sizes for vregs 37 if (ElemTy.isIntegerTy()) { 38 unsigned ScaBits = ElemTy.getScalarSizeInBits(); 39 return ScaBits == 1 || ScaBits == 32 || ScaBits == 64; 40 } 41 if (ElemTy.isPointerTy()) { 42 return true; 43 } 44 if (ElemTy.isFloatTy() || ElemTy.isDoubleTy()) { 45 return true; 46 } 47 return false; 48 } 49 50 namespace llvm { 51 52 class VETTIImpl : public BasicTTIImplBase<VETTIImpl> { 53 using BaseT = BasicTTIImplBase<VETTIImpl>; 54 friend BaseT; 55 56 const VESubtarget *ST; 57 const VETargetLowering *TLI; 58 59 const VESubtarget *getST() const { return ST; } 60 const VETargetLowering *getTLI() const { return TLI; } 61 62 bool enableVPU() const { return getST()->enableVPU(); } 63 64 static bool isSupportedReduction(Intrinsic::ID ReductionID) { 65 #define VEC_VP_CASE(SUFFIX) \ 66 case Intrinsic::vp_reduce_##SUFFIX: \ 67 case Intrinsic::vector_reduce_##SUFFIX: 68 69 switch (ReductionID) { 70 VEC_VP_CASE(add) 71 VEC_VP_CASE(and) 72 VEC_VP_CASE(or) 73 VEC_VP_CASE(xor) 74 VEC_VP_CASE(smax) 75 return true; 76 77 default: 78 return false; 79 } 80 #undef VEC_VP_CASE 81 } 82 83 public: 84 explicit VETTIImpl(const VETargetMachine *TM, const Function &F) 85 : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)), 86 TLI(ST->getTargetLowering()) {} 87 88 unsigned getNumberOfRegisters(unsigned ClassID) const { 89 bool VectorRegs = (ClassID == 1); 90 if (VectorRegs) { 91 // TODO report vregs once vector isel is stable. 92 return 0; 93 } 94 95 return 64; 96 } 97 98 TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const { 99 switch (K) { 100 case TargetTransformInfo::RGK_Scalar: 101 return TypeSize::getFixed(64); 102 case TargetTransformInfo::RGK_FixedWidthVector: 103 // TODO report vregs once vector isel is stable. 104 return TypeSize::getFixed(0); 105 case TargetTransformInfo::RGK_ScalableVector: 106 return TypeSize::getScalable(0); 107 } 108 109 llvm_unreachable("Unsupported register kind"); 110 } 111 112 /// \returns How the target needs this vector-predicated operation to be 113 /// transformed. 114 TargetTransformInfo::VPLegalization 115 getVPLegalizationStrategy(const VPIntrinsic &PI) const { 116 using VPLegalization = TargetTransformInfo::VPLegalization; 117 return VPLegalization(VPLegalization::Legal, VPLegalization::Legal); 118 } 119 120 unsigned getMinVectorRegisterBitWidth() const { 121 // TODO report vregs once vector isel is stable. 122 return 0; 123 } 124 125 bool shouldBuildRelLookupTables() const { 126 // NEC nld doesn't support relative lookup tables. It shows following 127 // errors. So, we disable it at the moment. 128 // /opt/nec/ve/bin/nld: src/CMakeFiles/cxxabi_shared.dir/cxa_demangle.cpp 129 // .o(.rodata+0x17b4): reloc against `.L.str.376': error 2 130 // /opt/nec/ve/bin/nld: final link failed: Nonrepresentable section on 131 // output 132 return false; 133 } 134 135 // Load & Store { 136 bool isLegalMaskedLoad(Type *DataType, MaybeAlign Alignment) { 137 return isVectorLaneType(*getLaneType(DataType)); 138 } 139 bool isLegalMaskedStore(Type *DataType, MaybeAlign Alignment) { 140 return isVectorLaneType(*getLaneType(DataType)); 141 } 142 bool isLegalMaskedGather(Type *DataType, MaybeAlign Alignment) { 143 return isVectorLaneType(*getLaneType(DataType)); 144 }; 145 bool isLegalMaskedScatter(Type *DataType, MaybeAlign Alignment) { 146 return isVectorLaneType(*getLaneType(DataType)); 147 } 148 // } Load & Store 149 150 bool shouldExpandReduction(const IntrinsicInst *II) const { 151 if (!enableVPU()) 152 return true; 153 return !isSupportedReduction(II->getIntrinsicID()); 154 } 155 }; 156 157 } // namespace llvm 158 159 #endif // LLVM_LIB_TARGET_VE_VETARGETTRANSFORMINFO_H 160