1//===- CodeGenInstruction.h - Instruction Class Wrapper ---------*- 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 a wrapper class for the 'Instruction' TableGen class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_UTILS_TABLEGEN_CODEGENINSTRUCTION_H
14#define LLVM_UTILS_TABLEGEN_CODEGENINSTRUCTION_H
15
16#include "llvm/ADT/BitVector.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/CodeGenTypes/MachineValueType.h"
20#include "llvm/TableGen/Record.h"
21#include <cassert>
22#include <string>
23#include <utility>
24#include <vector>
25
26namespace llvm {
27class CodeGenTarget;
28
29class CGIOperandList {
30public:
31 class ConstraintInfo {
32 enum { None, EarlyClobber, Tied } Kind = None;
33 unsigned OtherTiedOperand = 0;
34
35 public:
36 ConstraintInfo() = default;
37
38 static ConstraintInfo getEarlyClobber() {
39 ConstraintInfo I;
40 I.Kind = EarlyClobber;
41 I.OtherTiedOperand = 0;
42 return I;
43 }
44
45 static ConstraintInfo getTied(unsigned Op) {
46 ConstraintInfo I;
47 I.Kind = Tied;
48 I.OtherTiedOperand = Op;
49 return I;
50 }
51
52 bool isNone() const { return Kind == None; }
53 bool isEarlyClobber() const { return Kind == EarlyClobber; }
54 bool isTied() const { return Kind == Tied; }
55
56 unsigned getTiedOperand() const {
57 assert(isTied());
58 return OtherTiedOperand;
59 }
60
61 bool operator==(const ConstraintInfo &RHS) const {
62 if (Kind != RHS.Kind)
63 return false;
64 if (Kind == Tied && OtherTiedOperand != RHS.OtherTiedOperand)
65 return false;
66 return true;
67 }
68 bool operator!=(const ConstraintInfo &RHS) const { return !(*this == RHS); }
69 };
70
71 /// OperandInfo - The information we keep track of for each operand in the
72 /// operand list for a tablegen instruction.
73 struct OperandInfo {
74 /// Rec - The definition this operand is declared as.
75 ///
76 Record *Rec;
77
78 /// Name - If this operand was assigned a symbolic name, this is it,
79 /// otherwise, it's empty.
80 std::string Name;
81
82 /// The names of sub-operands, if given, otherwise empty.
83 std::vector<std::string> SubOpNames;
84
85 /// PrinterMethodName - The method used to print operands of this type in
86 /// the asmprinter.
87 std::string PrinterMethodName;
88
89 /// The method used to get the machine operand value for binary
90 /// encoding, per sub-operand. If empty, uses "getMachineOpValue".
91 std::vector<std::string> EncoderMethodNames;
92
93 /// OperandType - A value from MCOI::OperandType representing the type of
94 /// the operand.
95 std::string OperandType;
96
97 /// MIOperandNo - Currently (this is meant to be phased out), some logical
98 /// operands correspond to multiple MachineInstr operands. In the X86
99 /// target for example, one address operand is represented as 4
100 /// MachineOperands. Because of this, the operand number in the
101 /// OperandList may not match the MachineInstr operand num. Until it
102 /// does, this contains the MI operand index of this operand.
103 unsigned MIOperandNo;
104 unsigned MINumOperands; // The number of operands.
105
106 /// DoNotEncode - Bools are set to true in this vector for each operand in
107 /// the DisableEncoding list. These should not be emitted by the code
108 /// emitter.
109 BitVector DoNotEncode;
110
111 /// MIOperandInfo - Default MI operand type. Note an operand may be made
112 /// up of multiple MI operands.
113 DagInit *MIOperandInfo;
114
115 /// Constraint info for this operand. This operand can have pieces, so we
116 /// track constraint info for each.
117 std::vector<ConstraintInfo> Constraints;
118
119 OperandInfo(Record *R, const std::string &N, const std::string &PMN,
120 const std::string &OT, unsigned MION, unsigned MINO,
121 DagInit *MIOI)
122 : Rec(R), Name(N), SubOpNames(MINO), PrinterMethodName(PMN),
123 EncoderMethodNames(MINO), OperandType(OT), MIOperandNo(MION),
124 MINumOperands(MINO), DoNotEncode(MINO), MIOperandInfo(MIOI),
125 Constraints(MINO) {}
126
127 /// getTiedOperand - If this operand is tied to another one, return the
128 /// other operand number. Otherwise, return -1.
129 int getTiedRegister() const {
130 for (unsigned j = 0, e = Constraints.size(); j != e; ++j) {
131 const CGIOperandList::ConstraintInfo &CI = Constraints[j];
132 if (CI.isTied())
133 return CI.getTiedOperand();
134 }
135 return -1;
136 }
137 };
138
139 CGIOperandList(Record *D);
140
141 Record *TheDef; // The actual record containing this OperandList.
142
143 /// NumDefs - Number of def operands declared, this is the number of
144 /// elements in the instruction's (outs) list.
145 ///
146 unsigned NumDefs;
147
148 /// OperandList - The list of declared operands, along with their declared
149 /// type (which is a record).
150 std::vector<OperandInfo> OperandList;
151
152 /// SubOpAliases - List of alias names for suboperands.
153 StringMap<std::pair<unsigned, unsigned>> SubOpAliases;
154
155 // Information gleaned from the operand list.
156 bool isPredicable;
157 bool hasOptionalDef;
158 bool isVariadic;
159
160 // Provide transparent accessors to the operand list.
161 bool empty() const { return OperandList.empty(); }
162 unsigned size() const { return OperandList.size(); }
163 const OperandInfo &operator[](unsigned i) const { return OperandList[i]; }
164 OperandInfo &operator[](unsigned i) { return OperandList[i]; }
165 OperandInfo &back() { return OperandList.back(); }
166 const OperandInfo &back() const { return OperandList.back(); }
167
168 typedef std::vector<OperandInfo>::iterator iterator;
169 typedef std::vector<OperandInfo>::const_iterator const_iterator;
170 iterator begin() { return OperandList.begin(); }
171 const_iterator begin() const { return OperandList.begin(); }
172 iterator end() { return OperandList.end(); }
173 const_iterator end() const { return OperandList.end(); }
174
175 /// getOperandNamed - Return the index of the operand with the specified
176 /// non-empty name. If the instruction does not have an operand with the
177 /// specified name, abort.
178 unsigned getOperandNamed(StringRef Name) const;
179
180 /// hasOperandNamed - Query whether the instruction has an operand of the
181 /// given name. If so, return true and set OpIdx to the index of the
182 /// operand. Otherwise, return false.
183 bool hasOperandNamed(StringRef Name, unsigned &OpIdx) const;
184
185 bool hasSubOperandAlias(StringRef Name,
186 std::pair<unsigned, unsigned> &SubOp) const;
187
188 /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar",
189 /// where $foo is a whole operand and $foo.bar refers to a suboperand.
190 /// This aborts if the name is invalid. If AllowWholeOp is true, references
191 /// to operands with suboperands are allowed, otherwise not.
192 std::pair<unsigned, unsigned> ParseOperandName(StringRef Op,
193 bool AllowWholeOp = true);
194
195 /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a
196 /// flat machineinstr operand #.
197 unsigned getFlattenedOperandNumber(std::pair<unsigned, unsigned> Op) const {
198 return OperandList[Op.first].MIOperandNo + Op.second;
199 }
200
201 /// getSubOperandNumber - Unflatten a operand number into an
202 /// operand/suboperand pair.
203 std::pair<unsigned, unsigned> getSubOperandNumber(unsigned Op) const {
204 for (unsigned i = 0;; ++i) {
205 assert(i < OperandList.size() && "Invalid flat operand #");
206 if (OperandList[i].MIOperandNo + OperandList[i].MINumOperands > Op)
207 return std::pair(i, Op - OperandList[i].MIOperandNo);
208 }
209 }
210
211 /// isFlatOperandNotEmitted - Return true if the specified flat operand #
212 /// should not be emitted with the code emitter.
213 bool isFlatOperandNotEmitted(unsigned FlatOpNo) const {
214 std::pair<unsigned, unsigned> Op = getSubOperandNumber(Op: FlatOpNo);
215 if (OperandList[Op.first].DoNotEncode.size() > Op.second)
216 return OperandList[Op.first].DoNotEncode[Op.second];
217 return false;
218 }
219
220 void ProcessDisableEncoding(StringRef Value);
221};
222
223class CodeGenInstruction {
224public:
225 Record *TheDef; // The actual record defining this instruction.
226 StringRef Namespace; // The namespace the instruction is in.
227
228 /// AsmString - The format string used to emit a .s file for the
229 /// instruction.
230 std::string AsmString;
231
232 /// Operands - This is information about the (ins) and (outs) list specified
233 /// to the instruction.
234 CGIOperandList Operands;
235
236 /// ImplicitDefs/ImplicitUses - These are lists of registers that are
237 /// implicitly defined and used by the instruction.
238 std::vector<Record *> ImplicitDefs, ImplicitUses;
239
240 // Various boolean values we track for the instruction.
241 bool isPreISelOpcode : 1;
242 bool isReturn : 1;
243 bool isEHScopeReturn : 1;
244 bool isBranch : 1;
245 bool isIndirectBranch : 1;
246 bool isCompare : 1;
247 bool isMoveImm : 1;
248 bool isMoveReg : 1;
249 bool isBitcast : 1;
250 bool isSelect : 1;
251 bool isBarrier : 1;
252 bool isCall : 1;
253 bool isAdd : 1;
254 bool isTrap : 1;
255 bool canFoldAsLoad : 1;
256 bool mayLoad : 1;
257 bool mayLoad_Unset : 1;
258 bool mayStore : 1;
259 bool mayStore_Unset : 1;
260 bool mayRaiseFPException : 1;
261 bool isPredicable : 1;
262 bool isConvertibleToThreeAddress : 1;
263 bool isCommutable : 1;
264 bool isTerminator : 1;
265 bool isReMaterializable : 1;
266 bool hasDelaySlot : 1;
267 bool usesCustomInserter : 1;
268 bool hasPostISelHook : 1;
269 bool hasCtrlDep : 1;
270 bool isNotDuplicable : 1;
271 bool hasSideEffects : 1;
272 bool hasSideEffects_Unset : 1;
273 bool isAsCheapAsAMove : 1;
274 bool hasExtraSrcRegAllocReq : 1;
275 bool hasExtraDefRegAllocReq : 1;
276 bool isCodeGenOnly : 1;
277 bool isPseudo : 1;
278 bool isMeta : 1;
279 bool isRegSequence : 1;
280 bool isExtractSubreg : 1;
281 bool isInsertSubreg : 1;
282 bool isConvergent : 1;
283 bool hasNoSchedulingInfo : 1;
284 bool FastISelShouldIgnore : 1;
285 bool hasChain : 1;
286 bool hasChain_Inferred : 1;
287 bool variadicOpsAreDefs : 1;
288 bool isAuthenticated : 1;
289
290 std::string DeprecatedReason;
291 bool HasComplexDeprecationPredicate;
292
293 /// Are there any undefined flags?
294 bool hasUndefFlags() const {
295 return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset;
296 }
297
298 // The record used to infer instruction flags, or NULL if no flag values
299 // have been inferred.
300 Record *InferredFrom;
301
302 // The enum value assigned by CodeGenTarget::computeInstrsByEnum.
303 mutable unsigned EnumVal = 0;
304
305 CodeGenInstruction(Record *R);
306
307 /// HasOneImplicitDefWithKnownVT - If the instruction has at least one
308 /// implicit def and it has a known VT, return the VT, otherwise return
309 /// MVT::Other.
310 MVT::SimpleValueType
311 HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const;
312
313 /// FlattenAsmStringVariants - Flatten the specified AsmString to only
314 /// include text from the specified variant, returning the new string.
315 static std::string FlattenAsmStringVariants(StringRef AsmString,
316 unsigned Variant);
317
318 // Is the specified operand in a generic instruction implicitly a pointer.
319 // This can be used on intructions that use typeN or ptypeN to identify
320 // operands that should be considered as pointers even though SelectionDAG
321 // didn't make a distinction between integer and pointers.
322 bool isInOperandAPointer(unsigned i) const {
323 return isOperandImpl(OpListName: "InOperandList", i, PropertyName: "IsPointer");
324 }
325
326 bool isOutOperandAPointer(unsigned i) const {
327 return isOperandImpl(OpListName: "OutOperandList", i, PropertyName: "IsPointer");
328 }
329
330 /// Check if the operand is required to be an immediate.
331 bool isInOperandImmArg(unsigned i) const {
332 return isOperandImpl(OpListName: "InOperandList", i, PropertyName: "IsImmediate");
333 }
334
335 /// Return true if the instruction uses a variable length encoding.
336 bool isVariableLengthEncoding() const {
337 const RecordVal *RV = TheDef->getValue(Name: "Inst");
338 return RV && isa<DagInit>(Val: RV->getValue());
339 }
340
341private:
342 bool isOperandImpl(StringRef OpListName, unsigned i,
343 StringRef PropertyName) const;
344};
345} // namespace llvm
346
347#endif
348