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