xref: /freebsd-src/contrib/llvm-project/llvm/utils/TableGen/Common/CodeGenTarget.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric //===- CodeGenTarget.h - Target Class Wrapper -------------------*- C++ -*-===//
2*0fca6ea1SDimitry Andric //
3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0fca6ea1SDimitry Andric //
7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
8*0fca6ea1SDimitry Andric //
9*0fca6ea1SDimitry Andric // This file defines wrappers for the Target class and related global
10*0fca6ea1SDimitry Andric // functionality.  This makes it easier to access the data and provides a single
11*0fca6ea1SDimitry Andric // place that needs to check it for validity.  All of these classes abort
12*0fca6ea1SDimitry Andric // on error conditions.
13*0fca6ea1SDimitry Andric //
14*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
15*0fca6ea1SDimitry Andric 
16*0fca6ea1SDimitry Andric #ifndef LLVM_UTILS_TABLEGEN_CODEGENTARGET_H
17*0fca6ea1SDimitry Andric #define LLVM_UTILS_TABLEGEN_CODEGENTARGET_H
18*0fca6ea1SDimitry Andric 
19*0fca6ea1SDimitry Andric #include "Basic/SDNodeProperties.h"
20*0fca6ea1SDimitry Andric #include "CodeGenHwModes.h"
21*0fca6ea1SDimitry Andric #include "CodeGenInstruction.h"
22*0fca6ea1SDimitry Andric #include "InfoByHwMode.h"
23*0fca6ea1SDimitry Andric #include "llvm/ADT/ArrayRef.h"
24*0fca6ea1SDimitry Andric #include "llvm/ADT/DenseMap.h"
25*0fca6ea1SDimitry Andric #include "llvm/ADT/SmallVector.h"
26*0fca6ea1SDimitry Andric #include "llvm/ADT/StringRef.h"
27*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/MachineValueType.h"
28*0fca6ea1SDimitry Andric #include <cassert>
29*0fca6ea1SDimitry Andric #include <memory>
30*0fca6ea1SDimitry Andric #include <optional>
31*0fca6ea1SDimitry Andric #include <string>
32*0fca6ea1SDimitry Andric #include <vector>
33*0fca6ea1SDimitry Andric 
34*0fca6ea1SDimitry Andric namespace llvm {
35*0fca6ea1SDimitry Andric 
36*0fca6ea1SDimitry Andric class RecordKeeper;
37*0fca6ea1SDimitry Andric class Record;
38*0fca6ea1SDimitry Andric class CodeGenRegBank;
39*0fca6ea1SDimitry Andric class CodeGenRegister;
40*0fca6ea1SDimitry Andric class CodeGenRegisterClass;
41*0fca6ea1SDimitry Andric class CodeGenSchedModels;
42*0fca6ea1SDimitry Andric class CodeGenSubRegIndex;
43*0fca6ea1SDimitry Andric 
44*0fca6ea1SDimitry Andric /// getValueType - Return the MVT::SimpleValueType that the specified TableGen
45*0fca6ea1SDimitry Andric /// record corresponds to.
46*0fca6ea1SDimitry Andric MVT::SimpleValueType getValueType(const Record *Rec);
47*0fca6ea1SDimitry Andric 
48*0fca6ea1SDimitry Andric StringRef getName(MVT::SimpleValueType T);
49*0fca6ea1SDimitry Andric StringRef getEnumName(MVT::SimpleValueType T);
50*0fca6ea1SDimitry Andric 
51*0fca6ea1SDimitry Andric /// getQualifiedName - Return the name of the specified record, with a
52*0fca6ea1SDimitry Andric /// namespace qualifier if the record contains one.
53*0fca6ea1SDimitry Andric std::string getQualifiedName(const Record *R);
54*0fca6ea1SDimitry Andric 
55*0fca6ea1SDimitry Andric /// CodeGenTarget - This class corresponds to the Target class in the .td files.
56*0fca6ea1SDimitry Andric ///
57*0fca6ea1SDimitry Andric class CodeGenTarget {
58*0fca6ea1SDimitry Andric   RecordKeeper &Records;
59*0fca6ea1SDimitry Andric   Record *TargetRec;
60*0fca6ea1SDimitry Andric 
61*0fca6ea1SDimitry Andric   mutable DenseMap<const Record *, std::unique_ptr<CodeGenInstruction>>
62*0fca6ea1SDimitry Andric       Instructions;
63*0fca6ea1SDimitry Andric   mutable std::unique_ptr<CodeGenRegBank> RegBank;
64*0fca6ea1SDimitry Andric   mutable std::vector<Record *> RegAltNameIndices;
65*0fca6ea1SDimitry Andric   mutable SmallVector<ValueTypeByHwMode, 8> LegalValueTypes;
66*0fca6ea1SDimitry Andric   CodeGenHwModes CGH;
67*0fca6ea1SDimitry Andric   std::vector<Record *> MacroFusions;
68*0fca6ea1SDimitry Andric   mutable bool HasVariableLengthEncodings = false;
69*0fca6ea1SDimitry Andric 
70*0fca6ea1SDimitry Andric   void ReadRegAltNameIndices() const;
71*0fca6ea1SDimitry Andric   void ReadInstructions() const;
72*0fca6ea1SDimitry Andric   void ReadLegalValueTypes() const;
73*0fca6ea1SDimitry Andric 
74*0fca6ea1SDimitry Andric   mutable std::unique_ptr<CodeGenSchedModels> SchedModels;
75*0fca6ea1SDimitry Andric 
76*0fca6ea1SDimitry Andric   mutable StringRef InstNamespace;
77*0fca6ea1SDimitry Andric   mutable std::vector<const CodeGenInstruction *> InstrsByEnum;
78*0fca6ea1SDimitry Andric   mutable unsigned NumPseudoInstructions = 0;
79*0fca6ea1SDimitry Andric 
80*0fca6ea1SDimitry Andric public:
81*0fca6ea1SDimitry Andric   CodeGenTarget(RecordKeeper &Records);
82*0fca6ea1SDimitry Andric   ~CodeGenTarget();
83*0fca6ea1SDimitry Andric 
84*0fca6ea1SDimitry Andric   Record *getTargetRecord() const { return TargetRec; }
85*0fca6ea1SDimitry Andric   StringRef getName() const;
86*0fca6ea1SDimitry Andric 
87*0fca6ea1SDimitry Andric   /// getInstNamespace - Return the target-specific instruction namespace.
88*0fca6ea1SDimitry Andric   ///
89*0fca6ea1SDimitry Andric   StringRef getInstNamespace() const;
90*0fca6ea1SDimitry Andric 
91*0fca6ea1SDimitry Andric   /// getRegNamespace - Return the target-specific register namespace.
92*0fca6ea1SDimitry Andric   StringRef getRegNamespace() const;
93*0fca6ea1SDimitry Andric 
94*0fca6ea1SDimitry Andric   /// getInstructionSet - Return the InstructionSet object.
95*0fca6ea1SDimitry Andric   ///
96*0fca6ea1SDimitry Andric   Record *getInstructionSet() const;
97*0fca6ea1SDimitry Andric 
98*0fca6ea1SDimitry Andric   /// getAllowRegisterRenaming - Return the AllowRegisterRenaming flag value for
99*0fca6ea1SDimitry Andric   /// this target.
100*0fca6ea1SDimitry Andric   ///
101*0fca6ea1SDimitry Andric   bool getAllowRegisterRenaming() const;
102*0fca6ea1SDimitry Andric 
103*0fca6ea1SDimitry Andric   /// getAsmParser - Return the AssemblyParser definition for this target.
104*0fca6ea1SDimitry Andric   ///
105*0fca6ea1SDimitry Andric   Record *getAsmParser() const;
106*0fca6ea1SDimitry Andric 
107*0fca6ea1SDimitry Andric   /// getAsmParserVariant - Return the AssemblyParserVariant definition for
108*0fca6ea1SDimitry Andric   /// this target.
109*0fca6ea1SDimitry Andric   ///
110*0fca6ea1SDimitry Andric   Record *getAsmParserVariant(unsigned i) const;
111*0fca6ea1SDimitry Andric 
112*0fca6ea1SDimitry Andric   /// getAsmParserVariantCount - Return the AssemblyParserVariant definition
113*0fca6ea1SDimitry Andric   /// available for this target.
114*0fca6ea1SDimitry Andric   ///
115*0fca6ea1SDimitry Andric   unsigned getAsmParserVariantCount() const;
116*0fca6ea1SDimitry Andric 
117*0fca6ea1SDimitry Andric   /// getAsmWriter - Return the AssemblyWriter definition for this target.
118*0fca6ea1SDimitry Andric   ///
119*0fca6ea1SDimitry Andric   Record *getAsmWriter() const;
120*0fca6ea1SDimitry Andric 
121*0fca6ea1SDimitry Andric   /// getRegBank - Return the register bank description.
122*0fca6ea1SDimitry Andric   CodeGenRegBank &getRegBank() const;
123*0fca6ea1SDimitry Andric 
124*0fca6ea1SDimitry Andric   /// Return the largest register class on \p RegBank which supports \p Ty and
125*0fca6ea1SDimitry Andric   /// covers \p SubIdx if it exists.
126*0fca6ea1SDimitry Andric   std::optional<CodeGenRegisterClass *>
127*0fca6ea1SDimitry Andric   getSuperRegForSubReg(const ValueTypeByHwMode &Ty, CodeGenRegBank &RegBank,
128*0fca6ea1SDimitry Andric                        const CodeGenSubRegIndex *SubIdx,
129*0fca6ea1SDimitry Andric                        bool MustBeAllocatable = false) const;
130*0fca6ea1SDimitry Andric 
131*0fca6ea1SDimitry Andric   /// getRegisterByName - If there is a register with the specific AsmName,
132*0fca6ea1SDimitry Andric   /// return it.
133*0fca6ea1SDimitry Andric   const CodeGenRegister *getRegisterByName(StringRef Name) const;
134*0fca6ea1SDimitry Andric 
135*0fca6ea1SDimitry Andric   const std::vector<Record *> &getRegAltNameIndices() const {
136*0fca6ea1SDimitry Andric     if (RegAltNameIndices.empty())
137*0fca6ea1SDimitry Andric       ReadRegAltNameIndices();
138*0fca6ea1SDimitry Andric     return RegAltNameIndices;
139*0fca6ea1SDimitry Andric   }
140*0fca6ea1SDimitry Andric 
141*0fca6ea1SDimitry Andric   const CodeGenRegisterClass &getRegisterClass(Record *R) const;
142*0fca6ea1SDimitry Andric 
143*0fca6ea1SDimitry Andric   /// getRegisterVTs - Find the union of all possible SimpleValueTypes for the
144*0fca6ea1SDimitry Andric   /// specified physical register.
145*0fca6ea1SDimitry Andric   std::vector<ValueTypeByHwMode> getRegisterVTs(Record *R) const;
146*0fca6ea1SDimitry Andric 
147*0fca6ea1SDimitry Andric   ArrayRef<ValueTypeByHwMode> getLegalValueTypes() const {
148*0fca6ea1SDimitry Andric     if (LegalValueTypes.empty())
149*0fca6ea1SDimitry Andric       ReadLegalValueTypes();
150*0fca6ea1SDimitry Andric     return LegalValueTypes;
151*0fca6ea1SDimitry Andric   }
152*0fca6ea1SDimitry Andric 
153*0fca6ea1SDimitry Andric   CodeGenSchedModels &getSchedModels() const;
154*0fca6ea1SDimitry Andric 
155*0fca6ea1SDimitry Andric   const CodeGenHwModes &getHwModes() const { return CGH; }
156*0fca6ea1SDimitry Andric 
157*0fca6ea1SDimitry Andric   bool hasMacroFusion() const { return !MacroFusions.empty(); }
158*0fca6ea1SDimitry Andric 
159*0fca6ea1SDimitry Andric   const std::vector<Record *> getMacroFusions() const { return MacroFusions; }
160*0fca6ea1SDimitry Andric 
161*0fca6ea1SDimitry Andric private:
162*0fca6ea1SDimitry Andric   DenseMap<const Record *, std::unique_ptr<CodeGenInstruction>> &
163*0fca6ea1SDimitry Andric   getInstructions() const {
164*0fca6ea1SDimitry Andric     if (Instructions.empty())
165*0fca6ea1SDimitry Andric       ReadInstructions();
166*0fca6ea1SDimitry Andric     return Instructions;
167*0fca6ea1SDimitry Andric   }
168*0fca6ea1SDimitry Andric 
169*0fca6ea1SDimitry Andric public:
170*0fca6ea1SDimitry Andric   CodeGenInstruction &getInstruction(const Record *InstRec) const {
171*0fca6ea1SDimitry Andric     if (Instructions.empty())
172*0fca6ea1SDimitry Andric       ReadInstructions();
173*0fca6ea1SDimitry Andric     auto I = Instructions.find(InstRec);
174*0fca6ea1SDimitry Andric     assert(I != Instructions.end() && "Not an instruction");
175*0fca6ea1SDimitry Andric     return *I->second;
176*0fca6ea1SDimitry Andric   }
177*0fca6ea1SDimitry Andric 
178*0fca6ea1SDimitry Andric   /// Returns the number of predefined instructions.
179*0fca6ea1SDimitry Andric   static unsigned getNumFixedInstructions();
180*0fca6ea1SDimitry Andric 
181*0fca6ea1SDimitry Andric   /// Returns the number of pseudo instructions.
182*0fca6ea1SDimitry Andric   unsigned getNumPseudoInstructions() const {
183*0fca6ea1SDimitry Andric     if (InstrsByEnum.empty())
184*0fca6ea1SDimitry Andric       ComputeInstrsByEnum();
185*0fca6ea1SDimitry Andric     return NumPseudoInstructions;
186*0fca6ea1SDimitry Andric   }
187*0fca6ea1SDimitry Andric 
188*0fca6ea1SDimitry Andric   /// Return all of the instructions defined by the target, ordered by their
189*0fca6ea1SDimitry Andric   /// enum value.
190*0fca6ea1SDimitry Andric   /// The following order of instructions is also guaranteed:
191*0fca6ea1SDimitry Andric   /// - fixed / generic instructions as declared in TargetOpcodes.def, in order;
192*0fca6ea1SDimitry Andric   /// - pseudo instructions in lexicographical order sorted by name;
193*0fca6ea1SDimitry Andric   /// - other instructions in lexicographical order sorted by name.
194*0fca6ea1SDimitry Andric   ArrayRef<const CodeGenInstruction *> getInstructionsByEnumValue() const {
195*0fca6ea1SDimitry Andric     if (InstrsByEnum.empty())
196*0fca6ea1SDimitry Andric       ComputeInstrsByEnum();
197*0fca6ea1SDimitry Andric     return InstrsByEnum;
198*0fca6ea1SDimitry Andric   }
199*0fca6ea1SDimitry Andric 
200*0fca6ea1SDimitry Andric   /// Return the integer enum value corresponding to this instruction record.
201*0fca6ea1SDimitry Andric   unsigned getInstrIntValue(const Record *R) const {
202*0fca6ea1SDimitry Andric     if (InstrsByEnum.empty())
203*0fca6ea1SDimitry Andric       ComputeInstrsByEnum();
204*0fca6ea1SDimitry Andric     return getInstruction(R).EnumVal;
205*0fca6ea1SDimitry Andric   }
206*0fca6ea1SDimitry Andric 
207*0fca6ea1SDimitry Andric   typedef ArrayRef<const CodeGenInstruction *>::const_iterator inst_iterator;
208*0fca6ea1SDimitry Andric   inst_iterator inst_begin() const {
209*0fca6ea1SDimitry Andric     return getInstructionsByEnumValue().begin();
210*0fca6ea1SDimitry Andric   }
211*0fca6ea1SDimitry Andric   inst_iterator inst_end() const { return getInstructionsByEnumValue().end(); }
212*0fca6ea1SDimitry Andric 
213*0fca6ea1SDimitry Andric   /// Return whether instructions have variable length encodings on this target.
214*0fca6ea1SDimitry Andric   bool hasVariableLengthEncodings() const { return HasVariableLengthEncodings; }
215*0fca6ea1SDimitry Andric 
216*0fca6ea1SDimitry Andric   /// isLittleEndianEncoding - are instruction bit patterns defined as  [0..n]?
217*0fca6ea1SDimitry Andric   ///
218*0fca6ea1SDimitry Andric   bool isLittleEndianEncoding() const;
219*0fca6ea1SDimitry Andric 
220*0fca6ea1SDimitry Andric   /// reverseBitsForLittleEndianEncoding - For little-endian instruction bit
221*0fca6ea1SDimitry Andric   /// encodings, reverse the bit order of all instructions.
222*0fca6ea1SDimitry Andric   void reverseBitsForLittleEndianEncoding();
223*0fca6ea1SDimitry Andric 
224*0fca6ea1SDimitry Andric   /// guessInstructionProperties - should we just guess unset instruction
225*0fca6ea1SDimitry Andric   /// properties?
226*0fca6ea1SDimitry Andric   bool guessInstructionProperties() const;
227*0fca6ea1SDimitry Andric 
228*0fca6ea1SDimitry Andric private:
229*0fca6ea1SDimitry Andric   void ComputeInstrsByEnum() const;
230*0fca6ea1SDimitry Andric };
231*0fca6ea1SDimitry Andric 
232*0fca6ea1SDimitry Andric /// ComplexPattern - ComplexPattern info, corresponding to the ComplexPattern
233*0fca6ea1SDimitry Andric /// tablegen class in TargetSelectionDAG.td
234*0fca6ea1SDimitry Andric class ComplexPattern {
235*0fca6ea1SDimitry Andric   Record *Ty;
236*0fca6ea1SDimitry Andric   unsigned NumOperands;
237*0fca6ea1SDimitry Andric   std::string SelectFunc;
238*0fca6ea1SDimitry Andric   std::vector<Record *> RootNodes;
239*0fca6ea1SDimitry Andric   unsigned Properties; // Node properties
240*0fca6ea1SDimitry Andric   unsigned Complexity;
241*0fca6ea1SDimitry Andric 
242*0fca6ea1SDimitry Andric public:
243*0fca6ea1SDimitry Andric   ComplexPattern(Record *R);
244*0fca6ea1SDimitry Andric 
245*0fca6ea1SDimitry Andric   Record *getValueType() const { return Ty; }
246*0fca6ea1SDimitry Andric   unsigned getNumOperands() const { return NumOperands; }
247*0fca6ea1SDimitry Andric   const std::string &getSelectFunc() const { return SelectFunc; }
248*0fca6ea1SDimitry Andric   const std::vector<Record *> &getRootNodes() const { return RootNodes; }
249*0fca6ea1SDimitry Andric   bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
250*0fca6ea1SDimitry Andric   unsigned getComplexity() const { return Complexity; }
251*0fca6ea1SDimitry Andric };
252*0fca6ea1SDimitry Andric 
253*0fca6ea1SDimitry Andric } // namespace llvm
254*0fca6ea1SDimitry Andric 
255*0fca6ea1SDimitry Andric #endif
256