LLVM 22.0.0git
SDNodeInfo.cpp
Go to the documentation of this file.
1//==------------------------------------------------------------------------==//
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
14
15using namespace llvm;
16
17static void reportNodeError(const SelectionDAG &DAG, const SDNode *N,
18 const Twine &Msg) {
19 std::string S;
21 SS << "invalid node: " << Msg << '\n';
22 N->printrWithDepth(SS, &DAG, 2);
24}
25
26static void checkResultType(const SelectionDAG &DAG, const SDNode *N,
27 unsigned ResIdx, EVT ExpectedVT) {
28 EVT ActualVT = N->getValueType(ResIdx);
29 if (ActualVT != ExpectedVT)
31 DAG, N,
32 "result #" + Twine(ResIdx) + " has invalid type; expected " +
33 ExpectedVT.getEVTString() + ", got " + ActualVT.getEVTString());
34}
35
36static void checkOperandType(const SelectionDAG &DAG, const SDNode *N,
37 unsigned OpIdx, EVT ExpectedVT) {
38 EVT ActualVT = N->getOperand(OpIdx).getValueType();
39 if (ActualVT != ExpectedVT)
41 DAG, N,
42 "operand #" + Twine(OpIdx) + " has invalid type; expected " +
43 ExpectedVT.getEVTString() + ", got " + ActualVT.getEVTString());
44}
45
46namespace {
47
48/// Similar to SDValue, but also records whether it is a result or an operand
49/// of a node so we can provide more precise diagnostics.
50class SDNodeValue {
51 const SDNode *N;
52 unsigned Idx;
53 bool IsRes;
54
55public:
56 SDNodeValue(const SDNode *N, unsigned Idx, bool IsRes)
57 : N(N), Idx(Idx), IsRes(IsRes) {}
58
59 SDValue getValue() const {
60 return IsRes ? SDValue(const_cast<SDNode *>(N), Idx) : N->getOperand(Idx);
61 }
62
63 EVT getValueType() const { return getValue().getValueType(); }
64
65 friend raw_ostream &operator<<(raw_ostream &OS, const SDNodeValue &Op) {
66 return OS << (Op.IsRes ? "result" : "operand") << " #" << Op.Idx;
67 }
68};
69
70} // namespace
71
72void SDNodeInfo::verifyNode(const SelectionDAG &DAG, const SDNode *N) const {
73 const SDNodeDesc &Desc = getDesc(N->getOpcode());
74 bool HasChain = Desc.hasProperty(SDNPHasChain);
75 bool HasOutGlue = Desc.hasProperty(SDNPOutGlue);
76 bool HasInGlue = Desc.hasProperty(SDNPInGlue);
77 bool HasOptInGlue = Desc.hasProperty(SDNPOptInGlue);
78 bool IsVariadic = Desc.hasProperty(SDNPVariadic);
79
80 unsigned ActualNumResults = N->getNumValues();
81 unsigned ExpectedNumResults = Desc.NumResults + HasChain + HasOutGlue;
82
83 if (ActualNumResults != ExpectedNumResults)
84 reportNodeError(DAG, N,
85 "invalid number of results; expected " +
86 Twine(ExpectedNumResults) + ", got " +
87 Twine(ActualNumResults));
88
89 // Chain result comes after all normal results.
90 if (HasChain) {
91 unsigned ChainResIdx = Desc.NumResults;
92 checkResultType(DAG, N, ChainResIdx, MVT::Other);
93 }
94
95 // Glue result comes last.
96 if (HasOutGlue) {
97 unsigned GlueResIdx = Desc.NumResults + HasChain;
98 checkResultType(DAG, N, GlueResIdx, MVT::Glue);
99 }
100
101 // In the most general case, the operands of a node go in the following order:
102 // chain, fix#0, ..., fix#M-1, var#0, ... var#N-1, glue
103 // If the number of operands is < 0, M can be any;
104 // If the node has SDNPVariadic property, N can be any.
105 bool HasOptionalOperands = Desc.NumOperands < 0 || IsVariadic;
106
107 unsigned ActualNumOperands = N->getNumOperands();
108 unsigned ExpectedMinNumOperands =
109 (Desc.NumOperands >= 0 ? Desc.NumOperands : 0) + HasChain + HasInGlue;
110
111 // Check the lower bound.
112 if (ActualNumOperands < ExpectedMinNumOperands) {
113 StringRef How = HasOptionalOperands ? "at least " : "";
114 reportNodeError(DAG, N,
115 "invalid number of operands; expected " + How +
116 Twine(ExpectedMinNumOperands) + ", got " +
117 Twine(ActualNumOperands));
118 }
119
120 // Check the upper bound. We can only do this if the number of fixed operands
121 // is known and there are no variadic operands.
122 if (Desc.NumOperands >= 0 && !IsVariadic) {
123 // Account for optional input glue.
124 unsigned ExpectedMaxNumOperands = ExpectedMinNumOperands + HasOptInGlue;
125 if (ActualNumOperands > ExpectedMaxNumOperands) {
126 StringRef How = HasOptInGlue ? "at most " : "";
127 reportNodeError(DAG, N,
128 "invalid number of operands; expected " + How +
129 Twine(ExpectedMaxNumOperands) + ", got " +
130 Twine(ActualNumOperands));
131 }
132 }
133
134 // Chain operand comes first.
135 if (HasChain)
136 checkOperandType(DAG, N, 0, MVT::Other);
137
138 // Glue operand comes last.
139 if (HasInGlue)
140 checkOperandType(DAG, N, ActualNumOperands - 1, MVT::Glue);
141 if (HasOptInGlue && ActualNumOperands >= 1 &&
142 N->getOperand(ActualNumOperands - 1).getValueType() == MVT::Glue)
143 HasInGlue = true;
144
145 // Check variadic operands. These should be Register or RegisterMask.
146 if (IsVariadic && Desc.NumOperands >= 0) {
147 unsigned VarOpStart = HasChain + Desc.NumOperands;
148 unsigned VarOpEnd = ActualNumOperands - HasInGlue;
149 for (unsigned OpIdx = VarOpStart; OpIdx != VarOpEnd; ++OpIdx) {
150 unsigned OpOpcode = N->getOperand(OpIdx).getOpcode();
151 if (OpOpcode != ISD::Register && OpOpcode != ISD::RegisterMask)
152 reportNodeError(DAG, N,
153 "variadic operand #" + Twine(OpIdx) +
154 " must be Register or RegisterMask");
155 }
156 }
157
158 unsigned VTHwMode =
160
161 // Returns a constrained or constraining value (result or operand) of a node.
162 // ValIdx is the index of a node's value, as defined by SDTypeConstraint;
163 // that is, it indexes a node's operands after its results and ignores
164 // chain/glue values.
165 auto GetConstraintValue = [&](unsigned ValIdx) {
166 if (ValIdx < Desc.NumResults)
167 return SDNodeValue(N, ValIdx, /*IsRes=*/true);
168 return SDNodeValue(N, HasChain + (ValIdx - Desc.NumResults),
169 /*IsRes=*/false);
170 };
171
172 auto GetConstraintVT = [&](const SDTypeConstraint &C) {
173 if (!C.NumHwModes)
174 return static_cast<MVT::SimpleValueType>(C.VT);
175 for (auto [Mode, VT] : ArrayRef(&VTByHwModeTable[C.VT], C.NumHwModes))
176 if (Mode == VTHwMode)
177 return VT;
178 llvm_unreachable("No value type for this HW mode");
179 };
180
182 raw_svector_ostream SS(ES);
183
184 for (const SDTypeConstraint &C : getConstraints(N->getOpcode())) {
185 SDNodeValue Val = GetConstraintValue(C.ConstrainedValIdx);
186 EVT VT = Val.getValueType();
187
188 switch (C.Kind) {
189 case SDTCisVT: {
190 EVT ExpectedVT = GetConstraintVT(C);
191
192 bool IsPtr = ExpectedVT == MVT::iPTR;
193 if (IsPtr)
194 ExpectedVT =
196
197 if (VT != ExpectedVT) {
198 SS << Val << " must have type " << ExpectedVT;
199 if (IsPtr)
200 SS << " (iPTR)";
201 SS << ", but has type " << VT;
202 reportNodeError(DAG, N, SS.str());
203 }
204 break;
205 }
206 case SDTCisPtrTy:
207 break;
208 case SDTCisInt:
209 break;
210 case SDTCisFP:
211 break;
212 case SDTCisVec:
213 break;
214 case SDTCisSameAs:
215 break;
217 break;
219 break;
220 case SDTCisEltOfVec:
221 break;
223 break;
224 case SDTCVecEltisVT: {
225 EVT ExpectedVT = GetConstraintVT(C);
226
227 if (!VT.isVector()) {
228 SS << Val << " must have vector type";
229 reportNodeError(DAG, N, SS.str());
230 }
231 if (VT.getVectorElementType() != ExpectedVT) {
232 SS << Val << " must have " << ExpectedVT << " element type, but has "
233 << VT.getVectorElementType() << " element type";
234 reportNodeError(DAG, N, SS.str());
235 }
236 break;
237 }
239 break;
240 case SDTCisSameSizeAs:
241 break;
242 }
243 }
244}
return SDValue()
MachineInstr unsigned OpIdx
static void checkOperandType(const SelectionDAG &DAG, const SDNode *N, unsigned OpIdx, EVT ExpectedVT)
static void reportNodeError(const SelectionDAG &DAG, const SDNode *N, const Twine &Msg)
static void checkResultType(const SelectionDAG &DAG, const SDNode *N, unsigned ResIdx, EVT ExpectedVT)
static Type * getValueType(Value *V)
Returns the type of the given value/instruction V.
This file describes how to lower LLVM code to machine code.
virtual unsigned getHwMode(enum HwModeType type=HwMode_Default) const
HwMode ID corresponding to the 'type' parameter is retrieved from the HwMode bit set of the current s...
const SDNodeDesc & getDesc(unsigned Opcode) const
Returns the description of a node with the given opcode.
Definition SDNodeInfo.h:107
void verifyNode(const SelectionDAG &DAG, const SDNode *N) const
ArrayRef< SDTypeConstraint > getConstraints(unsigned Opcode) const
Returns operand constraints for a node with the given opcode.
Definition SDNodeInfo.h:113
Represents one node in the SelectionDAG.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
const TargetSubtargetInfo & getSubtarget() const
const TargetLowering & getTargetLoweringInfo() const
const DataLayout & getDataLayout() const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Op::Description Desc
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:167
@ SDNPOptInGlue
Definition SDNodeInfo.h:26
@ SDNPVariadic
Definition SDNodeInfo.h:28
@ SDNPInGlue
Definition SDNodeInfo.h:25
@ SDNPOutGlue
Definition SDNodeInfo.h:24
@ SDNPHasChain
Definition SDNodeInfo.h:23
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
ArrayRef(const T &OneElt) -> ArrayRef< T >
@ SDTCisSameAs
Definition SDNodeInfo.h:37
@ SDTCisPtrTy
Definition SDNodeInfo.h:33
@ SDTCisOpSmallerThanOp
Definition SDNodeInfo.h:39
@ SDTCisSameSizeAs
Definition SDNodeInfo.h:44
@ SDTCisSameNumEltsAs
Definition SDNodeInfo.h:43
@ SDTCisEltOfVec
Definition SDNodeInfo.h:40
@ SDTCisVTSmallerThanOp
Definition SDNodeInfo.h:38
@ SDTCisInt
Definition SDNodeInfo.h:34
@ SDTCisVec
Definition SDNodeInfo.h:36
@ SDTCisVT
Definition SDNodeInfo.h:32
@ SDTCVecEltisVT
Definition SDNodeInfo.h:42
@ SDTCisSubVecOfVec
Definition SDNodeInfo.h:41
@ SDTCisFP
Definition SDNodeInfo.h:35
#define N
Extended Value Type.
Definition ValueTypes.h:35
LLVM_ABI std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:168
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition ValueTypes.h:328