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>(Val: Ty)->getElementType(); |
26 | } |
27 | |
28 | static llvm::Type *getLaneType(llvm::Type *Ty) { |
29 | using namespace llvm; |
30 | if (!isa<VectorType>(Val: 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.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(ExactSize: 64); |
102 | case TargetTransformInfo::RGK_FixedWidthVector: |
103 | // TODO report vregs once vector isel is stable. |
104 | return TypeSize::getFixed(ExactSize: 0); |
105 | case TargetTransformInfo::RGK_ScalableVector: |
106 | return TypeSize::getScalable(MinimumSize: 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(ElemTy&: *getLaneType(Ty: DataType)); |
138 | } |
139 | bool isLegalMaskedStore(Type *DataType, MaybeAlign Alignment) { |
140 | return isVectorLaneType(ElemTy&: *getLaneType(Ty: DataType)); |
141 | } |
142 | bool isLegalMaskedGather(Type *DataType, MaybeAlign Alignment) { |
143 | return isVectorLaneType(ElemTy&: *getLaneType(Ty: DataType)); |
144 | }; |
145 | bool isLegalMaskedScatter(Type *DataType, MaybeAlign Alignment) { |
146 | return isVectorLaneType(ElemTy&: *getLaneType(Ty: DataType)); |
147 | } |
148 | // } Load & Store |
149 | |
150 | bool shouldExpandReduction(const IntrinsicInst *II) const { |
151 | if (!enableVPU()) |
152 | return true; |
153 | return !isSupportedReduction(ReductionID: II->getIntrinsicID()); |
154 | } |
155 | }; |
156 | |
157 | } // namespace llvm |
158 | |
159 | #endif // LLVM_LIB_TARGET_VE_VETARGETTRANSFORMINFO_H |
160 | |