Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 1 | //===- MIParser.h - Machine Instructions Parser -----------------*- 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 declares the function that parses the machine instructions. |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| 13 | #ifndef LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H |
| 14 | #define LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H |
| 15 | |
| 16 | #include "llvm/ADT/DenseMap.h" |
| 17 | #include "llvm/ADT/StringMap.h" |
| 18 | #include "llvm/CodeGen/MachineMemOperand.h" |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 19 | #include "llvm/CodeGen/Register.h" |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 20 | #include "llvm/Support/Allocator.h" |
| 21 | |
| 22 | namespace llvm { |
| 23 | |
| 24 | class MachineBasicBlock; |
| 25 | class MachineFunction; |
| 26 | class MDNode; |
| 27 | class RegisterBank; |
| 28 | struct SlotMapping; |
| 29 | class SMDiagnostic; |
| 30 | class SourceMgr; |
| 31 | class StringRef; |
| 32 | class TargetRegisterClass; |
| 33 | class TargetSubtargetInfo; |
| 34 | |
| 35 | struct VRegInfo { |
| 36 | enum uint8_t { |
| 37 | UNKNOWN, NORMAL, GENERIC, REGBANK |
| 38 | } Kind = UNKNOWN; |
| 39 | bool Explicit = false; ///< VReg was explicitly specified in the .mir file. |
| 40 | union { |
| 41 | const TargetRegisterClass *RC; |
| 42 | const RegisterBank *RegBank; |
| 43 | } D; |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 44 | Register VReg; |
| 45 | Register PreferredReg; |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 46 | }; |
| 47 | |
| 48 | using Name2RegClassMap = StringMap<const TargetRegisterClass *>; |
| 49 | using Name2RegBankMap = StringMap<const RegisterBank *>; |
| 50 | |
| 51 | struct PerTargetMIParsingState { |
| 52 | private: |
| 53 | const TargetSubtargetInfo &Subtarget; |
| 54 | |
| 55 | /// Maps from instruction names to op codes. |
| 56 | StringMap<unsigned> Names2InstrOpCodes; |
| 57 | |
| 58 | /// Maps from register names to registers. |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 59 | StringMap<Register> Names2Regs; |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 60 | |
| 61 | /// Maps from register mask names to register masks. |
| 62 | StringMap<const uint32_t *> Names2RegMasks; |
| 63 | |
| 64 | /// Maps from subregister names to subregister indices. |
| 65 | StringMap<unsigned> Names2SubRegIndices; |
| 66 | |
| 67 | /// Maps from target index names to target indices. |
| 68 | StringMap<int> Names2TargetIndices; |
| 69 | |
| 70 | /// Maps from direct target flag names to the direct target flag values. |
| 71 | StringMap<unsigned> Names2DirectTargetFlags; |
| 72 | |
| 73 | /// Maps from direct target flag names to the bitmask target flag values. |
| 74 | StringMap<unsigned> Names2BitmaskTargetFlags; |
| 75 | |
| 76 | /// Maps from MMO target flag names to MMO target flag values. |
| 77 | StringMap<MachineMemOperand::Flags> Names2MMOTargetFlags; |
| 78 | |
| 79 | /// Maps from register class names to register classes. |
| 80 | Name2RegClassMap Names2RegClasses; |
| 81 | |
| 82 | /// Maps from register bank names to register banks. |
| 83 | Name2RegBankMap Names2RegBanks; |
| 84 | |
| 85 | void initNames2InstrOpCodes(); |
| 86 | void initNames2Regs(); |
| 87 | void initNames2RegMasks(); |
| 88 | void initNames2SubRegIndices(); |
| 89 | void initNames2TargetIndices(); |
| 90 | void initNames2DirectTargetFlags(); |
| 91 | void initNames2BitmaskTargetFlags(); |
| 92 | void initNames2MMOTargetFlags(); |
| 93 | |
| 94 | void initNames2RegClasses(); |
| 95 | void initNames2RegBanks(); |
| 96 | |
| 97 | public: |
| 98 | /// Try to convert an instruction name to an opcode. Return true if the |
| 99 | /// instruction name is invalid. |
| 100 | bool parseInstrName(StringRef InstrName, unsigned &OpCode); |
| 101 | |
| 102 | /// Try to convert a register name to a register number. Return true if the |
| 103 | /// register name is invalid. |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 104 | bool getRegisterByName(StringRef RegName, Register &Reg); |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 105 | |
| 106 | /// Check if the given identifier is a name of a register mask. |
| 107 | /// |
| 108 | /// Return null if the identifier isn't a register mask. |
| 109 | const uint32_t *getRegMask(StringRef Identifier); |
| 110 | |
| 111 | /// Check if the given identifier is a name of a subregister index. |
| 112 | /// |
| 113 | /// Return 0 if the name isn't a subregister index class. |
| 114 | unsigned getSubRegIndex(StringRef Name); |
| 115 | |
| 116 | /// Try to convert a name of target index to the corresponding target index. |
| 117 | /// |
| 118 | /// Return true if the name isn't a name of a target index. |
| 119 | bool getTargetIndex(StringRef Name, int &Index); |
| 120 | |
| 121 | /// Try to convert a name of a direct target flag to the corresponding |
| 122 | /// target flag. |
| 123 | /// |
| 124 | /// Return true if the name isn't a name of a direct flag. |
| 125 | bool getDirectTargetFlag(StringRef Name, unsigned &Flag); |
| 126 | |
| 127 | /// Try to convert a name of a bitmask target flag to the corresponding |
| 128 | /// target flag. |
| 129 | /// |
| 130 | /// Return true if the name isn't a name of a bitmask target flag. |
| 131 | bool getBitmaskTargetFlag(StringRef Name, unsigned &Flag); |
| 132 | |
| 133 | /// Try to convert a name of a MachineMemOperand target flag to the |
| 134 | /// corresponding target flag. |
| 135 | /// |
| 136 | /// Return true if the name isn't a name of a target MMO flag. |
| 137 | bool getMMOTargetFlag(StringRef Name, MachineMemOperand::Flags &Flag); |
| 138 | |
| 139 | /// Check if the given identifier is a name of a register class. |
| 140 | /// |
| 141 | /// Return null if the name isn't a register class. |
| 142 | const TargetRegisterClass *getRegClass(StringRef Name); |
| 143 | |
| 144 | /// Check if the given identifier is a name of a register bank. |
| 145 | /// |
| 146 | /// Return null if the name isn't a register bank. |
| 147 | const RegisterBank *getRegBank(StringRef Name); |
| 148 | |
| 149 | PerTargetMIParsingState(const TargetSubtargetInfo &STI) |
| 150 | : Subtarget(STI) { |
| 151 | initNames2RegClasses(); |
| 152 | initNames2RegBanks(); |
| 153 | } |
| 154 | |
| 155 | ~PerTargetMIParsingState() = default; |
| 156 | |
| 157 | void setTarget(const TargetSubtargetInfo &NewSubtarget); |
| 158 | }; |
| 159 | |
| 160 | struct PerFunctionMIParsingState { |
| 161 | BumpPtrAllocator Allocator; |
| 162 | MachineFunction &MF; |
| 163 | SourceMgr *SM; |
| 164 | const SlotMapping &IRSlots; |
| 165 | PerTargetMIParsingState &Target; |
| 166 | |
| 167 | DenseMap<unsigned, MachineBasicBlock *> MBBSlots; |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 168 | DenseMap<Register, VRegInfo *> VRegInfos; |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 169 | StringMap<VRegInfo *> VRegInfosNamed; |
| 170 | DenseMap<unsigned, int> FixedStackObjectSlots; |
| 171 | DenseMap<unsigned, int> StackObjectSlots; |
| 172 | DenseMap<unsigned, unsigned> ConstantPoolSlots; |
| 173 | DenseMap<unsigned, unsigned> JumpTableSlots; |
| 174 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 175 | /// Maps from slot numbers to function's unnamed values. |
| 176 | DenseMap<unsigned, const Value *> Slots2Values; |
| 177 | |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 178 | PerFunctionMIParsingState(MachineFunction &MF, SourceMgr &SM, |
| 179 | const SlotMapping &IRSlots, |
| 180 | PerTargetMIParsingState &Target); |
| 181 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 182 | VRegInfo &getVRegInfo(Register Num); |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 183 | VRegInfo &getVRegInfoNamed(StringRef RegName); |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 184 | const Value *getIRValue(unsigned Slot); |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 185 | }; |
| 186 | |
| 187 | /// Parse the machine basic block definitions, and skip the machine |
| 188 | /// instructions. |
| 189 | /// |
| 190 | /// This function runs the first parsing pass on the machine function's body. |
| 191 | /// It parses only the machine basic block definitions and creates the machine |
| 192 | /// basic blocks in the given machine function. |
| 193 | /// |
| 194 | /// The machine instructions aren't parsed during the first pass because all |
| 195 | /// the machine basic blocks aren't defined yet - this makes it impossible to |
| 196 | /// resolve the machine basic block references. |
| 197 | /// |
| 198 | /// Return true if an error occurred. |
| 199 | bool parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS, |
| 200 | StringRef Src, SMDiagnostic &Error); |
| 201 | |
| 202 | /// Parse the machine instructions. |
| 203 | /// |
| 204 | /// This function runs the second parsing pass on the machine function's body. |
| 205 | /// It skips the machine basic block definitions and parses only the machine |
| 206 | /// instructions and basic block attributes like liveins and successors. |
| 207 | /// |
| 208 | /// The second parsing pass assumes that the first parsing pass already ran |
| 209 | /// on the given source string. |
| 210 | /// |
| 211 | /// Return true if an error occurred. |
| 212 | bool parseMachineInstructions(PerFunctionMIParsingState &PFS, StringRef Src, |
| 213 | SMDiagnostic &Error); |
| 214 | |
| 215 | bool parseMBBReference(PerFunctionMIParsingState &PFS, |
| 216 | MachineBasicBlock *&MBB, StringRef Src, |
| 217 | SMDiagnostic &Error); |
| 218 | |
| 219 | bool parseRegisterReference(PerFunctionMIParsingState &PFS, |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 220 | Register &Reg, StringRef Src, |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 221 | SMDiagnostic &Error); |
| 222 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 223 | bool parseNamedRegisterReference(PerFunctionMIParsingState &PFS, Register &Reg, |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 224 | StringRef Src, SMDiagnostic &Error); |
| 225 | |
| 226 | bool parseVirtualRegisterReference(PerFunctionMIParsingState &PFS, |
| 227 | VRegInfo *&Info, StringRef Src, |
| 228 | SMDiagnostic &Error); |
| 229 | |
| 230 | bool parseStackObjectReference(PerFunctionMIParsingState &PFS, int &FI, |
| 231 | StringRef Src, SMDiagnostic &Error); |
| 232 | |
| 233 | bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node, StringRef Src, |
| 234 | SMDiagnostic &Error); |
| 235 | |
| 236 | } // end namespace llvm |
| 237 | |
| 238 | #endif // LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H |