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