1 //===------------ VECustomDAG.h - VE Custom DAG Nodes -----------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_TARGET_VE_VECUSTOMDAG_H
15 #define LLVM_LIB_TARGET_VE_VECUSTOMDAG_H
18 #include "VEISelLowering.h"
19 #include "llvm/CodeGen/SelectionDAG.h"
20 #include "llvm/CodeGen/TargetLowering.h"
24 std::optional
<unsigned> getVVPOpcode(unsigned Opcode
);
26 bool isVVPUnaryOp(unsigned Opcode
);
27 bool isVVPBinaryOp(unsigned Opcode
);
28 bool isVVPReductionOp(unsigned Opcode
);
30 MVT
splitVectorType(MVT VT
);
32 bool isPackedVectorType(EVT SomeVT
);
34 bool isMaskType(EVT SomeVT
);
36 bool isMaskArithmetic(SDValue Op
);
38 bool isVVPOrVEC(unsigned);
40 bool supportsPackedMode(unsigned Opcode
, EVT IdiomVT
);
42 bool isPackingSupportOpcode(unsigned Opc
);
44 bool maySafelyIgnoreMask(SDValue Op
);
46 /// The VE backend uses a two-staged process to lower and legalize vector
49 /// 1. VP and standard vector SDNodes are lowered to SDNodes of the VVP_* layer.
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
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.
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.
73 // The AVL operand position of this node.
74 std::optional
<int> getAVLPos(unsigned);
76 // Whether this is a LEGALAVL node.
77 bool isLegalAVL(SDValue AVL
);
79 // The AVL operand of this node.
80 SDValue
getNodeAVL(SDValue
);
82 // Mask position of this node.
83 std::optional
<int> getMaskPos(unsigned);
85 SDValue
getNodeMask(SDValue
);
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
);
95 std::optional
<EVT
> getIdiomaticVectorType(SDNode
*Op
);
97 SDValue
getLoadStoreStride(SDValue Op
, VECustomDAG
&CDAG
);
99 SDValue
getMemoryPtr(SDValue Op
);
101 SDValue
getNodeChain(SDValue Op
);
103 SDValue
getStoredValue(SDValue Op
);
105 SDValue
getNodePassthru(SDValue Op
);
107 SDValue
getGatherScatterIndex(SDValue Op
);
109 SDValue
getGatherScatterScale(SDValue Op
);
111 unsigned getScalarReductionOpcode(unsigned VVPOC
, bool IsMask
);
113 // Whether this VP_REDUCE_*/ VECREDUCE_*/VVP_REDUCE_* SDNode has a start
115 bool hasReductionStartParam(unsigned VVPOC
);
117 /// } Node Properties
120 Normal
= 0, // 256 element standard mode.
121 Dense
= 1 // 512 element packed mode.
124 // Get the vector or mask register type for this packing and element type.
125 MVT
getLegalVectorType(Packing P
, MVT ElemVT
);
127 // Whether this type belongs to a packed mask or vector register.
128 Packing
getTypePacking(EVT
);
130 enum class PackElem
: int8_t {
131 Lo
= 0, // Integer (63, 32]
132 Hi
= 1 // Float (32, 0]
135 struct VETargetMasks
{
138 VETargetMasks(SDValue Mask
= SDValue(), SDValue AVL
= SDValue())
139 : Mask(Mask
), AVL(AVL
) {}
147 SelectionDAG
*getDAG() const { return &DAG
; }
149 VECustomDAG(SelectionDAG
&DAG
, SDLoc DL
) : DAG(DAG
), DL(DL
) {}
151 VECustomDAG(SelectionDAG
&DAG
, SDValue WhereOp
) : DAG(DAG
), DL(WhereOp
) {}
153 VECustomDAG(SelectionDAG
&DAG
, const SDNode
*WhereN
) : DAG(DAG
), DL(WhereN
) {}
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
);
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
);
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
);
180 SDValue
getUNDEF(EVT VT
) const { return DAG
.getUNDEF(VT
); }
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
190 SDValue
getUnpack(EVT DestVT
, SDValue Vec
, PackElem Part
, SDValue AVL
) const;
191 SDValue
getPack(EVT DestVT
, SDValue LoVec
, SDValue HiVec
, SDValue AVL
) const;
194 SDValue
getMergeValues(ArrayRef
<SDValue
> Values
) const {
195 return DAG
.getMergeValues(Values
, DL
);
198 SDValue
getConstant(uint64_t Val
, EVT VT
, bool IsTarget
= false,
199 bool IsOpaque
= false) const;
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;
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;
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;
216 EVT
getVectorVT(EVT ElemVT
, unsigned NumElems
) const {
217 return EVT::getVectorVT(*DAG
.getContext(), ElemVT
, NumElems
);
223 #endif // LLVM_LIB_TARGET_VE_VECUSTOMDAG_H