Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/Common/CodeGenInstruction.h
35290 views
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
26
namespace llvm {
27
class CodeGenTarget;
28
29
class CGIOperandList {
30
public:
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(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
223
class CodeGenInstruction {
224
public:
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("InOperandList", i, "IsPointer");
324
}
325
326
bool isOutOperandAPointer(unsigned i) const {
327
return isOperandImpl("OutOperandList", i, "IsPointer");
328
}
329
330
/// Check if the operand is required to be an immediate.
331
bool isInOperandImmArg(unsigned i) const {
332
return isOperandImpl("InOperandList", i, "IsImmediate");
333
}
334
335
/// Return true if the instruction uses a variable length encoding.
336
bool isVariableLengthEncoding() const {
337
const RecordVal *RV = TheDef->getValue("Inst");
338
return RV && isa<DagInit>(RV->getValue());
339
}
340
341
private:
342
bool isOperandImpl(StringRef OpListName, unsigned i,
343
StringRef PropertyName) const;
344
};
345
} // namespace llvm
346
347
#endif
348
349