1 //===------------ VECustomDAG.h - VE Custom DAG Nodes -----------*- 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 // 9 // This file defines the helper functions that VE uses to lower LLVM code into a 10 // selection DAG. For example, hiding SDLoc, and easy to use SDNodeFlags. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_TARGET_VE_VECUSTOMDAG_H 15 #define LLVM_LIB_TARGET_VE_VECUSTOMDAG_H 16 17 #include "VE.h" 18 #include "VEISelLowering.h" 19 #include "llvm/CodeGen/SelectionDAG.h" 20 #include "llvm/CodeGen/TargetLowering.h" 21 22 namespace llvm { 23 24 std::optional<unsigned> getVVPOpcode(unsigned Opcode); 25 26 bool isVVPUnaryOp(unsigned Opcode); 27 bool isVVPBinaryOp(unsigned Opcode); 28 bool isVVPReductionOp(unsigned Opcode); 29 30 MVT splitVectorType(MVT VT); 31 32 bool isPackedVectorType(EVT SomeVT); 33 34 bool isMaskType(EVT SomeVT); 35 36 bool isMaskArithmetic(SDValue Op); 37 38 bool isVVPOrVEC(unsigned); 39 40 bool supportsPackedMode(unsigned Opcode, EVT IdiomVT); 41 42 bool isPackingSupportOpcode(unsigned Opc); 43 44 bool maySafelyIgnoreMask(SDValue Op); 45 46 /// The VE backend uses a two-staged process to lower and legalize vector 47 /// instructions: 48 // 49 /// 1. VP and standard vector SDNodes are lowered to SDNodes of the VVP_* layer. 50 // 51 // All VVP nodes have a mask and an Active Vector Length (AVL) parameter. 52 // The AVL parameters refers to the element position in the vector the VVP 53 // node operates on. 54 // 55 // 56 // 2. The VVP SDNodes are legalized. The AVL in a legal VVP node refers to 57 // chunks of 64bit. We track this by wrapping the AVL in a LEGALAVL node. 58 // 59 // The AVL mechanism in the VE architecture always refers to chunks of 60 // 64bit, regardless of the actual element type vector instructions are 61 // operating on. For vector types v256.32 or v256.64 nothing needs to be 62 // legalized since each element occupies a 64bit chunk - there is no 63 // difference between counting 64bit chunks or element positions. However, 64 // all vector types with > 256 elements store more than one logical element 65 // per 64bit chunk and need to be transformed. 66 // However legalization is performed, the resulting legal VVP SDNodes will 67 // have a LEGALAVL node as their AVL operand. The LEGALAVL nodes wraps 68 // around an AVL that refers to 64 bit chunks just as the architecture 69 // demands - that is, the wrapped AVL is the correct setting for the VL 70 // register for this VVP operation to get the desired behavior. 71 // 72 /// AVL Functions { 73 // The AVL operand position of this node. 74 std::optional<int> getAVLPos(unsigned); 75 76 // Whether this is a LEGALAVL node. 77 bool isLegalAVL(SDValue AVL); 78 79 // The AVL operand of this node. 80 SDValue getNodeAVL(SDValue); 81 82 // Mask position of this node. 83 std::optional<int> getMaskPos(unsigned); 84 85 SDValue getNodeMask(SDValue); 86 87 // Return the AVL operand of this node. If it is a LEGALAVL node, unwrap it. 88 // Return with the boolean whether unwrapping happened. 89 std::pair<SDValue, bool> getAnnotatedNodeAVL(SDValue); 90 91 /// } AVL Functions 92 93 /// Node Properties { 94 95 std::optional<EVT> getIdiomaticVectorType(SDNode *Op); 96 97 SDValue getLoadStoreStride(SDValue Op, VECustomDAG &CDAG); 98 99 SDValue getMemoryPtr(SDValue Op); 100 101 SDValue getNodeChain(SDValue Op); 102 103 SDValue getStoredValue(SDValue Op); 104 105 SDValue getNodePassthru(SDValue Op); 106 107 SDValue getGatherScatterIndex(SDValue Op); 108 109 SDValue getGatherScatterScale(SDValue Op); 110 111 unsigned getScalarReductionOpcode(unsigned VVPOC, bool IsMask); 112 113 // Whether this VP_REDUCE_*/ VECREDUCE_*/VVP_REDUCE_* SDNode has a start 114 // parameter. 115 bool hasReductionStartParam(unsigned VVPOC); 116 117 /// } Node Properties 118 119 enum class Packing { 120 Normal = 0, // 256 element standard mode. 121 Dense = 1 // 512 element packed mode. 122 }; 123 124 // Get the vector or mask register type for this packing and element type. 125 MVT getLegalVectorType(Packing P, MVT ElemVT); 126 127 // Whether this type belongs to a packed mask or vector register. 128 Packing getTypePacking(EVT); 129 130 enum class PackElem : int8_t { 131 Lo = 0, // Integer (63, 32] 132 Hi = 1 // Float (32, 0] 133 }; 134 135 struct VETargetMasks { 136 SDValue Mask; 137 SDValue AVL; 138 VETargetMasks(SDValue Mask = SDValue(), SDValue AVL = SDValue()) MaskVETargetMasks139 : Mask(Mask), AVL(AVL) {} 140 }; 141 142 class VECustomDAG { 143 SelectionDAG &DAG; 144 SDLoc DL; 145 146 public: getDAG()147 SelectionDAG *getDAG() const { return &DAG; } 148 VECustomDAG(SelectionDAG & DAG,SDLoc DL)149 VECustomDAG(SelectionDAG &DAG, SDLoc DL) : DAG(DAG), DL(DL) {} 150 VECustomDAG(SelectionDAG & DAG,SDValue WhereOp)151 VECustomDAG(SelectionDAG &DAG, SDValue WhereOp) : DAG(DAG), DL(WhereOp) {} 152 VECustomDAG(SelectionDAG & DAG,const SDNode * WhereN)153 VECustomDAG(SelectionDAG &DAG, const SDNode *WhereN) : DAG(DAG), DL(WhereN) {} 154 155 /// getNode { 156 SDValue getNode(unsigned OC, SDVTList VTL, ArrayRef<SDValue> OpV, 157 std::optional<SDNodeFlags> Flags = std::nullopt) const { 158 auto N = DAG.getNode(OC, DL, VTL, OpV); 159 if (Flags) 160 N->setFlags(*Flags); 161 return N; 162 } 163 164 SDValue getNode(unsigned OC, ArrayRef<EVT> ResVT, ArrayRef<SDValue> OpV, 165 std::optional<SDNodeFlags> Flags = std::nullopt) const { 166 auto N = DAG.getNode(OC, DL, ResVT, OpV); 167 if (Flags) 168 N->setFlags(*Flags); 169 return N; 170 } 171 172 SDValue getNode(unsigned OC, EVT ResVT, ArrayRef<SDValue> OpV, 173 std::optional<SDNodeFlags> Flags = std::nullopt) const { 174 auto N = DAG.getNode(OC, DL, ResVT, OpV); 175 if (Flags) 176 N->setFlags(*Flags); 177 return N; 178 } 179 getUNDEF(EVT VT)180 SDValue getUNDEF(EVT VT) const { return DAG.getUNDEF(VT); } 181 /// } getNode 182 183 /// Legalizing getNode { 184 SDValue getLegalReductionOpVVP(unsigned VVPOpcode, EVT ResVT, SDValue StartV, 185 SDValue VectorV, SDValue Mask, SDValue AVL, 186 SDNodeFlags Flags) const; 187 /// } Legalizing getNode 188 189 /// Packing { 190 SDValue getUnpack(EVT DestVT, SDValue Vec, PackElem Part, SDValue AVL) const; 191 SDValue getPack(EVT DestVT, SDValue LoVec, SDValue HiVec, SDValue AVL) const; 192 /// } Packing 193 getMergeValues(ArrayRef<SDValue> Values)194 SDValue getMergeValues(ArrayRef<SDValue> Values) const { 195 return DAG.getMergeValues(Values, DL); 196 } 197 198 SDValue getConstant(uint64_t Val, EVT VT, bool IsTarget = false, 199 bool IsOpaque = false) const; 200 201 SDValue getConstantMask(Packing Packing, bool AllTrue) const; 202 SDValue getMaskBroadcast(EVT ResultVT, SDValue Scalar, SDValue AVL) const; 203 SDValue getBroadcast(EVT ResultVT, SDValue Scalar, SDValue AVL) const; 204 205 // Wrap AVL in a LEGALAVL node (unless it is one already). 206 SDValue annotateLegalAVL(SDValue AVL) const; 207 VETargetMasks getTargetSplitMask(SDValue RawMask, SDValue RawAVL, 208 PackElem Part) const; 209 210 // Splitting support 211 SDValue getSplitPtrOffset(SDValue Ptr, SDValue ByteStride, 212 PackElem Part) const; 213 SDValue getSplitPtrStride(SDValue PackStride) const; 214 SDValue getGatherScatterAddress(SDValue BasePtr, SDValue Scale, SDValue Index, 215 SDValue Mask, SDValue AVL) const; getVectorVT(EVT ElemVT,unsigned NumElems)216 EVT getVectorVT(EVT ElemVT, unsigned NumElems) const { 217 return EVT::getVectorVT(*DAG.getContext(), ElemVT, NumElems); 218 } 219 }; 220 221 } // namespace llvm 222 223 #endif // LLVM_LIB_TARGET_VE_VECUSTOMDAG_H 224