Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/llvm/lib/Target/VE/VECustomDAG.h
Line
Count
Source (jump to first uncovered line)
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())
139
0
      : Mask(Mask), AVL(AVL) {}
140
};
141
142
class VECustomDAG {
143
  SelectionDAG &DAG;
144
  SDLoc DL;
145
146
public:
147
0
  SelectionDAG *getDAG() const { return &DAG; }
148
149
0
  VECustomDAG(SelectionDAG &DAG, SDLoc DL) : DAG(DAG), DL(DL) {}
150
151
0
  VECustomDAG(SelectionDAG &DAG, SDValue WhereOp) : DAG(DAG), DL(WhereOp) {}
152
153
0
  VECustomDAG(SelectionDAG &DAG, const SDNode *WhereN) : DAG(DAG), DL(WhereN) {}
154
155
  /// getNode {
156
  SDValue getNode(unsigned OC, SDVTList VTL, ArrayRef<SDValue> OpV,
157
0
                  std::optional<SDNodeFlags> Flags = std::nullopt) const {
158
0
    auto N = DAG.getNode(OC, DL, VTL, OpV);
159
0
    if (Flags)
160
0
      N->setFlags(*Flags);
161
0
    return N;
162
0
  }
163
164
  SDValue getNode(unsigned OC, ArrayRef<EVT> ResVT, ArrayRef<SDValue> OpV,
165
0
                  std::optional<SDNodeFlags> Flags = std::nullopt) const {
166
0
    auto N = DAG.getNode(OC, DL, ResVT, OpV);
167
0
    if (Flags)
168
0
      N->setFlags(*Flags);
169
0
    return N;
170
0
  }
171
172
  SDValue getNode(unsigned OC, EVT ResVT, ArrayRef<SDValue> OpV,
173
0
                  std::optional<SDNodeFlags> Flags = std::nullopt) const {
174
0
    auto N = DAG.getNode(OC, DL, ResVT, OpV);
175
0
    if (Flags)
176
0
      N->setFlags(*Flags);
177
0
    return N;
178
0
  }
179
180
0
  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
194
0
  SDValue getMergeValues(ArrayRef<SDValue> Values) const {
195
0
    return DAG.getMergeValues(Values, DL);
196
0
  }
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;
216
0
  EVT getVectorVT(EVT ElemVT, unsigned NumElems) const {
217
0
    return EVT::getVectorVT(*DAG.getContext(), ElemVT, NumElems);
218
0
  }
219
};
220
221
} // namespace llvm
222
223
#endif // LLVM_LIB_TARGET_VE_VECUSTOMDAG_H