xref: /freebsd/contrib/llvm-project/llvm/utils/TableGen/Common/CodeGenInstruction.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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_COMMON_CODEGENINSTRUCTION_H
14 #define LLVM_UTILS_TABLEGEN_COMMON_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 
getEarlyClobber()38     static ConstraintInfo getEarlyClobber() {
39       ConstraintInfo I;
40       I.Kind = EarlyClobber;
41       I.OtherTiedOperand = 0;
42       return I;
43     }
44 
getTied(unsigned Op)45     static ConstraintInfo getTied(unsigned Op) {
46       ConstraintInfo I;
47       I.Kind = Tied;
48       I.OtherTiedOperand = Op;
49       return I;
50     }
51 
isNone()52     bool isNone() const { return Kind == None; }
isEarlyClobber()53     bool isEarlyClobber() const { return Kind == EarlyClobber; }
isTied()54     bool isTied() const { return Kind == Tied; }
55 
getTiedOperand()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     const Record *Rec;
77 
78     /// Name - If this operand was assigned a symbolic name, this is it,
79     /// otherwise, it's empty.
80     StringRef Name;
81 
82     /// The names of sub-operands, if given, otherwise empty.
83     std::vector<StringRef> SubOpNames;
84 
85     /// PrinterMethodName - The method used to print operands of this type in
86     /// the asmprinter.
87     StringRef 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<StringRef> 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     const 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 
OperandInfoOperandInfo119     OperandInfo(const Record *R, StringRef Name, StringRef PrinterMethodName,
120                 const std::string &OT, unsigned MION, unsigned MINO,
121                 const DagInit *MIOI)
122         : Rec(R), Name(Name), SubOpNames(MINO),
123           PrinterMethodName(PrinterMethodName), EncoderMethodNames(MINO),
124           OperandType(OT), MIOperandNo(MION), MINumOperands(MINO),
125           DoNotEncode(MINO), MIOperandInfo(MIOI), Constraints(MINO) {}
126 
127     /// getTiedOperand - If this operand is tied to another one, return the
128     /// other operand number.  Otherwise, return -1.
getTiedRegisterOperandInfo129     int getTiedRegister() const {
130       for (const CGIOperandList::ConstraintInfo &CI : Constraints)
131         if (CI.isTied())
132           return CI.getTiedOperand();
133       return -1;
134     }
135   };
136 
137   CGIOperandList(const Record *D);
138 
139   const Record *TheDef; // The actual record containing this OperandList.
140 
141   /// NumDefs - Number of def operands declared, this is the number of
142   /// elements in the instruction's (outs) list.
143   ///
144   unsigned NumDefs;
145 
146   /// OperandList - The list of declared operands, along with their declared
147   /// type (which is a record).
148   std::vector<OperandInfo> OperandList;
149 
150   /// SubOpAliases - List of alias names for suboperands.
151   StringMap<std::pair<unsigned, unsigned>> SubOpAliases;
152 
153   // Information gleaned from the operand list.
154   bool isPredicable;
155   bool hasOptionalDef;
156   bool isVariadic;
157 
158   // Provide transparent accessors to the operand list.
empty()159   bool empty() const { return OperandList.empty(); }
size()160   unsigned size() const { return OperandList.size(); }
161   const OperandInfo &operator[](unsigned i) const { return OperandList[i]; }
162   OperandInfo &operator[](unsigned i) { return OperandList[i]; }
back()163   OperandInfo &back() { return OperandList.back(); }
back()164   const OperandInfo &back() const { return OperandList.back(); }
165 
166   typedef std::vector<OperandInfo>::iterator iterator;
167   typedef std::vector<OperandInfo>::const_iterator const_iterator;
begin()168   iterator begin() { return OperandList.begin(); }
begin()169   const_iterator begin() const { return OperandList.begin(); }
end()170   iterator end() { return OperandList.end(); }
end()171   const_iterator end() const { return OperandList.end(); }
172 
173   /// getOperandNamed - Return the index of the operand with the specified
174   /// non-empty name.  If the instruction does not have an operand with the
175   /// specified name, abort.
176   unsigned getOperandNamed(StringRef Name) const;
177 
178   /// findOperandNamed - Query whether the instruction has an operand of the
179   /// given name. If so, the index of the operand. Otherwise, return
180   /// std::nullopt.
181   std::optional<unsigned> findOperandNamed(StringRef Name) const;
182 
183   std::optional<std::pair<unsigned, unsigned>>
184   findSubOperandAlias(StringRef Name) const;
185 
186   /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar",
187   /// where $foo is a whole operand and $foo.bar refers to a suboperand.
188   /// This aborts if the name is invalid.  If AllowWholeOp is true, references
189   /// to operands with suboperands are allowed, otherwise not.
190   std::pair<unsigned, unsigned> ParseOperandName(StringRef Op,
191                                                  bool AllowWholeOp = true);
192 
193   /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a
194   /// flat machineinstr operand #.
getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op)195   unsigned getFlattenedOperandNumber(std::pair<unsigned, unsigned> Op) const {
196     return OperandList[Op.first].MIOperandNo + Op.second;
197   }
198 
199   /// getSubOperandNumber - Unflatten a operand number into an
200   /// operand/suboperand pair.
getSubOperandNumber(unsigned Op)201   std::pair<unsigned, unsigned> getSubOperandNumber(unsigned Op) const {
202     for (unsigned i = 0;; ++i) {
203       assert(i < OperandList.size() && "Invalid flat operand #");
204       if (OperandList[i].MIOperandNo + OperandList[i].MINumOperands > Op)
205         return {i, Op - OperandList[i].MIOperandNo};
206     }
207   }
208 
209   /// isFlatOperandNotEmitted - Return true if the specified flat operand #
210   /// should not be emitted with the code emitter.
isFlatOperandNotEmitted(unsigned FlatOpNo)211   bool isFlatOperandNotEmitted(unsigned FlatOpNo) const {
212     std::pair<unsigned, unsigned> Op = getSubOperandNumber(FlatOpNo);
213     if (OperandList[Op.first].DoNotEncode.size() > Op.second)
214       return OperandList[Op.first].DoNotEncode[Op.second];
215     return false;
216   }
217 
218   void ProcessDisableEncoding(StringRef Value);
219 };
220 
221 class CodeGenInstruction {
222 public:
223   const Record *TheDef; // The actual record defining this instruction.
224   StringRef Namespace;  // The namespace the instruction is in.
225 
226   /// AsmString - The format string used to emit a .s file for the
227   /// instruction.
228   StringRef AsmString;
229 
230   /// Operands - This is information about the (ins) and (outs) list specified
231   /// to the instruction.
232   CGIOperandList Operands;
233 
234   /// ImplicitDefs/ImplicitUses - These are lists of registers that are
235   /// implicitly defined and used by the instruction.
236   std::vector<const Record *> ImplicitDefs, ImplicitUses;
237 
238   // Various boolean values we track for the instruction.
239   bool isPreISelOpcode : 1;
240   bool isReturn : 1;
241   bool isEHScopeReturn : 1;
242   bool isBranch : 1;
243   bool isIndirectBranch : 1;
244   bool isCompare : 1;
245   bool isMoveImm : 1;
246   bool isMoveReg : 1;
247   bool isBitcast : 1;
248   bool isSelect : 1;
249   bool isBarrier : 1;
250   bool isCall : 1;
251   bool isAdd : 1;
252   bool isTrap : 1;
253   bool canFoldAsLoad : 1;
254   bool mayLoad : 1;
255   bool mayLoad_Unset : 1;
256   bool mayStore : 1;
257   bool mayStore_Unset : 1;
258   bool mayRaiseFPException : 1;
259   bool isPredicable : 1;
260   bool isConvertibleToThreeAddress : 1;
261   bool isCommutable : 1;
262   bool isTerminator : 1;
263   bool isReMaterializable : 1;
264   bool hasDelaySlot : 1;
265   bool usesCustomInserter : 1;
266   bool hasPostISelHook : 1;
267   bool hasCtrlDep : 1;
268   bool isNotDuplicable : 1;
269   bool hasSideEffects : 1;
270   bool hasSideEffects_Unset : 1;
271   bool isAsCheapAsAMove : 1;
272   bool hasExtraSrcRegAllocReq : 1;
273   bool hasExtraDefRegAllocReq : 1;
274   bool isCodeGenOnly : 1;
275   bool isPseudo : 1;
276   bool isMeta : 1;
277   bool isRegSequence : 1;
278   bool isExtractSubreg : 1;
279   bool isInsertSubreg : 1;
280   bool isConvergent : 1;
281   bool hasNoSchedulingInfo : 1;
282   bool FastISelShouldIgnore : 1;
283   bool hasChain : 1;
284   bool hasChain_Inferred : 1;
285   bool variadicOpsAreDefs : 1;
286   bool isAuthenticated : 1;
287 
288   std::string DeprecatedReason;
289   bool HasComplexDeprecationPredicate;
290 
291   /// Are there any undefined flags?
hasUndefFlags()292   bool hasUndefFlags() const {
293     return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset;
294   }
295 
296   // The record used to infer instruction flags, or NULL if no flag values
297   // have been inferred.
298   const Record *InferredFrom;
299 
300   // The enum value assigned by CodeGenTarget::computeInstrsByEnum.
301   mutable unsigned EnumVal = 0;
302 
303   CodeGenInstruction(const Record *R);
304 
305   /// HasOneImplicitDefWithKnownVT - If the instruction has at least one
306   /// implicit def and it has a known VT, return the VT, otherwise return
307   /// MVT::Other.
308   MVT::SimpleValueType
309   HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const;
310 
311   /// FlattenAsmStringVariants - Flatten the specified AsmString to only
312   /// include text from the specified variant, returning the new string.
313   static std::string FlattenAsmStringVariants(StringRef AsmString,
314                                               unsigned Variant);
315 
316   // Is the specified operand in a generic instruction implicitly a pointer.
317   // This can be used on intructions that use typeN or ptypeN to identify
318   // operands that should be considered as pointers even though SelectionDAG
319   // didn't make a distinction between integer and pointers.
isInOperandAPointer(unsigned i)320   bool isInOperandAPointer(unsigned i) const {
321     return isOperandImpl("InOperandList", i, "IsPointer");
322   }
323 
isOutOperandAPointer(unsigned i)324   bool isOutOperandAPointer(unsigned i) const {
325     return isOperandImpl("OutOperandList", i, "IsPointer");
326   }
327 
328   /// Check if the operand is required to be an immediate.
isInOperandImmArg(unsigned i)329   bool isInOperandImmArg(unsigned i) const {
330     return isOperandImpl("InOperandList", i, "IsImmediate");
331   }
332 
333   /// Return true if the instruction uses a variable length encoding.
isVariableLengthEncoding()334   bool isVariableLengthEncoding() const {
335     const RecordVal *RV = TheDef->getValue("Inst");
336     return RV && isa<DagInit>(RV->getValue());
337   }
338 
339 private:
340   bool isOperandImpl(StringRef OpListName, unsigned i,
341                      StringRef PropertyName) const;
342 };
343 } // namespace llvm
344 
345 #endif // LLVM_UTILS_TABLEGEN_COMMON_CODEGENINSTRUCTION_H
346