LLVM 20.0.0git
MatchContext.h
Go to the documentation of this file.
1//===---------------- llvm/CodeGen/MatchContext.h --------------*- 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 declares the EmptyMatchContext class and VPMatchContext class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_MATCHCONTEXT_H
14#define LLVM_LIB_CODEGEN_SELECTIONDAG_MATCHCONTEXT_H
15
18
19namespace llvm {
20
22 SelectionDAG &DAG;
23 const TargetLowering &TLI;
24 SDNode *Root;
25
26public:
28 : DAG(DAG), TLI(TLI), Root(Root) {}
29
30 unsigned getRootBaseOpcode() { return Root->getOpcode(); }
31 bool match(SDValue OpN, unsigned Opcode) const {
32 return Opcode == OpN->getOpcode();
33 }
34
35 // Same as SelectionDAG::getNode().
36 template <typename... ArgT> SDValue getNode(ArgT &&...Args) {
37 return DAG.getNode(std::forward<ArgT>(Args)...);
38 }
39
40 bool isOperationLegal(unsigned Op, EVT VT) const {
41 return TLI.isOperationLegal(Op, VT);
42 }
43
44 bool isOperationLegalOrCustom(unsigned Op, EVT VT,
45 bool LegalOnly = false) const {
46 return TLI.isOperationLegalOrCustom(Op, VT, LegalOnly);
47 }
48};
49
51 SelectionDAG &DAG;
52 const TargetLowering &TLI;
53 SDValue RootMaskOp;
54 SDValue RootVectorLenOp;
55 SDNode *Root;
56
57public:
59 : DAG(DAG), TLI(TLI), RootMaskOp(), RootVectorLenOp() {
60 Root = _Root;
61 assert(Root->isVPOpcode());
62 if (auto RootMaskPos = ISD::getVPMaskIdx(Root->getOpcode()))
63 RootMaskOp = Root->getOperand(*RootMaskPos);
64 else if (Root->getOpcode() == ISD::VP_SELECT)
65 RootMaskOp = DAG.getAllOnesConstant(SDLoc(Root),
66 Root->getOperand(0).getValueType());
67
68 if (auto RootVLenPos = ISD::getVPExplicitVectorLengthIdx(Root->getOpcode()))
69 RootVectorLenOp = Root->getOperand(*RootVLenPos);
70 }
71
72 unsigned getRootBaseOpcode() {
73 std::optional<unsigned> Opcode = ISD::getBaseOpcodeForVP(
74 Root->getOpcode(), !Root->getFlags().hasNoFPExcept());
75 assert(Opcode.has_value());
76 return *Opcode;
77 }
78
79 /// whether \p OpVal is a node that is functionally compatible with the
80 /// NodeType \p Opc
81 bool match(SDValue OpVal, unsigned Opc) const {
82 if (!OpVal->isVPOpcode())
83 return OpVal->getOpcode() == Opc;
84
85 auto BaseOpc = ISD::getBaseOpcodeForVP(OpVal->getOpcode(),
86 !OpVal->getFlags().hasNoFPExcept());
87 if (BaseOpc != Opc)
88 return false;
89
90 // Make sure the mask of OpVal is true mask or is same as Root's.
91 unsigned VPOpcode = OpVal->getOpcode();
92 if (auto MaskPos = ISD::getVPMaskIdx(VPOpcode)) {
93 SDValue MaskOp = OpVal.getOperand(*MaskPos);
94 if (RootMaskOp != MaskOp &&
96 return false;
97 }
98
99 // Make sure the EVL of OpVal is same as Root's.
100 if (auto VLenPos = ISD::getVPExplicitVectorLengthIdx(VPOpcode))
101 if (RootVectorLenOp != OpVal.getOperand(*VLenPos))
102 return false;
103 return true;
104 }
105
106 // Specialize based on number of operands.
107 // TODO emit VP intrinsics where MaskOp/VectorLenOp != null
108 // SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT) { return
109 // DAG.getNode(Opcode, DL, VT); }
110 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue Operand) {
111 unsigned VPOpcode = ISD::getVPForBaseOpcode(Opcode);
112 assert(ISD::getVPMaskIdx(VPOpcode) == 1 &&
113 ISD::getVPExplicitVectorLengthIdx(VPOpcode) == 2);
114 return DAG.getNode(VPOpcode, DL, VT,
115 {Operand, RootMaskOp, RootVectorLenOp});
116 }
117
118 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
119 SDValue N2) {
120 unsigned VPOpcode = ISD::getVPForBaseOpcode(Opcode);
121 assert(ISD::getVPMaskIdx(VPOpcode) == 2 &&
122 ISD::getVPExplicitVectorLengthIdx(VPOpcode) == 3);
123 return DAG.getNode(VPOpcode, DL, VT, {N1, N2, RootMaskOp, RootVectorLenOp});
124 }
125
126 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
127 SDValue N2, SDValue N3) {
128 unsigned VPOpcode = ISD::getVPForBaseOpcode(Opcode);
129 assert(ISD::getVPMaskIdx(VPOpcode) == 3 &&
130 ISD::getVPExplicitVectorLengthIdx(VPOpcode) == 4);
131 return DAG.getNode(VPOpcode, DL, VT,
132 {N1, N2, N3, RootMaskOp, RootVectorLenOp});
133 }
134
135 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue Operand,
136 SDNodeFlags Flags) {
137 unsigned VPOpcode = ISD::getVPForBaseOpcode(Opcode);
138 assert(ISD::getVPMaskIdx(VPOpcode) == 1 &&
139 ISD::getVPExplicitVectorLengthIdx(VPOpcode) == 2);
140 return DAG.getNode(VPOpcode, DL, VT, {Operand, RootMaskOp, RootVectorLenOp},
141 Flags);
142 }
143
144 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
145 SDValue N2, SDNodeFlags Flags) {
146 unsigned VPOpcode = ISD::getVPForBaseOpcode(Opcode);
147 assert(ISD::getVPMaskIdx(VPOpcode) == 2 &&
148 ISD::getVPExplicitVectorLengthIdx(VPOpcode) == 3);
149 return DAG.getNode(VPOpcode, DL, VT, {N1, N2, RootMaskOp, RootVectorLenOp},
150 Flags);
151 }
152
153 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
154 SDValue N2, SDValue N3, SDNodeFlags Flags) {
155 unsigned VPOpcode = ISD::getVPForBaseOpcode(Opcode);
156 assert(ISD::getVPMaskIdx(VPOpcode) == 3 &&
157 ISD::getVPExplicitVectorLengthIdx(VPOpcode) == 4);
158 return DAG.getNode(VPOpcode, DL, VT,
159 {N1, N2, N3, RootMaskOp, RootVectorLenOp}, Flags);
160 }
161
162 bool isOperationLegal(unsigned Op, EVT VT) const {
163 unsigned VPOp = ISD::getVPForBaseOpcode(Op);
164 return TLI.isOperationLegal(VPOp, VT);
165 }
166
167 bool isOperationLegalOrCustom(unsigned Op, EVT VT,
168 bool LegalOnly = false) const {
169 unsigned VPOp = ISD::getVPForBaseOpcode(Op);
170 return TLI.isOperationLegalOrCustom(VPOp, VT, LegalOnly);
171 }
172};
173
174} // namespace llvm
175
176#endif // LLVM_LIB_CODEGEN_SELECTIONDAG_MATCHCONTEXT_H
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file describes how to lower LLVM code to machine code.
This class represents an Operation in the Expression.
bool match(SDValue OpN, unsigned Opcode) const
Definition: MatchContext.h:31
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Definition: MatchContext.h:44
EmptyMatchContext(SelectionDAG &DAG, const TargetLowering &TLI, SDNode *Root)
Definition: MatchContext.h:27
unsigned getRootBaseOpcode()
Definition: MatchContext.h:30
bool isOperationLegal(unsigned Op, EVT VT) const
Definition: MatchContext.h:40
SDValue getNode(ArgT &&...Args)
Definition: MatchContext.h:36
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
SDNodeFlags getFlags() const
const SDValue & getOperand(unsigned Num) const
bool isVPOpcode() const
Test if this node is a vector predication operation.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:226
SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1, SDValue N2, SDNodeFlags Flags)
Definition: MatchContext.h:144
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Definition: MatchContext.h:167
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue Operand, SDNodeFlags Flags)
Definition: MatchContext.h:135
bool isOperationLegal(unsigned Op, EVT VT) const
Definition: MatchContext.h:162
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1, SDValue N2, SDValue N3, SDNodeFlags Flags)
Definition: MatchContext.h:153
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1, SDValue N2, SDValue N3)
Definition: MatchContext.h:126
bool match(SDValue OpVal, unsigned Opc) const
whether OpVal is a node that is functionally compatible with the NodeType Opc
Definition: MatchContext.h:81
unsigned getRootBaseOpcode()
Definition: MatchContext.h:72
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue Operand)
Definition: MatchContext.h:110
VPMatchContext(SelectionDAG &DAG, const TargetLowering &TLI, SDNode *_Root)
Definition: MatchContext.h:58
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1, SDValue N2)
Definition: MatchContext.h:118
bool isConstantSplatVectorAllOnes(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are ~0 ...
unsigned getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
std::optional< unsigned > getBaseOpcodeForVP(unsigned Opcode, bool hasFPExcept)
Translate this VP Opcode to its corresponding non-VP Opcode.
std::optional< unsigned > getVPMaskIdx(unsigned Opcode)
The operand position of the vector mask.
std::optional< unsigned > getVPExplicitVectorLengthIdx(unsigned Opcode)
The operand position of the explicit vector length parameter.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Extended Value Type.
Definition: ValueTypes.h:35
These are IR-level optimization flags that may be propagated to SDNodes.
bool hasNoFPExcept() const