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 
getVectorElementType(llvm::Type * Ty)24 static llvm::Type *getVectorElementType(llvm::Type *Ty) {
25   return llvm::cast<llvm::FixedVectorType>(Ty)->getElementType();
26 }
27 
getLaneType(llvm::Type * Ty)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 
isVectorLaneType(llvm::Type & ElemTy)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 
getST()59   const VESubtarget *getST() const { return ST; }
getTLI()60   const VETargetLowering *getTLI() const { return TLI; }
61 
enableVPU()62   bool enableVPU() const { return getST()->enableVPU(); }
63 
isSupportedReduction(Intrinsic::ID ReductionID)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:
VETTIImpl(const VETargetMachine * TM,const Function & F)84   explicit VETTIImpl(const VETargetMachine *TM, const Function &F)
85       : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)),
86         TLI(ST->getTargetLowering()) {}
87 
getNumberOfRegisters(unsigned ClassID)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 
getRegisterBitWidth(TargetTransformInfo::RegisterKind K)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
getVPLegalizationStrategy(const VPIntrinsic & PI)115   getVPLegalizationStrategy(const VPIntrinsic &PI) const {
116     using VPLegalization = TargetTransformInfo::VPLegalization;
117     return VPLegalization(VPLegalization::Legal, VPLegalization::Legal);
118   }
119 
getMinVectorRegisterBitWidth()120   unsigned getMinVectorRegisterBitWidth() const {
121     // TODO report vregs once vector isel is stable.
122     return 0;
123   }
124 
shouldBuildRelLookupTables()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 {
isLegalMaskedLoad(Type * DataType,MaybeAlign Alignment)136   bool isLegalMaskedLoad(Type *DataType, MaybeAlign Alignment) {
137     return isVectorLaneType(*getLaneType(DataType));
138   }
isLegalMaskedStore(Type * DataType,MaybeAlign Alignment)139   bool isLegalMaskedStore(Type *DataType, MaybeAlign Alignment) {
140     return isVectorLaneType(*getLaneType(DataType));
141   }
isLegalMaskedGather(Type * DataType,MaybeAlign Alignment)142   bool isLegalMaskedGather(Type *DataType, MaybeAlign Alignment) {
143     return isVectorLaneType(*getLaneType(DataType));
144   };
isLegalMaskedScatter(Type * DataType,MaybeAlign Alignment)145   bool isLegalMaskedScatter(Type *DataType, MaybeAlign Alignment) {
146     return isVectorLaneType(*getLaneType(DataType));
147   }
148   // } Load & Store
149 
shouldExpandReduction(const IntrinsicInst * II)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