xref: /freebsd/contrib/llvm-project/llvm/utils/TableGen/Common/CodeGenInstruction.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
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     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 
OperandInfoOperandInfo119     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.
getTiedRegisterOperandInfo129     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.
empty()161   bool empty() const { return OperandList.empty(); }
size()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]; }
back()165   OperandInfo &back() { return OperandList.back(); }
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;
begin()170   iterator begin() { return OperandList.begin(); }
begin()171   const_iterator begin() const { return OperandList.begin(); }
end()172   iterator end() { return OperandList.end(); }
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 #.
getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op)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.
getSubOperandNumber(unsigned Op)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.
isFlatOperandNotEmitted(unsigned FlatOpNo)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?
hasUndefFlags()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.
isInOperandAPointer(unsigned i)322   bool isInOperandAPointer(unsigned i) const {
323     return isOperandImpl("InOperandList", i, "IsPointer");
324   }
325 
isOutOperandAPointer(unsigned i)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.
isInOperandImmArg(unsigned i)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.
isVariableLengthEncoding()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