File: | llvm/lib/CodeGen/MIRParser/MIParser.cpp |
Warning: | line 2062, column 15 The left operand of '>=' is a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- MIParser.cpp - Machine instructions parser implementation ----------===// | ||||
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 implements the parsing of machine instructions. | ||||
10 | // | ||||
11 | //===----------------------------------------------------------------------===// | ||||
12 | |||||
13 | #include "llvm/CodeGen/MIRParser/MIParser.h" | ||||
14 | #include "MILexer.h" | ||||
15 | #include "llvm/ADT/APInt.h" | ||||
16 | #include "llvm/ADT/APSInt.h" | ||||
17 | #include "llvm/ADT/ArrayRef.h" | ||||
18 | #include "llvm/ADT/DenseMap.h" | ||||
19 | #include "llvm/ADT/None.h" | ||||
20 | #include "llvm/ADT/Optional.h" | ||||
21 | #include "llvm/ADT/SmallVector.h" | ||||
22 | #include "llvm/ADT/StringMap.h" | ||||
23 | #include "llvm/ADT/StringRef.h" | ||||
24 | #include "llvm/ADT/StringSwitch.h" | ||||
25 | #include "llvm/ADT/Twine.h" | ||||
26 | #include "llvm/Analysis/MemoryLocation.h" | ||||
27 | #include "llvm/AsmParser/Parser.h" | ||||
28 | #include "llvm/AsmParser/SlotMapping.h" | ||||
29 | #include "llvm/CodeGen/GlobalISel/RegisterBank.h" | ||||
30 | #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" | ||||
31 | #include "llvm/CodeGen/MIRFormatter.h" | ||||
32 | #include "llvm/CodeGen/MIRPrinter.h" | ||||
33 | #include "llvm/CodeGen/MachineBasicBlock.h" | ||||
34 | #include "llvm/CodeGen/MachineFrameInfo.h" | ||||
35 | #include "llvm/CodeGen/MachineFunction.h" | ||||
36 | #include "llvm/CodeGen/MachineInstr.h" | ||||
37 | #include "llvm/CodeGen/MachineInstrBuilder.h" | ||||
38 | #include "llvm/CodeGen/MachineMemOperand.h" | ||||
39 | #include "llvm/CodeGen/MachineOperand.h" | ||||
40 | #include "llvm/CodeGen/MachineRegisterInfo.h" | ||||
41 | #include "llvm/CodeGen/TargetInstrInfo.h" | ||||
42 | #include "llvm/CodeGen/TargetRegisterInfo.h" | ||||
43 | #include "llvm/CodeGen/TargetSubtargetInfo.h" | ||||
44 | #include "llvm/IR/BasicBlock.h" | ||||
45 | #include "llvm/IR/Constants.h" | ||||
46 | #include "llvm/IR/DataLayout.h" | ||||
47 | #include "llvm/IR/DebugInfoMetadata.h" | ||||
48 | #include "llvm/IR/DebugLoc.h" | ||||
49 | #include "llvm/IR/Function.h" | ||||
50 | #include "llvm/IR/InstrTypes.h" | ||||
51 | #include "llvm/IR/Instructions.h" | ||||
52 | #include "llvm/IR/Intrinsics.h" | ||||
53 | #include "llvm/IR/Metadata.h" | ||||
54 | #include "llvm/IR/Module.h" | ||||
55 | #include "llvm/IR/ModuleSlotTracker.h" | ||||
56 | #include "llvm/IR/Type.h" | ||||
57 | #include "llvm/IR/Value.h" | ||||
58 | #include "llvm/IR/ValueSymbolTable.h" | ||||
59 | #include "llvm/MC/LaneBitmask.h" | ||||
60 | #include "llvm/MC/MCContext.h" | ||||
61 | #include "llvm/MC/MCDwarf.h" | ||||
62 | #include "llvm/MC/MCInstrDesc.h" | ||||
63 | #include "llvm/MC/MCRegisterInfo.h" | ||||
64 | #include "llvm/Support/AtomicOrdering.h" | ||||
65 | #include "llvm/Support/BranchProbability.h" | ||||
66 | #include "llvm/Support/Casting.h" | ||||
67 | #include "llvm/Support/ErrorHandling.h" | ||||
68 | #include "llvm/Support/LowLevelTypeImpl.h" | ||||
69 | #include "llvm/Support/MemoryBuffer.h" | ||||
70 | #include "llvm/Support/SMLoc.h" | ||||
71 | #include "llvm/Support/SourceMgr.h" | ||||
72 | #include "llvm/Support/raw_ostream.h" | ||||
73 | #include "llvm/Target/TargetIntrinsicInfo.h" | ||||
74 | #include "llvm/Target/TargetMachine.h" | ||||
75 | #include <algorithm> | ||||
76 | #include <cassert> | ||||
77 | #include <cctype> | ||||
78 | #include <cstddef> | ||||
79 | #include <cstdint> | ||||
80 | #include <limits> | ||||
81 | #include <string> | ||||
82 | #include <utility> | ||||
83 | |||||
84 | using namespace llvm; | ||||
85 | |||||
86 | void PerTargetMIParsingState::setTarget( | ||||
87 | const TargetSubtargetInfo &NewSubtarget) { | ||||
88 | |||||
89 | // If the subtarget changed, over conservatively assume everything is invalid. | ||||
90 | if (&Subtarget == &NewSubtarget) | ||||
91 | return; | ||||
92 | |||||
93 | Names2InstrOpCodes.clear(); | ||||
94 | Names2Regs.clear(); | ||||
95 | Names2RegMasks.clear(); | ||||
96 | Names2SubRegIndices.clear(); | ||||
97 | Names2TargetIndices.clear(); | ||||
98 | Names2DirectTargetFlags.clear(); | ||||
99 | Names2BitmaskTargetFlags.clear(); | ||||
100 | Names2MMOTargetFlags.clear(); | ||||
101 | |||||
102 | initNames2RegClasses(); | ||||
103 | initNames2RegBanks(); | ||||
104 | } | ||||
105 | |||||
106 | void PerTargetMIParsingState::initNames2Regs() { | ||||
107 | if (!Names2Regs.empty()) | ||||
108 | return; | ||||
109 | |||||
110 | // The '%noreg' register is the register 0. | ||||
111 | Names2Regs.insert(std::make_pair("noreg", 0)); | ||||
112 | const auto *TRI = Subtarget.getRegisterInfo(); | ||||
113 | assert(TRI && "Expected target register info")(static_cast <bool> (TRI && "Expected target register info" ) ? void (0) : __assert_fail ("TRI && \"Expected target register info\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 113, __extension__ __PRETTY_FUNCTION__)); | ||||
114 | |||||
115 | for (unsigned I = 0, E = TRI->getNumRegs(); I < E; ++I) { | ||||
116 | bool WasInserted = | ||||
117 | Names2Regs.insert(std::make_pair(StringRef(TRI->getName(I)).lower(), I)) | ||||
118 | .second; | ||||
119 | (void)WasInserted; | ||||
120 | assert(WasInserted && "Expected registers to be unique case-insensitively")(static_cast <bool> (WasInserted && "Expected registers to be unique case-insensitively" ) ? void (0) : __assert_fail ("WasInserted && \"Expected registers to be unique case-insensitively\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 120, __extension__ __PRETTY_FUNCTION__)); | ||||
121 | } | ||||
122 | } | ||||
123 | |||||
124 | bool PerTargetMIParsingState::getRegisterByName(StringRef RegName, | ||||
125 | Register &Reg) { | ||||
126 | initNames2Regs(); | ||||
127 | auto RegInfo = Names2Regs.find(RegName); | ||||
128 | if (RegInfo == Names2Regs.end()) | ||||
129 | return true; | ||||
130 | Reg = RegInfo->getValue(); | ||||
131 | return false; | ||||
132 | } | ||||
133 | |||||
134 | void PerTargetMIParsingState::initNames2InstrOpCodes() { | ||||
135 | if (!Names2InstrOpCodes.empty()) | ||||
136 | return; | ||||
137 | const auto *TII = Subtarget.getInstrInfo(); | ||||
138 | assert(TII && "Expected target instruction info")(static_cast <bool> (TII && "Expected target instruction info" ) ? void (0) : __assert_fail ("TII && \"Expected target instruction info\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 138, __extension__ __PRETTY_FUNCTION__)); | ||||
139 | for (unsigned I = 0, E = TII->getNumOpcodes(); I < E; ++I) | ||||
140 | Names2InstrOpCodes.insert(std::make_pair(StringRef(TII->getName(I)), I)); | ||||
141 | } | ||||
142 | |||||
143 | bool PerTargetMIParsingState::parseInstrName(StringRef InstrName, | ||||
144 | unsigned &OpCode) { | ||||
145 | initNames2InstrOpCodes(); | ||||
146 | auto InstrInfo = Names2InstrOpCodes.find(InstrName); | ||||
147 | if (InstrInfo == Names2InstrOpCodes.end()) | ||||
148 | return true; | ||||
149 | OpCode = InstrInfo->getValue(); | ||||
150 | return false; | ||||
151 | } | ||||
152 | |||||
153 | void PerTargetMIParsingState::initNames2RegMasks() { | ||||
154 | if (!Names2RegMasks.empty()) | ||||
155 | return; | ||||
156 | const auto *TRI = Subtarget.getRegisterInfo(); | ||||
157 | assert(TRI && "Expected target register info")(static_cast <bool> (TRI && "Expected target register info" ) ? void (0) : __assert_fail ("TRI && \"Expected target register info\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 157, __extension__ __PRETTY_FUNCTION__)); | ||||
158 | ArrayRef<const uint32_t *> RegMasks = TRI->getRegMasks(); | ||||
159 | ArrayRef<const char *> RegMaskNames = TRI->getRegMaskNames(); | ||||
160 | assert(RegMasks.size() == RegMaskNames.size())(static_cast <bool> (RegMasks.size() == RegMaskNames.size ()) ? void (0) : __assert_fail ("RegMasks.size() == RegMaskNames.size()" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 160, __extension__ __PRETTY_FUNCTION__)); | ||||
161 | for (size_t I = 0, E = RegMasks.size(); I < E; ++I) | ||||
162 | Names2RegMasks.insert( | ||||
163 | std::make_pair(StringRef(RegMaskNames[I]).lower(), RegMasks[I])); | ||||
164 | } | ||||
165 | |||||
166 | const uint32_t *PerTargetMIParsingState::getRegMask(StringRef Identifier) { | ||||
167 | initNames2RegMasks(); | ||||
168 | auto RegMaskInfo = Names2RegMasks.find(Identifier); | ||||
169 | if (RegMaskInfo == Names2RegMasks.end()) | ||||
170 | return nullptr; | ||||
171 | return RegMaskInfo->getValue(); | ||||
172 | } | ||||
173 | |||||
174 | void PerTargetMIParsingState::initNames2SubRegIndices() { | ||||
175 | if (!Names2SubRegIndices.empty()) | ||||
176 | return; | ||||
177 | const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); | ||||
178 | for (unsigned I = 1, E = TRI->getNumSubRegIndices(); I < E; ++I) | ||||
179 | Names2SubRegIndices.insert( | ||||
180 | std::make_pair(TRI->getSubRegIndexName(I), I)); | ||||
181 | } | ||||
182 | |||||
183 | unsigned PerTargetMIParsingState::getSubRegIndex(StringRef Name) { | ||||
184 | initNames2SubRegIndices(); | ||||
185 | auto SubRegInfo = Names2SubRegIndices.find(Name); | ||||
186 | if (SubRegInfo == Names2SubRegIndices.end()) | ||||
187 | return 0; | ||||
188 | return SubRegInfo->getValue(); | ||||
189 | } | ||||
190 | |||||
191 | void PerTargetMIParsingState::initNames2TargetIndices() { | ||||
192 | if (!Names2TargetIndices.empty()) | ||||
193 | return; | ||||
194 | const auto *TII = Subtarget.getInstrInfo(); | ||||
195 | assert(TII && "Expected target instruction info")(static_cast <bool> (TII && "Expected target instruction info" ) ? void (0) : __assert_fail ("TII && \"Expected target instruction info\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 195, __extension__ __PRETTY_FUNCTION__)); | ||||
196 | auto Indices = TII->getSerializableTargetIndices(); | ||||
197 | for (const auto &I : Indices) | ||||
198 | Names2TargetIndices.insert(std::make_pair(StringRef(I.second), I.first)); | ||||
199 | } | ||||
200 | |||||
201 | bool PerTargetMIParsingState::getTargetIndex(StringRef Name, int &Index) { | ||||
202 | initNames2TargetIndices(); | ||||
203 | auto IndexInfo = Names2TargetIndices.find(Name); | ||||
204 | if (IndexInfo == Names2TargetIndices.end()) | ||||
205 | return true; | ||||
206 | Index = IndexInfo->second; | ||||
207 | return false; | ||||
208 | } | ||||
209 | |||||
210 | void PerTargetMIParsingState::initNames2DirectTargetFlags() { | ||||
211 | if (!Names2DirectTargetFlags.empty()) | ||||
212 | return; | ||||
213 | |||||
214 | const auto *TII = Subtarget.getInstrInfo(); | ||||
215 | assert(TII && "Expected target instruction info")(static_cast <bool> (TII && "Expected target instruction info" ) ? void (0) : __assert_fail ("TII && \"Expected target instruction info\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 215, __extension__ __PRETTY_FUNCTION__)); | ||||
216 | auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); | ||||
217 | for (const auto &I : Flags) | ||||
218 | Names2DirectTargetFlags.insert( | ||||
219 | std::make_pair(StringRef(I.second), I.first)); | ||||
220 | } | ||||
221 | |||||
222 | bool PerTargetMIParsingState::getDirectTargetFlag(StringRef Name, | ||||
223 | unsigned &Flag) { | ||||
224 | initNames2DirectTargetFlags(); | ||||
225 | auto FlagInfo = Names2DirectTargetFlags.find(Name); | ||||
226 | if (FlagInfo == Names2DirectTargetFlags.end()) | ||||
227 | return true; | ||||
228 | Flag = FlagInfo->second; | ||||
229 | return false; | ||||
230 | } | ||||
231 | |||||
232 | void PerTargetMIParsingState::initNames2BitmaskTargetFlags() { | ||||
233 | if (!Names2BitmaskTargetFlags.empty()) | ||||
234 | return; | ||||
235 | |||||
236 | const auto *TII = Subtarget.getInstrInfo(); | ||||
237 | assert(TII && "Expected target instruction info")(static_cast <bool> (TII && "Expected target instruction info" ) ? void (0) : __assert_fail ("TII && \"Expected target instruction info\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 237, __extension__ __PRETTY_FUNCTION__)); | ||||
238 | auto Flags = TII->getSerializableBitmaskMachineOperandTargetFlags(); | ||||
239 | for (const auto &I : Flags) | ||||
240 | Names2BitmaskTargetFlags.insert( | ||||
241 | std::make_pair(StringRef(I.second), I.first)); | ||||
242 | } | ||||
243 | |||||
244 | bool PerTargetMIParsingState::getBitmaskTargetFlag(StringRef Name, | ||||
245 | unsigned &Flag) { | ||||
246 | initNames2BitmaskTargetFlags(); | ||||
247 | auto FlagInfo = Names2BitmaskTargetFlags.find(Name); | ||||
248 | if (FlagInfo == Names2BitmaskTargetFlags.end()) | ||||
249 | return true; | ||||
250 | Flag = FlagInfo->second; | ||||
251 | return false; | ||||
252 | } | ||||
253 | |||||
254 | void PerTargetMIParsingState::initNames2MMOTargetFlags() { | ||||
255 | if (!Names2MMOTargetFlags.empty()) | ||||
256 | return; | ||||
257 | |||||
258 | const auto *TII = Subtarget.getInstrInfo(); | ||||
259 | assert(TII && "Expected target instruction info")(static_cast <bool> (TII && "Expected target instruction info" ) ? void (0) : __assert_fail ("TII && \"Expected target instruction info\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 259, __extension__ __PRETTY_FUNCTION__)); | ||||
260 | auto Flags = TII->getSerializableMachineMemOperandTargetFlags(); | ||||
261 | for (const auto &I : Flags) | ||||
262 | Names2MMOTargetFlags.insert(std::make_pair(StringRef(I.second), I.first)); | ||||
263 | } | ||||
264 | |||||
265 | bool PerTargetMIParsingState::getMMOTargetFlag(StringRef Name, | ||||
266 | MachineMemOperand::Flags &Flag) { | ||||
267 | initNames2MMOTargetFlags(); | ||||
268 | auto FlagInfo = Names2MMOTargetFlags.find(Name); | ||||
269 | if (FlagInfo == Names2MMOTargetFlags.end()) | ||||
270 | return true; | ||||
271 | Flag = FlagInfo->second; | ||||
272 | return false; | ||||
273 | } | ||||
274 | |||||
275 | void PerTargetMIParsingState::initNames2RegClasses() { | ||||
276 | if (!Names2RegClasses.empty()) | ||||
277 | return; | ||||
278 | |||||
279 | const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); | ||||
280 | for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) { | ||||
281 | const auto *RC = TRI->getRegClass(I); | ||||
282 | Names2RegClasses.insert( | ||||
283 | std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC)); | ||||
284 | } | ||||
285 | } | ||||
286 | |||||
287 | void PerTargetMIParsingState::initNames2RegBanks() { | ||||
288 | if (!Names2RegBanks.empty()) | ||||
289 | return; | ||||
290 | |||||
291 | const RegisterBankInfo *RBI = Subtarget.getRegBankInfo(); | ||||
292 | // If the target does not support GlobalISel, we may not have a | ||||
293 | // register bank info. | ||||
294 | if (!RBI) | ||||
295 | return; | ||||
296 | |||||
297 | for (unsigned I = 0, E = RBI->getNumRegBanks(); I < E; ++I) { | ||||
298 | const auto &RegBank = RBI->getRegBank(I); | ||||
299 | Names2RegBanks.insert( | ||||
300 | std::make_pair(StringRef(RegBank.getName()).lower(), &RegBank)); | ||||
301 | } | ||||
302 | } | ||||
303 | |||||
304 | const TargetRegisterClass * | ||||
305 | PerTargetMIParsingState::getRegClass(StringRef Name) { | ||||
306 | auto RegClassInfo = Names2RegClasses.find(Name); | ||||
307 | if (RegClassInfo == Names2RegClasses.end()) | ||||
308 | return nullptr; | ||||
309 | return RegClassInfo->getValue(); | ||||
310 | } | ||||
311 | |||||
312 | const RegisterBank *PerTargetMIParsingState::getRegBank(StringRef Name) { | ||||
313 | auto RegBankInfo = Names2RegBanks.find(Name); | ||||
314 | if (RegBankInfo == Names2RegBanks.end()) | ||||
315 | return nullptr; | ||||
316 | return RegBankInfo->getValue(); | ||||
317 | } | ||||
318 | |||||
319 | PerFunctionMIParsingState::PerFunctionMIParsingState(MachineFunction &MF, | ||||
320 | SourceMgr &SM, const SlotMapping &IRSlots, PerTargetMIParsingState &T) | ||||
321 | : MF(MF), SM(&SM), IRSlots(IRSlots), Target(T) { | ||||
322 | } | ||||
323 | |||||
324 | VRegInfo &PerFunctionMIParsingState::getVRegInfo(Register Num) { | ||||
325 | auto I = VRegInfos.insert(std::make_pair(Num, nullptr)); | ||||
326 | if (I.second) { | ||||
327 | MachineRegisterInfo &MRI = MF.getRegInfo(); | ||||
328 | VRegInfo *Info = new (Allocator) VRegInfo; | ||||
329 | Info->VReg = MRI.createIncompleteVirtualRegister(); | ||||
330 | I.first->second = Info; | ||||
331 | } | ||||
332 | return *I.first->second; | ||||
333 | } | ||||
334 | |||||
335 | VRegInfo &PerFunctionMIParsingState::getVRegInfoNamed(StringRef RegName) { | ||||
336 | assert(RegName != "" && "Expected named reg.")(static_cast <bool> (RegName != "" && "Expected named reg." ) ? void (0) : __assert_fail ("RegName != \"\" && \"Expected named reg.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 336, __extension__ __PRETTY_FUNCTION__)); | ||||
337 | |||||
338 | auto I = VRegInfosNamed.insert(std::make_pair(RegName.str(), nullptr)); | ||||
339 | if (I.second) { | ||||
340 | VRegInfo *Info = new (Allocator) VRegInfo; | ||||
341 | Info->VReg = MF.getRegInfo().createIncompleteVirtualRegister(RegName); | ||||
342 | I.first->second = Info; | ||||
343 | } | ||||
344 | return *I.first->second; | ||||
345 | } | ||||
346 | |||||
347 | static void mapValueToSlot(const Value *V, ModuleSlotTracker &MST, | ||||
348 | DenseMap<unsigned, const Value *> &Slots2Values) { | ||||
349 | int Slot = MST.getLocalSlot(V); | ||||
350 | if (Slot == -1) | ||||
351 | return; | ||||
352 | Slots2Values.insert(std::make_pair(unsigned(Slot), V)); | ||||
353 | } | ||||
354 | |||||
355 | /// Creates the mapping from slot numbers to function's unnamed IR values. | ||||
356 | static void initSlots2Values(const Function &F, | ||||
357 | DenseMap<unsigned, const Value *> &Slots2Values) { | ||||
358 | ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false); | ||||
359 | MST.incorporateFunction(F); | ||||
360 | for (const auto &Arg : F.args()) | ||||
361 | mapValueToSlot(&Arg, MST, Slots2Values); | ||||
362 | for (const auto &BB : F) { | ||||
363 | mapValueToSlot(&BB, MST, Slots2Values); | ||||
364 | for (const auto &I : BB) | ||||
365 | mapValueToSlot(&I, MST, Slots2Values); | ||||
366 | } | ||||
367 | } | ||||
368 | |||||
369 | const Value* PerFunctionMIParsingState::getIRValue(unsigned Slot) { | ||||
370 | if (Slots2Values.empty()) | ||||
371 | initSlots2Values(MF.getFunction(), Slots2Values); | ||||
372 | return Slots2Values.lookup(Slot); | ||||
373 | } | ||||
374 | |||||
375 | namespace { | ||||
376 | |||||
377 | /// A wrapper struct around the 'MachineOperand' struct that includes a source | ||||
378 | /// range and other attributes. | ||||
379 | struct ParsedMachineOperand { | ||||
380 | MachineOperand Operand; | ||||
381 | StringRef::iterator Begin; | ||||
382 | StringRef::iterator End; | ||||
383 | Optional<unsigned> TiedDefIdx; | ||||
384 | |||||
385 | ParsedMachineOperand(const MachineOperand &Operand, StringRef::iterator Begin, | ||||
386 | StringRef::iterator End, Optional<unsigned> &TiedDefIdx) | ||||
387 | : Operand(Operand), Begin(Begin), End(End), TiedDefIdx(TiedDefIdx) { | ||||
388 | if (TiedDefIdx) | ||||
389 | assert(Operand.isReg() && Operand.isUse() &&(static_cast <bool> (Operand.isReg() && Operand .isUse() && "Only used register operands can be tied" ) ? void (0) : __assert_fail ("Operand.isReg() && Operand.isUse() && \"Only used register operands can be tied\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 390, __extension__ __PRETTY_FUNCTION__)) | ||||
390 | "Only used register operands can be tied")(static_cast <bool> (Operand.isReg() && Operand .isUse() && "Only used register operands can be tied" ) ? void (0) : __assert_fail ("Operand.isReg() && Operand.isUse() && \"Only used register operands can be tied\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 390, __extension__ __PRETTY_FUNCTION__)); | ||||
391 | } | ||||
392 | }; | ||||
393 | |||||
394 | class MIParser { | ||||
395 | MachineFunction &MF; | ||||
396 | SMDiagnostic &Error; | ||||
397 | StringRef Source, CurrentSource; | ||||
398 | SMRange SourceRange; | ||||
399 | MIToken Token; | ||||
400 | PerFunctionMIParsingState &PFS; | ||||
401 | /// Maps from slot numbers to function's unnamed basic blocks. | ||||
402 | DenseMap<unsigned, const BasicBlock *> Slots2BasicBlocks; | ||||
403 | |||||
404 | public: | ||||
405 | MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error, | ||||
406 | StringRef Source); | ||||
407 | MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error, | ||||
408 | StringRef Source, SMRange SourceRange); | ||||
409 | |||||
410 | /// \p SkipChar gives the number of characters to skip before looking | ||||
411 | /// for the next token. | ||||
412 | void lex(unsigned SkipChar = 0); | ||||
413 | |||||
414 | /// Report an error at the current location with the given message. | ||||
415 | /// | ||||
416 | /// This function always return true. | ||||
417 | bool error(const Twine &Msg); | ||||
418 | |||||
419 | /// Report an error at the given location with the given message. | ||||
420 | /// | ||||
421 | /// This function always return true. | ||||
422 | bool error(StringRef::iterator Loc, const Twine &Msg); | ||||
423 | |||||
424 | bool | ||||
425 | parseBasicBlockDefinitions(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots); | ||||
426 | bool parseBasicBlocks(); | ||||
427 | bool parse(MachineInstr *&MI); | ||||
428 | bool parseStandaloneMBB(MachineBasicBlock *&MBB); | ||||
429 | bool parseStandaloneNamedRegister(Register &Reg); | ||||
430 | bool parseStandaloneVirtualRegister(VRegInfo *&Info); | ||||
431 | bool parseStandaloneRegister(Register &Reg); | ||||
432 | bool parseStandaloneStackObject(int &FI); | ||||
433 | bool parseStandaloneMDNode(MDNode *&Node); | ||||
434 | bool parseMachineMetadata(); | ||||
435 | bool parseMDTuple(MDNode *&MD, bool IsDistinct); | ||||
436 | bool parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts); | ||||
437 | bool parseMetadata(Metadata *&MD); | ||||
438 | |||||
439 | bool | ||||
440 | parseBasicBlockDefinition(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots); | ||||
441 | bool parseBasicBlock(MachineBasicBlock &MBB, | ||||
442 | MachineBasicBlock *&AddFalthroughFrom); | ||||
443 | bool parseBasicBlockLiveins(MachineBasicBlock &MBB); | ||||
444 | bool parseBasicBlockSuccessors(MachineBasicBlock &MBB); | ||||
445 | |||||
446 | bool parseNamedRegister(Register &Reg); | ||||
447 | bool parseVirtualRegister(VRegInfo *&Info); | ||||
448 | bool parseNamedVirtualRegister(VRegInfo *&Info); | ||||
449 | bool parseRegister(Register &Reg, VRegInfo *&VRegInfo); | ||||
450 | bool parseRegisterFlag(unsigned &Flags); | ||||
451 | bool parseRegisterClassOrBank(VRegInfo &RegInfo); | ||||
452 | bool parseSubRegisterIndex(unsigned &SubReg); | ||||
453 | bool parseRegisterTiedDefIndex(unsigned &TiedDefIdx); | ||||
454 | bool parseRegisterOperand(MachineOperand &Dest, | ||||
455 | Optional<unsigned> &TiedDefIdx, bool IsDef = false); | ||||
456 | bool parseImmediateOperand(MachineOperand &Dest); | ||||
457 | bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue, | ||||
458 | const Constant *&C); | ||||
459 | bool parseIRConstant(StringRef::iterator Loc, const Constant *&C); | ||||
460 | bool parseLowLevelType(StringRef::iterator Loc, LLT &Ty); | ||||
461 | bool parseTypedImmediateOperand(MachineOperand &Dest); | ||||
462 | bool parseFPImmediateOperand(MachineOperand &Dest); | ||||
463 | bool parseMBBReference(MachineBasicBlock *&MBB); | ||||
464 | bool parseMBBOperand(MachineOperand &Dest); | ||||
465 | bool parseStackFrameIndex(int &FI); | ||||
466 | bool parseStackObjectOperand(MachineOperand &Dest); | ||||
467 | bool parseFixedStackFrameIndex(int &FI); | ||||
468 | bool parseFixedStackObjectOperand(MachineOperand &Dest); | ||||
469 | bool parseGlobalValue(GlobalValue *&GV); | ||||
470 | bool parseGlobalAddressOperand(MachineOperand &Dest); | ||||
471 | bool parseConstantPoolIndexOperand(MachineOperand &Dest); | ||||
472 | bool parseSubRegisterIndexOperand(MachineOperand &Dest); | ||||
473 | bool parseJumpTableIndexOperand(MachineOperand &Dest); | ||||
474 | bool parseExternalSymbolOperand(MachineOperand &Dest); | ||||
475 | bool parseMCSymbolOperand(MachineOperand &Dest); | ||||
476 | bool parseMDNode(MDNode *&Node); | ||||
477 | bool parseDIExpression(MDNode *&Expr); | ||||
478 | bool parseDILocation(MDNode *&Expr); | ||||
479 | bool parseMetadataOperand(MachineOperand &Dest); | ||||
480 | bool parseCFIOffset(int &Offset); | ||||
481 | bool parseCFIRegister(Register &Reg); | ||||
482 | bool parseCFIAddressSpace(unsigned &AddressSpace); | ||||
483 | bool parseCFIEscapeValues(std::string& Values); | ||||
484 | bool parseCFIOperand(MachineOperand &Dest); | ||||
485 | bool parseIRBlock(BasicBlock *&BB, const Function &F); | ||||
486 | bool parseBlockAddressOperand(MachineOperand &Dest); | ||||
487 | bool parseIntrinsicOperand(MachineOperand &Dest); | ||||
488 | bool parsePredicateOperand(MachineOperand &Dest); | ||||
489 | bool parseShuffleMaskOperand(MachineOperand &Dest); | ||||
490 | bool parseTargetIndexOperand(MachineOperand &Dest); | ||||
491 | bool parseCustomRegisterMaskOperand(MachineOperand &Dest); | ||||
492 | bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest); | ||||
493 | bool parseMachineOperand(const unsigned OpCode, const unsigned OpIdx, | ||||
494 | MachineOperand &Dest, | ||||
495 | Optional<unsigned> &TiedDefIdx); | ||||
496 | bool parseMachineOperandAndTargetFlags(const unsigned OpCode, | ||||
497 | const unsigned OpIdx, | ||||
498 | MachineOperand &Dest, | ||||
499 | Optional<unsigned> &TiedDefIdx); | ||||
500 | bool parseOffset(int64_t &Offset); | ||||
501 | bool parseAlignment(unsigned &Alignment); | ||||
502 | bool parseAddrspace(unsigned &Addrspace); | ||||
503 | bool parseSectionID(Optional<MBBSectionID> &SID); | ||||
504 | bool parseOperandsOffset(MachineOperand &Op); | ||||
505 | bool parseIRValue(const Value *&V); | ||||
506 | bool parseMemoryOperandFlag(MachineMemOperand::Flags &Flags); | ||||
507 | bool parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV); | ||||
508 | bool parseMachinePointerInfo(MachinePointerInfo &Dest); | ||||
509 | bool parseOptionalScope(LLVMContext &Context, SyncScope::ID &SSID); | ||||
510 | bool parseOptionalAtomicOrdering(AtomicOrdering &Order); | ||||
511 | bool parseMachineMemoryOperand(MachineMemOperand *&Dest); | ||||
512 | bool parsePreOrPostInstrSymbol(MCSymbol *&Symbol); | ||||
513 | bool parseHeapAllocMarker(MDNode *&Node); | ||||
514 | |||||
515 | bool parseTargetImmMnemonic(const unsigned OpCode, const unsigned OpIdx, | ||||
516 | MachineOperand &Dest, const MIRFormatter &MF); | ||||
517 | |||||
518 | private: | ||||
519 | /// Convert the integer literal in the current token into an unsigned integer. | ||||
520 | /// | ||||
521 | /// Return true if an error occurred. | ||||
522 | bool getUnsigned(unsigned &Result); | ||||
523 | |||||
524 | /// Convert the integer literal in the current token into an uint64. | ||||
525 | /// | ||||
526 | /// Return true if an error occurred. | ||||
527 | bool getUint64(uint64_t &Result); | ||||
528 | |||||
529 | /// Convert the hexadecimal literal in the current token into an unsigned | ||||
530 | /// APInt with a minimum bitwidth required to represent the value. | ||||
531 | /// | ||||
532 | /// Return true if the literal does not represent an integer value. | ||||
533 | bool getHexUint(APInt &Result); | ||||
534 | |||||
535 | /// If the current token is of the given kind, consume it and return false. | ||||
536 | /// Otherwise report an error and return true. | ||||
537 | bool expectAndConsume(MIToken::TokenKind TokenKind); | ||||
538 | |||||
539 | /// If the current token is of the given kind, consume it and return true. | ||||
540 | /// Otherwise return false. | ||||
541 | bool consumeIfPresent(MIToken::TokenKind TokenKind); | ||||
542 | |||||
543 | bool parseInstruction(unsigned &OpCode, unsigned &Flags); | ||||
544 | |||||
545 | bool assignRegisterTies(MachineInstr &MI, | ||||
546 | ArrayRef<ParsedMachineOperand> Operands); | ||||
547 | |||||
548 | bool verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands, | ||||
549 | const MCInstrDesc &MCID); | ||||
550 | |||||
551 | const BasicBlock *getIRBlock(unsigned Slot); | ||||
552 | const BasicBlock *getIRBlock(unsigned Slot, const Function &F); | ||||
553 | |||||
554 | /// Get or create an MCSymbol for a given name. | ||||
555 | MCSymbol *getOrCreateMCSymbol(StringRef Name); | ||||
556 | |||||
557 | /// parseStringConstant | ||||
558 | /// ::= StringConstant | ||||
559 | bool parseStringConstant(std::string &Result); | ||||
560 | |||||
561 | /// Map the location in the MI string to the corresponding location specified | ||||
562 | /// in `SourceRange`. | ||||
563 | SMLoc mapSMLoc(StringRef::iterator Loc); | ||||
564 | }; | ||||
565 | |||||
566 | } // end anonymous namespace | ||||
567 | |||||
568 | MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error, | ||||
569 | StringRef Source) | ||||
570 | : MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source), PFS(PFS) | ||||
571 | {} | ||||
572 | |||||
573 | MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error, | ||||
574 | StringRef Source, SMRange SourceRange) | ||||
575 | : MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source), | ||||
576 | SourceRange(SourceRange), PFS(PFS) {} | ||||
577 | |||||
578 | void MIParser::lex(unsigned SkipChar) { | ||||
579 | CurrentSource = lexMIToken( | ||||
580 | CurrentSource.slice(SkipChar, StringRef::npos), Token, | ||||
581 | [this](StringRef::iterator Loc, const Twine &Msg) { error(Loc, Msg); }); | ||||
582 | } | ||||
583 | |||||
584 | bool MIParser::error(const Twine &Msg) { return error(Token.location(), Msg); } | ||||
585 | |||||
586 | bool MIParser::error(StringRef::iterator Loc, const Twine &Msg) { | ||||
587 | const SourceMgr &SM = *PFS.SM; | ||||
588 | assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size()))(static_cast <bool> (Loc >= Source.data() && Loc <= (Source.data() + Source.size())) ? void (0) : __assert_fail ("Loc >= Source.data() && Loc <= (Source.data() + Source.size())" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 588, __extension__ __PRETTY_FUNCTION__)); | ||||
589 | const MemoryBuffer &Buffer = *SM.getMemoryBuffer(SM.getMainFileID()); | ||||
590 | if (Loc >= Buffer.getBufferStart() && Loc <= Buffer.getBufferEnd()) { | ||||
591 | // Create an ordinary diagnostic when the source manager's buffer is the | ||||
592 | // source string. | ||||
593 | Error = SM.GetMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg); | ||||
594 | return true; | ||||
595 | } | ||||
596 | // Create a diagnostic for a YAML string literal. | ||||
597 | Error = SMDiagnostic(SM, SMLoc(), Buffer.getBufferIdentifier(), 1, | ||||
598 | Loc - Source.data(), SourceMgr::DK_Error, Msg.str(), | ||||
599 | Source, None, None); | ||||
600 | return true; | ||||
601 | } | ||||
602 | |||||
603 | SMLoc MIParser::mapSMLoc(StringRef::iterator Loc) { | ||||
604 | assert(SourceRange.isValid() && "Invalid source range")(static_cast <bool> (SourceRange.isValid() && "Invalid source range" ) ? void (0) : __assert_fail ("SourceRange.isValid() && \"Invalid source range\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 604, __extension__ __PRETTY_FUNCTION__)); | ||||
605 | assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size()))(static_cast <bool> (Loc >= Source.data() && Loc <= (Source.data() + Source.size())) ? void (0) : __assert_fail ("Loc >= Source.data() && Loc <= (Source.data() + Source.size())" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 605, __extension__ __PRETTY_FUNCTION__)); | ||||
606 | return SMLoc::getFromPointer(SourceRange.Start.getPointer() + | ||||
607 | (Loc - Source.data())); | ||||
608 | } | ||||
609 | |||||
610 | typedef function_ref<bool(StringRef::iterator Loc, const Twine &)> | ||||
611 | ErrorCallbackType; | ||||
612 | |||||
613 | static const char *toString(MIToken::TokenKind TokenKind) { | ||||
614 | switch (TokenKind) { | ||||
615 | case MIToken::comma: | ||||
616 | return "','"; | ||||
617 | case MIToken::equal: | ||||
618 | return "'='"; | ||||
619 | case MIToken::colon: | ||||
620 | return "':'"; | ||||
621 | case MIToken::lparen: | ||||
622 | return "'('"; | ||||
623 | case MIToken::rparen: | ||||
624 | return "')'"; | ||||
625 | default: | ||||
626 | return "<unknown token>"; | ||||
627 | } | ||||
628 | } | ||||
629 | |||||
630 | bool MIParser::expectAndConsume(MIToken::TokenKind TokenKind) { | ||||
631 | if (Token.isNot(TokenKind)) | ||||
632 | return error(Twine("expected ") + toString(TokenKind)); | ||||
633 | lex(); | ||||
634 | return false; | ||||
635 | } | ||||
636 | |||||
637 | bool MIParser::consumeIfPresent(MIToken::TokenKind TokenKind) { | ||||
638 | if (Token.isNot(TokenKind)) | ||||
639 | return false; | ||||
640 | lex(); | ||||
641 | return true; | ||||
642 | } | ||||
643 | |||||
644 | // Parse Machine Basic Block Section ID. | ||||
645 | bool MIParser::parseSectionID(Optional<MBBSectionID> &SID) { | ||||
646 | assert(Token.is(MIToken::kw_bbsections))(static_cast <bool> (Token.is(MIToken::kw_bbsections)) ? void (0) : __assert_fail ("Token.is(MIToken::kw_bbsections)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 646, __extension__ __PRETTY_FUNCTION__)); | ||||
647 | lex(); | ||||
648 | if (Token.is(MIToken::IntegerLiteral)) { | ||||
649 | unsigned Value = 0; | ||||
650 | if (getUnsigned(Value)) | ||||
651 | return error("Unknown Section ID"); | ||||
652 | SID = MBBSectionID{Value}; | ||||
653 | } else { | ||||
654 | const StringRef &S = Token.stringValue(); | ||||
655 | if (S == "Exception") | ||||
656 | SID = MBBSectionID::ExceptionSectionID; | ||||
657 | else if (S == "Cold") | ||||
658 | SID = MBBSectionID::ColdSectionID; | ||||
659 | else | ||||
660 | return error("Unknown Section ID"); | ||||
661 | } | ||||
662 | lex(); | ||||
663 | return false; | ||||
664 | } | ||||
665 | |||||
666 | bool MIParser::parseBasicBlockDefinition( | ||||
667 | DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) { | ||||
668 | assert(Token.is(MIToken::MachineBasicBlockLabel))(static_cast <bool> (Token.is(MIToken::MachineBasicBlockLabel )) ? void (0) : __assert_fail ("Token.is(MIToken::MachineBasicBlockLabel)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 668, __extension__ __PRETTY_FUNCTION__)); | ||||
669 | unsigned ID = 0; | ||||
670 | if (getUnsigned(ID)) | ||||
671 | return true; | ||||
672 | auto Loc = Token.location(); | ||||
673 | auto Name = Token.stringValue(); | ||||
674 | lex(); | ||||
675 | bool HasAddressTaken = false; | ||||
676 | bool IsLandingPad = false; | ||||
677 | bool IsEHFuncletEntry = false; | ||||
678 | Optional<MBBSectionID> SectionID; | ||||
679 | unsigned Alignment = 0; | ||||
680 | BasicBlock *BB = nullptr; | ||||
681 | if (consumeIfPresent(MIToken::lparen)) { | ||||
682 | do { | ||||
683 | // TODO: Report an error when multiple same attributes are specified. | ||||
684 | switch (Token.kind()) { | ||||
685 | case MIToken::kw_address_taken: | ||||
686 | HasAddressTaken = true; | ||||
687 | lex(); | ||||
688 | break; | ||||
689 | case MIToken::kw_landing_pad: | ||||
690 | IsLandingPad = true; | ||||
691 | lex(); | ||||
692 | break; | ||||
693 | case MIToken::kw_ehfunclet_entry: | ||||
694 | IsEHFuncletEntry = true; | ||||
695 | lex(); | ||||
696 | break; | ||||
697 | case MIToken::kw_align: | ||||
698 | if (parseAlignment(Alignment)) | ||||
699 | return true; | ||||
700 | break; | ||||
701 | case MIToken::IRBlock: | ||||
702 | // TODO: Report an error when both name and ir block are specified. | ||||
703 | if (parseIRBlock(BB, MF.getFunction())) | ||||
704 | return true; | ||||
705 | lex(); | ||||
706 | break; | ||||
707 | case MIToken::kw_bbsections: | ||||
708 | if (parseSectionID(SectionID)) | ||||
709 | return true; | ||||
710 | break; | ||||
711 | default: | ||||
712 | break; | ||||
713 | } | ||||
714 | } while (consumeIfPresent(MIToken::comma)); | ||||
715 | if (expectAndConsume(MIToken::rparen)) | ||||
716 | return true; | ||||
717 | } | ||||
718 | if (expectAndConsume(MIToken::colon)) | ||||
719 | return true; | ||||
720 | |||||
721 | if (!Name.empty()) { | ||||
722 | BB = dyn_cast_or_null<BasicBlock>( | ||||
723 | MF.getFunction().getValueSymbolTable()->lookup(Name)); | ||||
724 | if (!BB) | ||||
725 | return error(Loc, Twine("basic block '") + Name + | ||||
726 | "' is not defined in the function '" + | ||||
727 | MF.getName() + "'"); | ||||
728 | } | ||||
729 | auto *MBB = MF.CreateMachineBasicBlock(BB); | ||||
730 | MF.insert(MF.end(), MBB); | ||||
731 | bool WasInserted = MBBSlots.insert(std::make_pair(ID, MBB)).second; | ||||
732 | if (!WasInserted) | ||||
733 | return error(Loc, Twine("redefinition of machine basic block with id #") + | ||||
734 | Twine(ID)); | ||||
735 | if (Alignment) | ||||
736 | MBB->setAlignment(Align(Alignment)); | ||||
737 | if (HasAddressTaken) | ||||
738 | MBB->setHasAddressTaken(); | ||||
739 | MBB->setIsEHPad(IsLandingPad); | ||||
740 | MBB->setIsEHFuncletEntry(IsEHFuncletEntry); | ||||
741 | if (SectionID.hasValue()) { | ||||
742 | MBB->setSectionID(SectionID.getValue()); | ||||
743 | MF.setBBSectionsType(BasicBlockSection::List); | ||||
744 | } | ||||
745 | return false; | ||||
746 | } | ||||
747 | |||||
748 | bool MIParser::parseBasicBlockDefinitions( | ||||
749 | DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) { | ||||
750 | lex(); | ||||
751 | // Skip until the first machine basic block. | ||||
752 | while (Token.is(MIToken::Newline)) | ||||
753 | lex(); | ||||
754 | if (Token.isErrorOrEOF()) | ||||
755 | return Token.isError(); | ||||
756 | if (Token.isNot(MIToken::MachineBasicBlockLabel)) | ||||
757 | return error("expected a basic block definition before instructions"); | ||||
758 | unsigned BraceDepth = 0; | ||||
759 | do { | ||||
760 | if (parseBasicBlockDefinition(MBBSlots)) | ||||
761 | return true; | ||||
762 | bool IsAfterNewline = false; | ||||
763 | // Skip until the next machine basic block. | ||||
764 | while (true) { | ||||
765 | if ((Token.is(MIToken::MachineBasicBlockLabel) && IsAfterNewline) || | ||||
766 | Token.isErrorOrEOF()) | ||||
767 | break; | ||||
768 | else if (Token.is(MIToken::MachineBasicBlockLabel)) | ||||
769 | return error("basic block definition should be located at the start of " | ||||
770 | "the line"); | ||||
771 | else if (consumeIfPresent(MIToken::Newline)) { | ||||
772 | IsAfterNewline = true; | ||||
773 | continue; | ||||
774 | } | ||||
775 | IsAfterNewline = false; | ||||
776 | if (Token.is(MIToken::lbrace)) | ||||
777 | ++BraceDepth; | ||||
778 | if (Token.is(MIToken::rbrace)) { | ||||
779 | if (!BraceDepth) | ||||
780 | return error("extraneous closing brace ('}')"); | ||||
781 | --BraceDepth; | ||||
782 | } | ||||
783 | lex(); | ||||
784 | } | ||||
785 | // Verify that we closed all of the '{' at the end of a file or a block. | ||||
786 | if (!Token.isError() && BraceDepth) | ||||
787 | return error("expected '}'"); // FIXME: Report a note that shows '{'. | ||||
788 | } while (!Token.isErrorOrEOF()); | ||||
789 | return Token.isError(); | ||||
790 | } | ||||
791 | |||||
792 | bool MIParser::parseBasicBlockLiveins(MachineBasicBlock &MBB) { | ||||
793 | assert(Token.is(MIToken::kw_liveins))(static_cast <bool> (Token.is(MIToken::kw_liveins)) ? void (0) : __assert_fail ("Token.is(MIToken::kw_liveins)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 793, __extension__ __PRETTY_FUNCTION__)); | ||||
794 | lex(); | ||||
795 | if (expectAndConsume(MIToken::colon)) | ||||
796 | return true; | ||||
797 | if (Token.isNewlineOrEOF()) // Allow an empty list of liveins. | ||||
798 | return false; | ||||
799 | do { | ||||
800 | if (Token.isNot(MIToken::NamedRegister)) | ||||
801 | return error("expected a named register"); | ||||
802 | Register Reg; | ||||
803 | if (parseNamedRegister(Reg)) | ||||
804 | return true; | ||||
805 | lex(); | ||||
806 | LaneBitmask Mask = LaneBitmask::getAll(); | ||||
807 | if (consumeIfPresent(MIToken::colon)) { | ||||
808 | // Parse lane mask. | ||||
809 | if (Token.isNot(MIToken::IntegerLiteral) && | ||||
810 | Token.isNot(MIToken::HexLiteral)) | ||||
811 | return error("expected a lane mask"); | ||||
812 | static_assert(sizeof(LaneBitmask::Type) == sizeof(uint64_t), | ||||
813 | "Use correct get-function for lane mask"); | ||||
814 | LaneBitmask::Type V; | ||||
815 | if (getUint64(V)) | ||||
816 | return error("invalid lane mask value"); | ||||
817 | Mask = LaneBitmask(V); | ||||
818 | lex(); | ||||
819 | } | ||||
820 | MBB.addLiveIn(Reg, Mask); | ||||
821 | } while (consumeIfPresent(MIToken::comma)); | ||||
822 | return false; | ||||
823 | } | ||||
824 | |||||
825 | bool MIParser::parseBasicBlockSuccessors(MachineBasicBlock &MBB) { | ||||
826 | assert(Token.is(MIToken::kw_successors))(static_cast <bool> (Token.is(MIToken::kw_successors)) ? void (0) : __assert_fail ("Token.is(MIToken::kw_successors)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 826, __extension__ __PRETTY_FUNCTION__)); | ||||
827 | lex(); | ||||
828 | if (expectAndConsume(MIToken::colon)) | ||||
829 | return true; | ||||
830 | if (Token.isNewlineOrEOF()) // Allow an empty list of successors. | ||||
831 | return false; | ||||
832 | do { | ||||
833 | if (Token.isNot(MIToken::MachineBasicBlock)) | ||||
834 | return error("expected a machine basic block reference"); | ||||
835 | MachineBasicBlock *SuccMBB = nullptr; | ||||
836 | if (parseMBBReference(SuccMBB)) | ||||
837 | return true; | ||||
838 | lex(); | ||||
839 | unsigned Weight = 0; | ||||
840 | if (consumeIfPresent(MIToken::lparen)) { | ||||
841 | if (Token.isNot(MIToken::IntegerLiteral) && | ||||
842 | Token.isNot(MIToken::HexLiteral)) | ||||
843 | return error("expected an integer literal after '('"); | ||||
844 | if (getUnsigned(Weight)) | ||||
845 | return true; | ||||
846 | lex(); | ||||
847 | if (expectAndConsume(MIToken::rparen)) | ||||
848 | return true; | ||||
849 | } | ||||
850 | MBB.addSuccessor(SuccMBB, BranchProbability::getRaw(Weight)); | ||||
851 | } while (consumeIfPresent(MIToken::comma)); | ||||
852 | MBB.normalizeSuccProbs(); | ||||
853 | return false; | ||||
854 | } | ||||
855 | |||||
856 | bool MIParser::parseBasicBlock(MachineBasicBlock &MBB, | ||||
857 | MachineBasicBlock *&AddFalthroughFrom) { | ||||
858 | // Skip the definition. | ||||
859 | assert(Token.is(MIToken::MachineBasicBlockLabel))(static_cast <bool> (Token.is(MIToken::MachineBasicBlockLabel )) ? void (0) : __assert_fail ("Token.is(MIToken::MachineBasicBlockLabel)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 859, __extension__ __PRETTY_FUNCTION__)); | ||||
860 | lex(); | ||||
861 | if (consumeIfPresent(MIToken::lparen)) { | ||||
862 | while (Token.isNot(MIToken::rparen) && !Token.isErrorOrEOF()) | ||||
863 | lex(); | ||||
864 | consumeIfPresent(MIToken::rparen); | ||||
865 | } | ||||
866 | consumeIfPresent(MIToken::colon); | ||||
867 | |||||
868 | // Parse the liveins and successors. | ||||
869 | // N.B: Multiple lists of successors and liveins are allowed and they're | ||||
870 | // merged into one. | ||||
871 | // Example: | ||||
872 | // liveins: %edi | ||||
873 | // liveins: %esi | ||||
874 | // | ||||
875 | // is equivalent to | ||||
876 | // liveins: %edi, %esi | ||||
877 | bool ExplicitSuccessors = false; | ||||
878 | while (true) { | ||||
879 | if (Token.is(MIToken::kw_successors)) { | ||||
880 | if (parseBasicBlockSuccessors(MBB)) | ||||
881 | return true; | ||||
882 | ExplicitSuccessors = true; | ||||
883 | } else if (Token.is(MIToken::kw_liveins)) { | ||||
884 | if (parseBasicBlockLiveins(MBB)) | ||||
885 | return true; | ||||
886 | } else if (consumeIfPresent(MIToken::Newline)) { | ||||
887 | continue; | ||||
888 | } else | ||||
889 | break; | ||||
890 | if (!Token.isNewlineOrEOF()) | ||||
891 | return error("expected line break at the end of a list"); | ||||
892 | lex(); | ||||
893 | } | ||||
894 | |||||
895 | // Parse the instructions. | ||||
896 | bool IsInBundle = false; | ||||
897 | MachineInstr *PrevMI = nullptr; | ||||
898 | while (!Token.is(MIToken::MachineBasicBlockLabel) && | ||||
899 | !Token.is(MIToken::Eof)) { | ||||
900 | if (consumeIfPresent(MIToken::Newline)) | ||||
901 | continue; | ||||
902 | if (consumeIfPresent(MIToken::rbrace)) { | ||||
903 | // The first parsing pass should verify that all closing '}' have an | ||||
904 | // opening '{'. | ||||
905 | assert(IsInBundle)(static_cast <bool> (IsInBundle) ? void (0) : __assert_fail ("IsInBundle", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 905, __extension__ __PRETTY_FUNCTION__)); | ||||
906 | IsInBundle = false; | ||||
907 | continue; | ||||
908 | } | ||||
909 | MachineInstr *MI = nullptr; | ||||
910 | if (parse(MI)) | ||||
911 | return true; | ||||
912 | MBB.insert(MBB.end(), MI); | ||||
913 | if (IsInBundle) { | ||||
914 | PrevMI->setFlag(MachineInstr::BundledSucc); | ||||
915 | MI->setFlag(MachineInstr::BundledPred); | ||||
916 | } | ||||
917 | PrevMI = MI; | ||||
918 | if (Token.is(MIToken::lbrace)) { | ||||
919 | if (IsInBundle) | ||||
920 | return error("nested instruction bundles are not allowed"); | ||||
921 | lex(); | ||||
922 | // This instruction is the start of the bundle. | ||||
923 | MI->setFlag(MachineInstr::BundledSucc); | ||||
924 | IsInBundle = true; | ||||
925 | if (!Token.is(MIToken::Newline)) | ||||
926 | // The next instruction can be on the same line. | ||||
927 | continue; | ||||
928 | } | ||||
929 | assert(Token.isNewlineOrEOF() && "MI is not fully parsed")(static_cast <bool> (Token.isNewlineOrEOF() && "MI is not fully parsed" ) ? void (0) : __assert_fail ("Token.isNewlineOrEOF() && \"MI is not fully parsed\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 929, __extension__ __PRETTY_FUNCTION__)); | ||||
930 | lex(); | ||||
931 | } | ||||
932 | |||||
933 | // Construct successor list by searching for basic block machine operands. | ||||
934 | if (!ExplicitSuccessors) { | ||||
935 | SmallVector<MachineBasicBlock*,4> Successors; | ||||
936 | bool IsFallthrough; | ||||
937 | guessSuccessors(MBB, Successors, IsFallthrough); | ||||
938 | for (MachineBasicBlock *Succ : Successors) | ||||
939 | MBB.addSuccessor(Succ); | ||||
940 | |||||
941 | if (IsFallthrough) { | ||||
942 | AddFalthroughFrom = &MBB; | ||||
943 | } else { | ||||
944 | MBB.normalizeSuccProbs(); | ||||
945 | } | ||||
946 | } | ||||
947 | |||||
948 | return false; | ||||
949 | } | ||||
950 | |||||
951 | bool MIParser::parseBasicBlocks() { | ||||
952 | lex(); | ||||
953 | // Skip until the first machine basic block. | ||||
954 | while (Token.is(MIToken::Newline)) | ||||
955 | lex(); | ||||
956 | if (Token.isErrorOrEOF()) | ||||
957 | return Token.isError(); | ||||
958 | // The first parsing pass should have verified that this token is a MBB label | ||||
959 | // in the 'parseBasicBlockDefinitions' method. | ||||
960 | assert(Token.is(MIToken::MachineBasicBlockLabel))(static_cast <bool> (Token.is(MIToken::MachineBasicBlockLabel )) ? void (0) : __assert_fail ("Token.is(MIToken::MachineBasicBlockLabel)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 960, __extension__ __PRETTY_FUNCTION__)); | ||||
961 | MachineBasicBlock *AddFalthroughFrom = nullptr; | ||||
962 | do { | ||||
963 | MachineBasicBlock *MBB = nullptr; | ||||
964 | if (parseMBBReference(MBB)) | ||||
965 | return true; | ||||
966 | if (AddFalthroughFrom) { | ||||
967 | if (!AddFalthroughFrom->isSuccessor(MBB)) | ||||
968 | AddFalthroughFrom->addSuccessor(MBB); | ||||
969 | AddFalthroughFrom->normalizeSuccProbs(); | ||||
970 | AddFalthroughFrom = nullptr; | ||||
971 | } | ||||
972 | if (parseBasicBlock(*MBB, AddFalthroughFrom)) | ||||
973 | return true; | ||||
974 | // The method 'parseBasicBlock' should parse the whole block until the next | ||||
975 | // block or the end of file. | ||||
976 | assert(Token.is(MIToken::MachineBasicBlockLabel) || Token.is(MIToken::Eof))(static_cast <bool> (Token.is(MIToken::MachineBasicBlockLabel ) || Token.is(MIToken::Eof)) ? void (0) : __assert_fail ("Token.is(MIToken::MachineBasicBlockLabel) || Token.is(MIToken::Eof)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 976, __extension__ __PRETTY_FUNCTION__)); | ||||
977 | } while (Token.isNot(MIToken::Eof)); | ||||
978 | return false; | ||||
979 | } | ||||
980 | |||||
981 | bool MIParser::parse(MachineInstr *&MI) { | ||||
982 | // Parse any register operands before '=' | ||||
983 | MachineOperand MO = MachineOperand::CreateImm(0); | ||||
984 | SmallVector<ParsedMachineOperand, 8> Operands; | ||||
985 | while (Token.isRegister() || Token.isRegisterFlag()) { | ||||
986 | auto Loc = Token.location(); | ||||
987 | Optional<unsigned> TiedDefIdx; | ||||
988 | if (parseRegisterOperand(MO, TiedDefIdx, /*IsDef=*/true)) | ||||
989 | return true; | ||||
990 | Operands.push_back( | ||||
991 | ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx)); | ||||
992 | if (Token.isNot(MIToken::comma)) | ||||
993 | break; | ||||
994 | lex(); | ||||
995 | } | ||||
996 | if (!Operands.empty() && expectAndConsume(MIToken::equal)) | ||||
997 | return true; | ||||
998 | |||||
999 | unsigned OpCode, Flags = 0; | ||||
1000 | if (Token.isError() || parseInstruction(OpCode, Flags)) | ||||
1001 | return true; | ||||
1002 | |||||
1003 | // Parse the remaining machine operands. | ||||
1004 | while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_pre_instr_symbol) && | ||||
1005 | Token.isNot(MIToken::kw_post_instr_symbol) && | ||||
1006 | Token.isNot(MIToken::kw_heap_alloc_marker) && | ||||
1007 | Token.isNot(MIToken::kw_debug_location) && | ||||
1008 | Token.isNot(MIToken::kw_debug_instr_number) && | ||||
1009 | Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) { | ||||
1010 | auto Loc = Token.location(); | ||||
1011 | Optional<unsigned> TiedDefIdx; | ||||
1012 | if (parseMachineOperandAndTargetFlags(OpCode, Operands.size(), MO, TiedDefIdx)) | ||||
1013 | return true; | ||||
1014 | if ((OpCode == TargetOpcode::DBG_VALUE || | ||||
1015 | OpCode == TargetOpcode::DBG_VALUE_LIST) && | ||||
1016 | MO.isReg()) | ||||
1017 | MO.setIsDebug(); | ||||
1018 | Operands.push_back( | ||||
1019 | ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx)); | ||||
1020 | if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) || | ||||
1021 | Token.is(MIToken::lbrace)) | ||||
1022 | break; | ||||
1023 | if (Token.isNot(MIToken::comma)) | ||||
1024 | return error("expected ',' before the next machine operand"); | ||||
1025 | lex(); | ||||
1026 | } | ||||
1027 | |||||
1028 | MCSymbol *PreInstrSymbol = nullptr; | ||||
1029 | if (Token.is(MIToken::kw_pre_instr_symbol)) | ||||
1030 | if (parsePreOrPostInstrSymbol(PreInstrSymbol)) | ||||
1031 | return true; | ||||
1032 | MCSymbol *PostInstrSymbol = nullptr; | ||||
1033 | if (Token.is(MIToken::kw_post_instr_symbol)) | ||||
1034 | if (parsePreOrPostInstrSymbol(PostInstrSymbol)) | ||||
1035 | return true; | ||||
1036 | MDNode *HeapAllocMarker = nullptr; | ||||
1037 | if (Token.is(MIToken::kw_heap_alloc_marker)) | ||||
1038 | if (parseHeapAllocMarker(HeapAllocMarker)) | ||||
1039 | return true; | ||||
1040 | |||||
1041 | unsigned InstrNum = 0; | ||||
1042 | if (Token.is(MIToken::kw_debug_instr_number)) { | ||||
1043 | lex(); | ||||
1044 | if (Token.isNot(MIToken::IntegerLiteral)) | ||||
1045 | return error("expected an integer literal after 'debug-instr-number'"); | ||||
1046 | if (getUnsigned(InstrNum)) | ||||
1047 | return true; | ||||
1048 | lex(); | ||||
1049 | // Lex past trailing comma if present. | ||||
1050 | if (Token.is(MIToken::comma)) | ||||
1051 | lex(); | ||||
1052 | } | ||||
1053 | |||||
1054 | DebugLoc DebugLocation; | ||||
1055 | if (Token.is(MIToken::kw_debug_location)) { | ||||
1056 | lex(); | ||||
1057 | MDNode *Node = nullptr; | ||||
1058 | if (Token.is(MIToken::exclaim)) { | ||||
1059 | if (parseMDNode(Node)) | ||||
1060 | return true; | ||||
1061 | } else if (Token.is(MIToken::md_dilocation)) { | ||||
1062 | if (parseDILocation(Node)) | ||||
1063 | return true; | ||||
1064 | } else | ||||
1065 | return error("expected a metadata node after 'debug-location'"); | ||||
1066 | if (!isa<DILocation>(Node)) | ||||
1067 | return error("referenced metadata is not a DILocation"); | ||||
1068 | DebugLocation = DebugLoc(Node); | ||||
1069 | } | ||||
1070 | |||||
1071 | // Parse the machine memory operands. | ||||
1072 | SmallVector<MachineMemOperand *, 2> MemOperands; | ||||
1073 | if (Token.is(MIToken::coloncolon)) { | ||||
1074 | lex(); | ||||
1075 | while (!Token.isNewlineOrEOF()) { | ||||
1076 | MachineMemOperand *MemOp = nullptr; | ||||
1077 | if (parseMachineMemoryOperand(MemOp)) | ||||
1078 | return true; | ||||
1079 | MemOperands.push_back(MemOp); | ||||
1080 | if (Token.isNewlineOrEOF()) | ||||
1081 | break; | ||||
1082 | if (Token.isNot(MIToken::comma)) | ||||
1083 | return error("expected ',' before the next machine memory operand"); | ||||
1084 | lex(); | ||||
1085 | } | ||||
1086 | } | ||||
1087 | |||||
1088 | const auto &MCID = MF.getSubtarget().getInstrInfo()->get(OpCode); | ||||
1089 | if (!MCID.isVariadic()) { | ||||
1090 | // FIXME: Move the implicit operand verification to the machine verifier. | ||||
1091 | if (verifyImplicitOperands(Operands, MCID)) | ||||
1092 | return true; | ||||
1093 | } | ||||
1094 | |||||
1095 | // TODO: Check for extraneous machine operands. | ||||
1096 | MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true); | ||||
1097 | MI->setFlags(Flags); | ||||
1098 | for (const auto &Operand : Operands) | ||||
1099 | MI->addOperand(MF, Operand.Operand); | ||||
1100 | if (assignRegisterTies(*MI, Operands)) | ||||
1101 | return true; | ||||
1102 | if (PreInstrSymbol) | ||||
1103 | MI->setPreInstrSymbol(MF, PreInstrSymbol); | ||||
1104 | if (PostInstrSymbol) | ||||
1105 | MI->setPostInstrSymbol(MF, PostInstrSymbol); | ||||
1106 | if (HeapAllocMarker) | ||||
1107 | MI->setHeapAllocMarker(MF, HeapAllocMarker); | ||||
1108 | if (!MemOperands.empty()) | ||||
1109 | MI->setMemRefs(MF, MemOperands); | ||||
1110 | if (InstrNum) | ||||
1111 | MI->setDebugInstrNum(InstrNum); | ||||
1112 | return false; | ||||
1113 | } | ||||
1114 | |||||
1115 | bool MIParser::parseStandaloneMBB(MachineBasicBlock *&MBB) { | ||||
1116 | lex(); | ||||
1117 | if (Token.isNot(MIToken::MachineBasicBlock)) | ||||
1118 | return error("expected a machine basic block reference"); | ||||
1119 | if (parseMBBReference(MBB)) | ||||
1120 | return true; | ||||
1121 | lex(); | ||||
1122 | if (Token.isNot(MIToken::Eof)) | ||||
1123 | return error( | ||||
1124 | "expected end of string after the machine basic block reference"); | ||||
1125 | return false; | ||||
1126 | } | ||||
1127 | |||||
1128 | bool MIParser::parseStandaloneNamedRegister(Register &Reg) { | ||||
1129 | lex(); | ||||
1130 | if (Token.isNot(MIToken::NamedRegister)) | ||||
1131 | return error("expected a named register"); | ||||
1132 | if (parseNamedRegister(Reg)) | ||||
1133 | return true; | ||||
1134 | lex(); | ||||
1135 | if (Token.isNot(MIToken::Eof)) | ||||
1136 | return error("expected end of string after the register reference"); | ||||
1137 | return false; | ||||
1138 | } | ||||
1139 | |||||
1140 | bool MIParser::parseStandaloneVirtualRegister(VRegInfo *&Info) { | ||||
1141 | lex(); | ||||
1142 | if (Token.isNot(MIToken::VirtualRegister)) | ||||
1143 | return error("expected a virtual register"); | ||||
1144 | if (parseVirtualRegister(Info)) | ||||
1145 | return true; | ||||
1146 | lex(); | ||||
1147 | if (Token.isNot(MIToken::Eof)) | ||||
1148 | return error("expected end of string after the register reference"); | ||||
1149 | return false; | ||||
1150 | } | ||||
1151 | |||||
1152 | bool MIParser::parseStandaloneRegister(Register &Reg) { | ||||
1153 | lex(); | ||||
1154 | if (Token.isNot(MIToken::NamedRegister) && | ||||
1155 | Token.isNot(MIToken::VirtualRegister)) | ||||
1156 | return error("expected either a named or virtual register"); | ||||
1157 | |||||
1158 | VRegInfo *Info; | ||||
1159 | if (parseRegister(Reg, Info)) | ||||
1160 | return true; | ||||
1161 | |||||
1162 | lex(); | ||||
1163 | if (Token.isNot(MIToken::Eof)) | ||||
1164 | return error("expected end of string after the register reference"); | ||||
1165 | return false; | ||||
1166 | } | ||||
1167 | |||||
1168 | bool MIParser::parseStandaloneStackObject(int &FI) { | ||||
1169 | lex(); | ||||
1170 | if (Token.isNot(MIToken::StackObject)) | ||||
1171 | return error("expected a stack object"); | ||||
1172 | if (parseStackFrameIndex(FI)) | ||||
1173 | return true; | ||||
1174 | if (Token.isNot(MIToken::Eof)) | ||||
1175 | return error("expected end of string after the stack object reference"); | ||||
1176 | return false; | ||||
1177 | } | ||||
1178 | |||||
1179 | bool MIParser::parseStandaloneMDNode(MDNode *&Node) { | ||||
1180 | lex(); | ||||
1181 | if (Token.is(MIToken::exclaim)) { | ||||
1182 | if (parseMDNode(Node)) | ||||
1183 | return true; | ||||
1184 | } else if (Token.is(MIToken::md_diexpr)) { | ||||
1185 | if (parseDIExpression(Node)) | ||||
1186 | return true; | ||||
1187 | } else if (Token.is(MIToken::md_dilocation)) { | ||||
1188 | if (parseDILocation(Node)) | ||||
1189 | return true; | ||||
1190 | } else | ||||
1191 | return error("expected a metadata node"); | ||||
1192 | if (Token.isNot(MIToken::Eof)) | ||||
1193 | return error("expected end of string after the metadata node"); | ||||
1194 | return false; | ||||
1195 | } | ||||
1196 | |||||
1197 | bool MIParser::parseMachineMetadata() { | ||||
1198 | lex(); | ||||
1199 | if (Token.isNot(MIToken::exclaim)) | ||||
1200 | return error("expected a metadata node"); | ||||
1201 | |||||
1202 | lex(); | ||||
1203 | if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) | ||||
1204 | return error("expected metadata id after '!'"); | ||||
1205 | unsigned ID = 0; | ||||
1206 | if (getUnsigned(ID)) | ||||
1207 | return true; | ||||
1208 | lex(); | ||||
1209 | if (expectAndConsume(MIToken::equal)) | ||||
1210 | return true; | ||||
1211 | bool IsDistinct = Token.is(MIToken::kw_distinct); | ||||
1212 | if (IsDistinct) | ||||
1213 | lex(); | ||||
1214 | if (Token.isNot(MIToken::exclaim)) | ||||
1215 | return error("expected a metadata node"); | ||||
1216 | lex(); | ||||
1217 | |||||
1218 | MDNode *MD; | ||||
1219 | if (parseMDTuple(MD, IsDistinct)) | ||||
1220 | return true; | ||||
1221 | |||||
1222 | auto FI = PFS.MachineForwardRefMDNodes.find(ID); | ||||
1223 | if (FI != PFS.MachineForwardRefMDNodes.end()) { | ||||
1224 | FI->second.first->replaceAllUsesWith(MD); | ||||
1225 | PFS.MachineForwardRefMDNodes.erase(FI); | ||||
1226 | |||||
1227 | assert(PFS.MachineMetadataNodes[ID] == MD && "Tracking VH didn't work")(static_cast <bool> (PFS.MachineMetadataNodes[ID] == MD && "Tracking VH didn't work") ? void (0) : __assert_fail ("PFS.MachineMetadataNodes[ID] == MD && \"Tracking VH didn't work\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1227, __extension__ __PRETTY_FUNCTION__)); | ||||
1228 | } else { | ||||
1229 | if (PFS.MachineMetadataNodes.count(ID)) | ||||
1230 | return error("Metadata id is already used"); | ||||
1231 | PFS.MachineMetadataNodes[ID].reset(MD); | ||||
1232 | } | ||||
1233 | |||||
1234 | return false; | ||||
1235 | } | ||||
1236 | |||||
1237 | bool MIParser::parseMDTuple(MDNode *&MD, bool IsDistinct) { | ||||
1238 | SmallVector<Metadata *, 16> Elts; | ||||
1239 | if (parseMDNodeVector(Elts)) | ||||
1240 | return true; | ||||
1241 | MD = (IsDistinct ? MDTuple::getDistinct | ||||
1242 | : MDTuple::get)(MF.getFunction().getContext(), Elts); | ||||
1243 | return false; | ||||
1244 | } | ||||
1245 | |||||
1246 | bool MIParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) { | ||||
1247 | if (Token.isNot(MIToken::lbrace)) | ||||
1248 | return error("expected '{' here"); | ||||
1249 | lex(); | ||||
1250 | |||||
1251 | if (Token.is(MIToken::rbrace)) { | ||||
1252 | lex(); | ||||
1253 | return false; | ||||
1254 | } | ||||
1255 | |||||
1256 | do { | ||||
1257 | Metadata *MD; | ||||
1258 | if (parseMetadata(MD)) | ||||
1259 | return true; | ||||
1260 | |||||
1261 | Elts.push_back(MD); | ||||
1262 | |||||
1263 | if (Token.isNot(MIToken::comma)) | ||||
1264 | break; | ||||
1265 | lex(); | ||||
1266 | } while (true); | ||||
1267 | |||||
1268 | if (Token.isNot(MIToken::rbrace)) | ||||
1269 | return error("expected end of metadata node"); | ||||
1270 | lex(); | ||||
1271 | |||||
1272 | return false; | ||||
1273 | } | ||||
1274 | |||||
1275 | // ::= !42 | ||||
1276 | // ::= !"string" | ||||
1277 | bool MIParser::parseMetadata(Metadata *&MD) { | ||||
1278 | if (Token.isNot(MIToken::exclaim)) | ||||
1279 | return error("expected '!' here"); | ||||
1280 | lex(); | ||||
1281 | |||||
1282 | if (Token.is(MIToken::StringConstant)) { | ||||
1283 | std::string Str; | ||||
1284 | if (parseStringConstant(Str)) | ||||
1285 | return true; | ||||
1286 | MD = MDString::get(MF.getFunction().getContext(), Str); | ||||
1287 | return false; | ||||
1288 | } | ||||
1289 | |||||
1290 | if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) | ||||
1291 | return error("expected metadata id after '!'"); | ||||
1292 | |||||
1293 | SMLoc Loc = mapSMLoc(Token.location()); | ||||
1294 | |||||
1295 | unsigned ID = 0; | ||||
1296 | if (getUnsigned(ID)) | ||||
1297 | return true; | ||||
1298 | lex(); | ||||
1299 | |||||
1300 | auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID); | ||||
1301 | if (NodeInfo != PFS.IRSlots.MetadataNodes.end()) { | ||||
1302 | MD = NodeInfo->second.get(); | ||||
1303 | return false; | ||||
1304 | } | ||||
1305 | // Check machine metadata. | ||||
1306 | NodeInfo = PFS.MachineMetadataNodes.find(ID); | ||||
1307 | if (NodeInfo != PFS.MachineMetadataNodes.end()) { | ||||
1308 | MD = NodeInfo->second.get(); | ||||
1309 | return false; | ||||
1310 | } | ||||
1311 | // Forward reference. | ||||
1312 | auto &FwdRef = PFS.MachineForwardRefMDNodes[ID]; | ||||
1313 | FwdRef = std::make_pair( | ||||
1314 | MDTuple::getTemporary(MF.getFunction().getContext(), None), Loc); | ||||
1315 | PFS.MachineMetadataNodes[ID].reset(FwdRef.first.get()); | ||||
1316 | MD = FwdRef.first.get(); | ||||
1317 | |||||
1318 | return false; | ||||
1319 | } | ||||
1320 | |||||
1321 | static const char *printImplicitRegisterFlag(const MachineOperand &MO) { | ||||
1322 | assert(MO.isImplicit())(static_cast <bool> (MO.isImplicit()) ? void (0) : __assert_fail ("MO.isImplicit()", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1322, __extension__ __PRETTY_FUNCTION__)); | ||||
1323 | return MO.isDef() ? "implicit-def" : "implicit"; | ||||
1324 | } | ||||
1325 | |||||
1326 | static std::string getRegisterName(const TargetRegisterInfo *TRI, | ||||
1327 | Register Reg) { | ||||
1328 | assert(Register::isPhysicalRegister(Reg) && "expected phys reg")(static_cast <bool> (Register::isPhysicalRegister(Reg) && "expected phys reg") ? void (0) : __assert_fail ("Register::isPhysicalRegister(Reg) && \"expected phys reg\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1328, __extension__ __PRETTY_FUNCTION__)); | ||||
1329 | return StringRef(TRI->getName(Reg)).lower(); | ||||
1330 | } | ||||
1331 | |||||
1332 | /// Return true if the parsed machine operands contain a given machine operand. | ||||
1333 | static bool isImplicitOperandIn(const MachineOperand &ImplicitOperand, | ||||
1334 | ArrayRef<ParsedMachineOperand> Operands) { | ||||
1335 | for (const auto &I : Operands) { | ||||
1336 | if (ImplicitOperand.isIdenticalTo(I.Operand)) | ||||
1337 | return true; | ||||
1338 | } | ||||
1339 | return false; | ||||
1340 | } | ||||
1341 | |||||
1342 | bool MIParser::verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands, | ||||
1343 | const MCInstrDesc &MCID) { | ||||
1344 | if (MCID.isCall()) | ||||
1345 | // We can't verify call instructions as they can contain arbitrary implicit | ||||
1346 | // register and register mask operands. | ||||
1347 | return false; | ||||
1348 | |||||
1349 | // Gather all the expected implicit operands. | ||||
1350 | SmallVector<MachineOperand, 4> ImplicitOperands; | ||||
1351 | if (MCID.ImplicitDefs) | ||||
1352 | for (const MCPhysReg *ImpDefs = MCID.getImplicitDefs(); *ImpDefs; ++ImpDefs) | ||||
1353 | ImplicitOperands.push_back( | ||||
1354 | MachineOperand::CreateReg(*ImpDefs, true, true)); | ||||
1355 | if (MCID.ImplicitUses) | ||||
1356 | for (const MCPhysReg *ImpUses = MCID.getImplicitUses(); *ImpUses; ++ImpUses) | ||||
1357 | ImplicitOperands.push_back( | ||||
1358 | MachineOperand::CreateReg(*ImpUses, false, true)); | ||||
1359 | |||||
1360 | const auto *TRI = MF.getSubtarget().getRegisterInfo(); | ||||
1361 | assert(TRI && "Expected target register info")(static_cast <bool> (TRI && "Expected target register info" ) ? void (0) : __assert_fail ("TRI && \"Expected target register info\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1361, __extension__ __PRETTY_FUNCTION__)); | ||||
1362 | for (const auto &I : ImplicitOperands) { | ||||
1363 | if (isImplicitOperandIn(I, Operands)) | ||||
1364 | continue; | ||||
1365 | return error(Operands.empty() ? Token.location() : Operands.back().End, | ||||
1366 | Twine("missing implicit register operand '") + | ||||
1367 | printImplicitRegisterFlag(I) + " $" + | ||||
1368 | getRegisterName(TRI, I.getReg()) + "'"); | ||||
1369 | } | ||||
1370 | return false; | ||||
1371 | } | ||||
1372 | |||||
1373 | bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) { | ||||
1374 | // Allow frame and fast math flags for OPCODE | ||||
1375 | while (Token.is(MIToken::kw_frame_setup) || | ||||
1376 | Token.is(MIToken::kw_frame_destroy) || | ||||
1377 | Token.is(MIToken::kw_nnan) || | ||||
1378 | Token.is(MIToken::kw_ninf) || | ||||
1379 | Token.is(MIToken::kw_nsz) || | ||||
1380 | Token.is(MIToken::kw_arcp) || | ||||
1381 | Token.is(MIToken::kw_contract) || | ||||
1382 | Token.is(MIToken::kw_afn) || | ||||
1383 | Token.is(MIToken::kw_reassoc) || | ||||
1384 | Token.is(MIToken::kw_nuw) || | ||||
1385 | Token.is(MIToken::kw_nsw) || | ||||
1386 | Token.is(MIToken::kw_exact) || | ||||
1387 | Token.is(MIToken::kw_nofpexcept)) { | ||||
1388 | // Mine frame and fast math flags | ||||
1389 | if (Token.is(MIToken::kw_frame_setup)) | ||||
1390 | Flags |= MachineInstr::FrameSetup; | ||||
1391 | if (Token.is(MIToken::kw_frame_destroy)) | ||||
1392 | Flags |= MachineInstr::FrameDestroy; | ||||
1393 | if (Token.is(MIToken::kw_nnan)) | ||||
1394 | Flags |= MachineInstr::FmNoNans; | ||||
1395 | if (Token.is(MIToken::kw_ninf)) | ||||
1396 | Flags |= MachineInstr::FmNoInfs; | ||||
1397 | if (Token.is(MIToken::kw_nsz)) | ||||
1398 | Flags |= MachineInstr::FmNsz; | ||||
1399 | if (Token.is(MIToken::kw_arcp)) | ||||
1400 | Flags |= MachineInstr::FmArcp; | ||||
1401 | if (Token.is(MIToken::kw_contract)) | ||||
1402 | Flags |= MachineInstr::FmContract; | ||||
1403 | if (Token.is(MIToken::kw_afn)) | ||||
1404 | Flags |= MachineInstr::FmAfn; | ||||
1405 | if (Token.is(MIToken::kw_reassoc)) | ||||
1406 | Flags |= MachineInstr::FmReassoc; | ||||
1407 | if (Token.is(MIToken::kw_nuw)) | ||||
1408 | Flags |= MachineInstr::NoUWrap; | ||||
1409 | if (Token.is(MIToken::kw_nsw)) | ||||
1410 | Flags |= MachineInstr::NoSWrap; | ||||
1411 | if (Token.is(MIToken::kw_exact)) | ||||
1412 | Flags |= MachineInstr::IsExact; | ||||
1413 | if (Token.is(MIToken::kw_nofpexcept)) | ||||
1414 | Flags |= MachineInstr::NoFPExcept; | ||||
1415 | |||||
1416 | lex(); | ||||
1417 | } | ||||
1418 | if (Token.isNot(MIToken::Identifier)) | ||||
1419 | return error("expected a machine instruction"); | ||||
1420 | StringRef InstrName = Token.stringValue(); | ||||
1421 | if (PFS.Target.parseInstrName(InstrName, OpCode)) | ||||
1422 | return error(Twine("unknown machine instruction name '") + InstrName + "'"); | ||||
1423 | lex(); | ||||
1424 | return false; | ||||
1425 | } | ||||
1426 | |||||
1427 | bool MIParser::parseNamedRegister(Register &Reg) { | ||||
1428 | assert(Token.is(MIToken::NamedRegister) && "Needs NamedRegister token")(static_cast <bool> (Token.is(MIToken::NamedRegister) && "Needs NamedRegister token") ? void (0) : __assert_fail ("Token.is(MIToken::NamedRegister) && \"Needs NamedRegister token\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1428, __extension__ __PRETTY_FUNCTION__)); | ||||
1429 | StringRef Name = Token.stringValue(); | ||||
1430 | if (PFS.Target.getRegisterByName(Name, Reg)) | ||||
1431 | return error(Twine("unknown register name '") + Name + "'"); | ||||
1432 | return false; | ||||
1433 | } | ||||
1434 | |||||
1435 | bool MIParser::parseNamedVirtualRegister(VRegInfo *&Info) { | ||||
1436 | assert(Token.is(MIToken::NamedVirtualRegister) && "Expected NamedVReg token")(static_cast <bool> (Token.is(MIToken::NamedVirtualRegister ) && "Expected NamedVReg token") ? void (0) : __assert_fail ("Token.is(MIToken::NamedVirtualRegister) && \"Expected NamedVReg token\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1436, __extension__ __PRETTY_FUNCTION__)); | ||||
1437 | StringRef Name = Token.stringValue(); | ||||
1438 | // TODO: Check that the VReg name is not the same as a physical register name. | ||||
1439 | // If it is, then print a warning (when warnings are implemented). | ||||
1440 | Info = &PFS.getVRegInfoNamed(Name); | ||||
1441 | return false; | ||||
1442 | } | ||||
1443 | |||||
1444 | bool MIParser::parseVirtualRegister(VRegInfo *&Info) { | ||||
1445 | if (Token.is(MIToken::NamedVirtualRegister)) | ||||
1446 | return parseNamedVirtualRegister(Info); | ||||
1447 | assert(Token.is(MIToken::VirtualRegister) && "Needs VirtualRegister token")(static_cast <bool> (Token.is(MIToken::VirtualRegister) && "Needs VirtualRegister token") ? void (0) : __assert_fail ("Token.is(MIToken::VirtualRegister) && \"Needs VirtualRegister token\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1447, __extension__ __PRETTY_FUNCTION__)); | ||||
1448 | unsigned ID; | ||||
1449 | if (getUnsigned(ID)) | ||||
1450 | return true; | ||||
1451 | Info = &PFS.getVRegInfo(ID); | ||||
1452 | return false; | ||||
1453 | } | ||||
1454 | |||||
1455 | bool MIParser::parseRegister(Register &Reg, VRegInfo *&Info) { | ||||
1456 | switch (Token.kind()) { | ||||
1457 | case MIToken::underscore: | ||||
1458 | Reg = 0; | ||||
1459 | return false; | ||||
1460 | case MIToken::NamedRegister: | ||||
1461 | return parseNamedRegister(Reg); | ||||
1462 | case MIToken::NamedVirtualRegister: | ||||
1463 | case MIToken::VirtualRegister: | ||||
1464 | if (parseVirtualRegister(Info)) | ||||
1465 | return true; | ||||
1466 | Reg = Info->VReg; | ||||
1467 | return false; | ||||
1468 | // TODO: Parse other register kinds. | ||||
1469 | default: | ||||
1470 | llvm_unreachable("The current token should be a register")::llvm::llvm_unreachable_internal("The current token should be a register" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1470); | ||||
1471 | } | ||||
1472 | } | ||||
1473 | |||||
1474 | bool MIParser::parseRegisterClassOrBank(VRegInfo &RegInfo) { | ||||
1475 | if (Token.isNot(MIToken::Identifier) && Token.isNot(MIToken::underscore)) | ||||
1476 | return error("expected '_', register class, or register bank name"); | ||||
1477 | StringRef::iterator Loc = Token.location(); | ||||
1478 | StringRef Name = Token.stringValue(); | ||||
1479 | |||||
1480 | // Was it a register class? | ||||
1481 | const TargetRegisterClass *RC = PFS.Target.getRegClass(Name); | ||||
1482 | if (RC) { | ||||
1483 | lex(); | ||||
1484 | |||||
1485 | switch (RegInfo.Kind) { | ||||
1486 | case VRegInfo::UNKNOWN: | ||||
1487 | case VRegInfo::NORMAL: | ||||
1488 | RegInfo.Kind = VRegInfo::NORMAL; | ||||
1489 | if (RegInfo.Explicit && RegInfo.D.RC != RC) { | ||||
1490 | const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); | ||||
1491 | return error(Loc, Twine("conflicting register classes, previously: ") + | ||||
1492 | Twine(TRI.getRegClassName(RegInfo.D.RC))); | ||||
1493 | } | ||||
1494 | RegInfo.D.RC = RC; | ||||
1495 | RegInfo.Explicit = true; | ||||
1496 | return false; | ||||
1497 | |||||
1498 | case VRegInfo::GENERIC: | ||||
1499 | case VRegInfo::REGBANK: | ||||
1500 | return error(Loc, "register class specification on generic register"); | ||||
1501 | } | ||||
1502 | llvm_unreachable("Unexpected register kind")::llvm::llvm_unreachable_internal("Unexpected register kind", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1502); | ||||
1503 | } | ||||
1504 | |||||
1505 | // Should be a register bank or a generic register. | ||||
1506 | const RegisterBank *RegBank = nullptr; | ||||
1507 | if (Name != "_") { | ||||
1508 | RegBank = PFS.Target.getRegBank(Name); | ||||
1509 | if (!RegBank) | ||||
1510 | return error(Loc, "expected '_', register class, or register bank name"); | ||||
1511 | } | ||||
1512 | |||||
1513 | lex(); | ||||
1514 | |||||
1515 | switch (RegInfo.Kind) { | ||||
1516 | case VRegInfo::UNKNOWN: | ||||
1517 | case VRegInfo::GENERIC: | ||||
1518 | case VRegInfo::REGBANK: | ||||
1519 | RegInfo.Kind = RegBank ? VRegInfo::REGBANK : VRegInfo::GENERIC; | ||||
1520 | if (RegInfo.Explicit && RegInfo.D.RegBank != RegBank) | ||||
1521 | return error(Loc, "conflicting generic register banks"); | ||||
1522 | RegInfo.D.RegBank = RegBank; | ||||
1523 | RegInfo.Explicit = true; | ||||
1524 | return false; | ||||
1525 | |||||
1526 | case VRegInfo::NORMAL: | ||||
1527 | return error(Loc, "register bank specification on normal register"); | ||||
1528 | } | ||||
1529 | llvm_unreachable("Unexpected register kind")::llvm::llvm_unreachable_internal("Unexpected register kind", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1529); | ||||
1530 | } | ||||
1531 | |||||
1532 | bool MIParser::parseRegisterFlag(unsigned &Flags) { | ||||
1533 | const unsigned OldFlags = Flags; | ||||
1534 | switch (Token.kind()) { | ||||
1535 | case MIToken::kw_implicit: | ||||
1536 | Flags |= RegState::Implicit; | ||||
1537 | break; | ||||
1538 | case MIToken::kw_implicit_define: | ||||
1539 | Flags |= RegState::ImplicitDefine; | ||||
1540 | break; | ||||
1541 | case MIToken::kw_def: | ||||
1542 | Flags |= RegState::Define; | ||||
1543 | break; | ||||
1544 | case MIToken::kw_dead: | ||||
1545 | Flags |= RegState::Dead; | ||||
1546 | break; | ||||
1547 | case MIToken::kw_killed: | ||||
1548 | Flags |= RegState::Kill; | ||||
1549 | break; | ||||
1550 | case MIToken::kw_undef: | ||||
1551 | Flags |= RegState::Undef; | ||||
1552 | break; | ||||
1553 | case MIToken::kw_internal: | ||||
1554 | Flags |= RegState::InternalRead; | ||||
1555 | break; | ||||
1556 | case MIToken::kw_early_clobber: | ||||
1557 | Flags |= RegState::EarlyClobber; | ||||
1558 | break; | ||||
1559 | case MIToken::kw_debug_use: | ||||
1560 | Flags |= RegState::Debug; | ||||
1561 | break; | ||||
1562 | case MIToken::kw_renamable: | ||||
1563 | Flags |= RegState::Renamable; | ||||
1564 | break; | ||||
1565 | default: | ||||
1566 | llvm_unreachable("The current token should be a register flag")::llvm::llvm_unreachable_internal("The current token should be a register flag" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1566); | ||||
1567 | } | ||||
1568 | if (OldFlags == Flags) | ||||
1569 | // We know that the same flag is specified more than once when the flags | ||||
1570 | // weren't modified. | ||||
1571 | return error("duplicate '" + Token.stringValue() + "' register flag"); | ||||
1572 | lex(); | ||||
1573 | return false; | ||||
1574 | } | ||||
1575 | |||||
1576 | bool MIParser::parseSubRegisterIndex(unsigned &SubReg) { | ||||
1577 | assert(Token.is(MIToken::dot))(static_cast <bool> (Token.is(MIToken::dot)) ? void (0) : __assert_fail ("Token.is(MIToken::dot)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1577, __extension__ __PRETTY_FUNCTION__)); | ||||
1578 | lex(); | ||||
1579 | if (Token.isNot(MIToken::Identifier)) | ||||
1580 | return error("expected a subregister index after '.'"); | ||||
1581 | auto Name = Token.stringValue(); | ||||
1582 | SubReg = PFS.Target.getSubRegIndex(Name); | ||||
1583 | if (!SubReg) | ||||
1584 | return error(Twine("use of unknown subregister index '") + Name + "'"); | ||||
1585 | lex(); | ||||
1586 | return false; | ||||
1587 | } | ||||
1588 | |||||
1589 | bool MIParser::parseRegisterTiedDefIndex(unsigned &TiedDefIdx) { | ||||
1590 | if (!consumeIfPresent(MIToken::kw_tied_def)) | ||||
1591 | return true; | ||||
1592 | if (Token.isNot(MIToken::IntegerLiteral)) | ||||
1593 | return error("expected an integer literal after 'tied-def'"); | ||||
1594 | if (getUnsigned(TiedDefIdx)) | ||||
1595 | return true; | ||||
1596 | lex(); | ||||
1597 | if (expectAndConsume(MIToken::rparen)) | ||||
1598 | return true; | ||||
1599 | return false; | ||||
1600 | } | ||||
1601 | |||||
1602 | bool MIParser::assignRegisterTies(MachineInstr &MI, | ||||
1603 | ArrayRef<ParsedMachineOperand> Operands) { | ||||
1604 | SmallVector<std::pair<unsigned, unsigned>, 4> TiedRegisterPairs; | ||||
1605 | for (unsigned I = 0, E = Operands.size(); I != E; ++I) { | ||||
1606 | if (!Operands[I].TiedDefIdx) | ||||
1607 | continue; | ||||
1608 | // The parser ensures that this operand is a register use, so we just have | ||||
1609 | // to check the tied-def operand. | ||||
1610 | unsigned DefIdx = Operands[I].TiedDefIdx.getValue(); | ||||
1611 | if (DefIdx >= E) | ||||
1612 | return error(Operands[I].Begin, | ||||
1613 | Twine("use of invalid tied-def operand index '" + | ||||
1614 | Twine(DefIdx) + "'; instruction has only ") + | ||||
1615 | Twine(E) + " operands"); | ||||
1616 | const auto &DefOperand = Operands[DefIdx].Operand; | ||||
1617 | if (!DefOperand.isReg() || !DefOperand.isDef()) | ||||
1618 | // FIXME: add note with the def operand. | ||||
1619 | return error(Operands[I].Begin, | ||||
1620 | Twine("use of invalid tied-def operand index '") + | ||||
1621 | Twine(DefIdx) + "'; the operand #" + Twine(DefIdx) + | ||||
1622 | " isn't a defined register"); | ||||
1623 | // Check that the tied-def operand wasn't tied elsewhere. | ||||
1624 | for (const auto &TiedPair : TiedRegisterPairs) { | ||||
1625 | if (TiedPair.first == DefIdx) | ||||
1626 | return error(Operands[I].Begin, | ||||
1627 | Twine("the tied-def operand #") + Twine(DefIdx) + | ||||
1628 | " is already tied with another register operand"); | ||||
1629 | } | ||||
1630 | TiedRegisterPairs.push_back(std::make_pair(DefIdx, I)); | ||||
1631 | } | ||||
1632 | // FIXME: Verify that for non INLINEASM instructions, the def and use tied | ||||
1633 | // indices must be less than tied max. | ||||
1634 | for (const auto &TiedPair : TiedRegisterPairs) | ||||
1635 | MI.tieOperands(TiedPair.first, TiedPair.second); | ||||
1636 | return false; | ||||
1637 | } | ||||
1638 | |||||
1639 | bool MIParser::parseRegisterOperand(MachineOperand &Dest, | ||||
1640 | Optional<unsigned> &TiedDefIdx, | ||||
1641 | bool IsDef) { | ||||
1642 | unsigned Flags = IsDef ? RegState::Define : 0; | ||||
1643 | while (Token.isRegisterFlag()) { | ||||
1644 | if (parseRegisterFlag(Flags)) | ||||
1645 | return true; | ||||
1646 | } | ||||
1647 | if (!Token.isRegister()) | ||||
1648 | return error("expected a register after register flags"); | ||||
1649 | Register Reg; | ||||
1650 | VRegInfo *RegInfo; | ||||
1651 | if (parseRegister(Reg, RegInfo)) | ||||
1652 | return true; | ||||
1653 | lex(); | ||||
1654 | unsigned SubReg = 0; | ||||
1655 | if (Token.is(MIToken::dot)) { | ||||
1656 | if (parseSubRegisterIndex(SubReg)) | ||||
1657 | return true; | ||||
1658 | if (!Register::isVirtualRegister(Reg)) | ||||
1659 | return error("subregister index expects a virtual register"); | ||||
1660 | } | ||||
1661 | if (Token.is(MIToken::colon)) { | ||||
1662 | if (!Register::isVirtualRegister(Reg)) | ||||
1663 | return error("register class specification expects a virtual register"); | ||||
1664 | lex(); | ||||
1665 | if (parseRegisterClassOrBank(*RegInfo)) | ||||
1666 | return true; | ||||
1667 | } | ||||
1668 | MachineRegisterInfo &MRI = MF.getRegInfo(); | ||||
1669 | if ((Flags & RegState::Define) == 0) { | ||||
1670 | if (consumeIfPresent(MIToken::lparen)) { | ||||
1671 | unsigned Idx; | ||||
1672 | if (!parseRegisterTiedDefIndex(Idx)) | ||||
1673 | TiedDefIdx = Idx; | ||||
1674 | else { | ||||
1675 | // Try a redundant low-level type. | ||||
1676 | LLT Ty; | ||||
1677 | if (parseLowLevelType(Token.location(), Ty)) | ||||
1678 | return error("expected tied-def or low-level type after '('"); | ||||
1679 | |||||
1680 | if (expectAndConsume(MIToken::rparen)) | ||||
1681 | return true; | ||||
1682 | |||||
1683 | if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty) | ||||
1684 | return error("inconsistent type for generic virtual register"); | ||||
1685 | |||||
1686 | MRI.setRegClassOrRegBank(Reg, static_cast<RegisterBank *>(nullptr)); | ||||
1687 | MRI.setType(Reg, Ty); | ||||
1688 | } | ||||
1689 | } | ||||
1690 | } else if (consumeIfPresent(MIToken::lparen)) { | ||||
1691 | // Virtual registers may have a tpe with GlobalISel. | ||||
1692 | if (!Register::isVirtualRegister(Reg)) | ||||
1693 | return error("unexpected type on physical register"); | ||||
1694 | |||||
1695 | LLT Ty; | ||||
1696 | if (parseLowLevelType(Token.location(), Ty)) | ||||
1697 | return true; | ||||
1698 | |||||
1699 | if (expectAndConsume(MIToken::rparen)) | ||||
1700 | return true; | ||||
1701 | |||||
1702 | if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty) | ||||
1703 | return error("inconsistent type for generic virtual register"); | ||||
1704 | |||||
1705 | MRI.setRegClassOrRegBank(Reg, static_cast<RegisterBank *>(nullptr)); | ||||
1706 | MRI.setType(Reg, Ty); | ||||
1707 | } else if (Register::isVirtualRegister(Reg)) { | ||||
1708 | // Generic virtual registers must have a type. | ||||
1709 | // If we end up here this means the type hasn't been specified and | ||||
1710 | // this is bad! | ||||
1711 | if (RegInfo->Kind == VRegInfo::GENERIC || | ||||
1712 | RegInfo->Kind == VRegInfo::REGBANK) | ||||
1713 | return error("generic virtual registers must have a type"); | ||||
1714 | } | ||||
1715 | Dest = MachineOperand::CreateReg( | ||||
1716 | Reg, Flags & RegState::Define, Flags & RegState::Implicit, | ||||
1717 | Flags & RegState::Kill, Flags & RegState::Dead, Flags & RegState::Undef, | ||||
1718 | Flags & RegState::EarlyClobber, SubReg, Flags & RegState::Debug, | ||||
1719 | Flags & RegState::InternalRead, Flags & RegState::Renamable); | ||||
1720 | |||||
1721 | return false; | ||||
1722 | } | ||||
1723 | |||||
1724 | bool MIParser::parseImmediateOperand(MachineOperand &Dest) { | ||||
1725 | assert(Token.is(MIToken::IntegerLiteral))(static_cast <bool> (Token.is(MIToken::IntegerLiteral)) ? void (0) : __assert_fail ("Token.is(MIToken::IntegerLiteral)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1725, __extension__ __PRETTY_FUNCTION__)); | ||||
1726 | const APSInt &Int = Token.integerValue(); | ||||
1727 | if (Int.getMinSignedBits() > 64) | ||||
1728 | return error("integer literal is too large to be an immediate operand"); | ||||
1729 | Dest = MachineOperand::CreateImm(Int.getExtValue()); | ||||
1730 | lex(); | ||||
1731 | return false; | ||||
1732 | } | ||||
1733 | |||||
1734 | bool MIParser::parseTargetImmMnemonic(const unsigned OpCode, | ||||
1735 | const unsigned OpIdx, | ||||
1736 | MachineOperand &Dest, | ||||
1737 | const MIRFormatter &MF) { | ||||
1738 | assert(Token.is(MIToken::dot))(static_cast <bool> (Token.is(MIToken::dot)) ? void (0) : __assert_fail ("Token.is(MIToken::dot)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1738, __extension__ __PRETTY_FUNCTION__)); | ||||
1739 | auto Loc = Token.location(); // record start position | ||||
1740 | size_t Len = 1; // for "." | ||||
1741 | lex(); | ||||
1742 | |||||
1743 | // Handle the case that mnemonic starts with number. | ||||
1744 | if (Token.is(MIToken::IntegerLiteral)) { | ||||
1745 | Len += Token.range().size(); | ||||
1746 | lex(); | ||||
1747 | } | ||||
1748 | |||||
1749 | StringRef Src; | ||||
1750 | if (Token.is(MIToken::comma)) | ||||
1751 | Src = StringRef(Loc, Len); | ||||
1752 | else { | ||||
1753 | assert(Token.is(MIToken::Identifier))(static_cast <bool> (Token.is(MIToken::Identifier)) ? void (0) : __assert_fail ("Token.is(MIToken::Identifier)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1753, __extension__ __PRETTY_FUNCTION__)); | ||||
1754 | Src = StringRef(Loc, Len + Token.stringValue().size()); | ||||
1755 | } | ||||
1756 | int64_t Val; | ||||
1757 | if (MF.parseImmMnemonic(OpCode, OpIdx, Src, Val, | ||||
1758 | [this](StringRef::iterator Loc, const Twine &Msg) | ||||
1759 | -> bool { return error(Loc, Msg); })) | ||||
1760 | return true; | ||||
1761 | |||||
1762 | Dest = MachineOperand::CreateImm(Val); | ||||
1763 | if (!Token.is(MIToken::comma)) | ||||
1764 | lex(); | ||||
1765 | return false; | ||||
1766 | } | ||||
1767 | |||||
1768 | static bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue, | ||||
1769 | PerFunctionMIParsingState &PFS, const Constant *&C, | ||||
1770 | ErrorCallbackType ErrCB) { | ||||
1771 | auto Source = StringValue.str(); // The source has to be null terminated. | ||||
1772 | SMDiagnostic Err; | ||||
1773 | C = parseConstantValue(Source, Err, *PFS.MF.getFunction().getParent(), | ||||
1774 | &PFS.IRSlots); | ||||
1775 | if (!C) | ||||
1776 | return ErrCB(Loc + Err.getColumnNo(), Err.getMessage()); | ||||
1777 | return false; | ||||
1778 | } | ||||
1779 | |||||
1780 | bool MIParser::parseIRConstant(StringRef::iterator Loc, StringRef StringValue, | ||||
1781 | const Constant *&C) { | ||||
1782 | return ::parseIRConstant( | ||||
1783 | Loc, StringValue, PFS, C, | ||||
1784 | [this](StringRef::iterator Loc, const Twine &Msg) -> bool { | ||||
1785 | return error(Loc, Msg); | ||||
1786 | }); | ||||
1787 | } | ||||
1788 | |||||
1789 | bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) { | ||||
1790 | if (parseIRConstant(Loc, StringRef(Loc, Token.range().end() - Loc), C)) | ||||
1791 | return true; | ||||
1792 | lex(); | ||||
1793 | return false; | ||||
1794 | } | ||||
1795 | |||||
1796 | // See LLT implemntation for bit size limits. | ||||
1797 | static bool verifyScalarSize(uint64_t Size) { | ||||
1798 | return Size != 0 && isUInt<16>(Size); | ||||
1799 | } | ||||
1800 | |||||
1801 | static bool verifyVectorElementCount(uint64_t NumElts) { | ||||
1802 | return NumElts != 0 && isUInt<16>(NumElts); | ||||
1803 | } | ||||
1804 | |||||
1805 | static bool verifyAddrSpace(uint64_t AddrSpace) { | ||||
1806 | return isUInt<24>(AddrSpace); | ||||
1807 | } | ||||
1808 | |||||
1809 | bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) { | ||||
1810 | if (Token.range().front() == 's' || Token.range().front() == 'p') { | ||||
1811 | StringRef SizeStr = Token.range().drop_front(); | ||||
1812 | if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit)) | ||||
1813 | return error("expected integers after 's'/'p' type character"); | ||||
1814 | } | ||||
1815 | |||||
1816 | if (Token.range().front() == 's') { | ||||
1817 | auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue(); | ||||
1818 | if (!verifyScalarSize(ScalarSize)) | ||||
1819 | return error("invalid size for scalar type"); | ||||
1820 | |||||
1821 | Ty = LLT::scalar(ScalarSize); | ||||
1822 | lex(); | ||||
1823 | return false; | ||||
1824 | } else if (Token.range().front() == 'p') { | ||||
1825 | const DataLayout &DL = MF.getDataLayout(); | ||||
1826 | uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue(); | ||||
1827 | if (!verifyAddrSpace(AS)) | ||||
1828 | return error("invalid address space number"); | ||||
1829 | |||||
1830 | Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS)); | ||||
1831 | lex(); | ||||
1832 | return false; | ||||
1833 | } | ||||
1834 | |||||
1835 | // Now we're looking for a vector. | ||||
1836 | if (Token.isNot(MIToken::less)) | ||||
1837 | return error(Loc, | ||||
1838 | "expected sN, pA, <M x sN>, or <M x pA> for GlobalISel type"); | ||||
1839 | lex(); | ||||
1840 | |||||
1841 | if (Token.isNot(MIToken::IntegerLiteral)) | ||||
1842 | return error(Loc, "expected <M x sN> or <M x pA> for vector type"); | ||||
1843 | uint64_t NumElements = Token.integerValue().getZExtValue(); | ||||
1844 | if (!verifyVectorElementCount(NumElements)) | ||||
1845 | return error("invalid number of vector elements"); | ||||
1846 | |||||
1847 | lex(); | ||||
1848 | |||||
1849 | if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x") | ||||
1850 | return error(Loc, "expected <M x sN> or <M x pA> for vector type"); | ||||
1851 | lex(); | ||||
1852 | |||||
1853 | if (Token.range().front() != 's' && Token.range().front() != 'p') | ||||
1854 | return error(Loc, "expected <M x sN> or <M x pA> for vector type"); | ||||
1855 | StringRef SizeStr = Token.range().drop_front(); | ||||
1856 | if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit)) | ||||
1857 | return error("expected integers after 's'/'p' type character"); | ||||
1858 | |||||
1859 | if (Token.range().front() == 's') { | ||||
1860 | auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue(); | ||||
1861 | if (!verifyScalarSize(ScalarSize)) | ||||
1862 | return error("invalid size for scalar type"); | ||||
1863 | Ty = LLT::scalar(ScalarSize); | ||||
1864 | } else if (Token.range().front() == 'p') { | ||||
1865 | const DataLayout &DL = MF.getDataLayout(); | ||||
1866 | uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue(); | ||||
1867 | if (!verifyAddrSpace(AS)) | ||||
1868 | return error("invalid address space number"); | ||||
1869 | |||||
1870 | Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS)); | ||||
1871 | } else | ||||
1872 | return error(Loc, "expected <M x sN> or <M x pA> for vector type"); | ||||
1873 | lex(); | ||||
1874 | |||||
1875 | if (Token.isNot(MIToken::greater)) | ||||
1876 | return error(Loc, "expected <M x sN> or <M x pA> for vector type"); | ||||
1877 | lex(); | ||||
1878 | |||||
1879 | Ty = LLT::fixed_vector(NumElements, Ty); | ||||
1880 | return false; | ||||
1881 | } | ||||
1882 | |||||
1883 | bool MIParser::parseTypedImmediateOperand(MachineOperand &Dest) { | ||||
1884 | assert(Token.is(MIToken::Identifier))(static_cast <bool> (Token.is(MIToken::Identifier)) ? void (0) : __assert_fail ("Token.is(MIToken::Identifier)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1884, __extension__ __PRETTY_FUNCTION__)); | ||||
1885 | StringRef TypeStr = Token.range(); | ||||
1886 | if (TypeStr.front() != 'i' && TypeStr.front() != 's' && | ||||
1887 | TypeStr.front() != 'p') | ||||
1888 | return error( | ||||
1889 | "a typed immediate operand should start with one of 'i', 's', or 'p'"); | ||||
1890 | StringRef SizeStr = Token.range().drop_front(); | ||||
1891 | if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit)) | ||||
1892 | return error("expected integers after 'i'/'s'/'p' type character"); | ||||
1893 | |||||
1894 | auto Loc = Token.location(); | ||||
1895 | lex(); | ||||
1896 | if (Token.isNot(MIToken::IntegerLiteral)) { | ||||
1897 | if (Token.isNot(MIToken::Identifier) || | ||||
1898 | !(Token.range() == "true" || Token.range() == "false")) | ||||
1899 | return error("expected an integer literal"); | ||||
1900 | } | ||||
1901 | const Constant *C = nullptr; | ||||
1902 | if (parseIRConstant(Loc, C)) | ||||
1903 | return true; | ||||
1904 | Dest = MachineOperand::CreateCImm(cast<ConstantInt>(C)); | ||||
1905 | return false; | ||||
1906 | } | ||||
1907 | |||||
1908 | bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) { | ||||
1909 | auto Loc = Token.location(); | ||||
1910 | lex(); | ||||
1911 | if (Token.isNot(MIToken::FloatingPointLiteral) && | ||||
1912 | Token.isNot(MIToken::HexLiteral)) | ||||
1913 | return error("expected a floating point literal"); | ||||
1914 | const Constant *C = nullptr; | ||||
1915 | if (parseIRConstant(Loc, C)) | ||||
1916 | return true; | ||||
1917 | Dest = MachineOperand::CreateFPImm(cast<ConstantFP>(C)); | ||||
1918 | return false; | ||||
1919 | } | ||||
1920 | |||||
1921 | static bool getHexUint(const MIToken &Token, APInt &Result) { | ||||
1922 | assert(Token.is(MIToken::HexLiteral))(static_cast <bool> (Token.is(MIToken::HexLiteral)) ? void (0) : __assert_fail ("Token.is(MIToken::HexLiteral)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1922, __extension__ __PRETTY_FUNCTION__)); | ||||
1923 | StringRef S = Token.range(); | ||||
1924 | assert(S[0] == '0' && tolower(S[1]) == 'x')(static_cast <bool> (S[0] == '0' && tolower(S[1 ]) == 'x') ? void (0) : __assert_fail ("S[0] == '0' && tolower(S[1]) == 'x'" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1924, __extension__ __PRETTY_FUNCTION__)); | ||||
1925 | // This could be a floating point literal with a special prefix. | ||||
1926 | if (!isxdigit(S[2])) | ||||
1927 | return true; | ||||
1928 | StringRef V = S.substr(2); | ||||
1929 | APInt A(V.size()*4, V, 16); | ||||
1930 | |||||
1931 | // If A is 0, then A.getActiveBits() is 0. This isn't a valid bitwidth. Make | ||||
1932 | // sure it isn't the case before constructing result. | ||||
1933 | unsigned NumBits = (A == 0) ? 32 : A.getActiveBits(); | ||||
1934 | Result = APInt(NumBits, ArrayRef<uint64_t>(A.getRawData(), A.getNumWords())); | ||||
1935 | return false; | ||||
1936 | } | ||||
1937 | |||||
1938 | static bool getUnsigned(const MIToken &Token, unsigned &Result, | ||||
1939 | ErrorCallbackType ErrCB) { | ||||
1940 | if (Token.hasIntegerValue()) { | ||||
1941 | const uint64_t Limit = uint64_t(std::numeric_limits<unsigned>::max()) + 1; | ||||
1942 | uint64_t Val64 = Token.integerValue().getLimitedValue(Limit); | ||||
1943 | if (Val64
| ||||
1944 | return ErrCB(Token.location(), "expected 32-bit integer (too large)"); | ||||
1945 | Result = Val64; | ||||
1946 | return false; | ||||
1947 | } | ||||
1948 | if (Token.is(MIToken::HexLiteral)) { | ||||
1949 | APInt A; | ||||
1950 | if (getHexUint(Token, A)) | ||||
1951 | return true; | ||||
1952 | if (A.getBitWidth() > 32) | ||||
1953 | return ErrCB(Token.location(), "expected 32-bit integer (too large)"); | ||||
1954 | Result = A.getZExtValue(); | ||||
1955 | return false; | ||||
1956 | } | ||||
1957 | return true; | ||||
1958 | } | ||||
1959 | |||||
1960 | bool MIParser::getUnsigned(unsigned &Result) { | ||||
1961 | return ::getUnsigned( | ||||
1962 | Token, Result, [this](StringRef::iterator Loc, const Twine &Msg) -> bool { | ||||
1963 | return error(Loc, Msg); | ||||
1964 | }); | ||||
1965 | } | ||||
1966 | |||||
1967 | bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) { | ||||
1968 | assert(Token.is(MIToken::MachineBasicBlock) ||(static_cast <bool> (Token.is(MIToken::MachineBasicBlock ) || Token.is(MIToken::MachineBasicBlockLabel)) ? void (0) : __assert_fail ("Token.is(MIToken::MachineBasicBlock) || Token.is(MIToken::MachineBasicBlockLabel)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1969, __extension__ __PRETTY_FUNCTION__)) | ||||
1969 | Token.is(MIToken::MachineBasicBlockLabel))(static_cast <bool> (Token.is(MIToken::MachineBasicBlock ) || Token.is(MIToken::MachineBasicBlockLabel)) ? void (0) : __assert_fail ("Token.is(MIToken::MachineBasicBlock) || Token.is(MIToken::MachineBasicBlockLabel)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1969, __extension__ __PRETTY_FUNCTION__)); | ||||
1970 | unsigned Number; | ||||
1971 | if (getUnsigned(Number)) | ||||
1972 | return true; | ||||
1973 | auto MBBInfo = PFS.MBBSlots.find(Number); | ||||
1974 | if (MBBInfo == PFS.MBBSlots.end()) | ||||
1975 | return error(Twine("use of undefined machine basic block #") + | ||||
1976 | Twine(Number)); | ||||
1977 | MBB = MBBInfo->second; | ||||
1978 | // TODO: Only parse the name if it's a MachineBasicBlockLabel. Deprecate once | ||||
1979 | // we drop the <irname> from the bb.<id>.<irname> format. | ||||
1980 | if (!Token.stringValue().empty() && Token.stringValue() != MBB->getName()) | ||||
1981 | return error(Twine("the name of machine basic block #") + Twine(Number) + | ||||
1982 | " isn't '" + Token.stringValue() + "'"); | ||||
1983 | return false; | ||||
1984 | } | ||||
1985 | |||||
1986 | bool MIParser::parseMBBOperand(MachineOperand &Dest) { | ||||
1987 | MachineBasicBlock *MBB; | ||||
1988 | if (parseMBBReference(MBB)) | ||||
1989 | return true; | ||||
1990 | Dest = MachineOperand::CreateMBB(MBB); | ||||
1991 | lex(); | ||||
1992 | return false; | ||||
1993 | } | ||||
1994 | |||||
1995 | bool MIParser::parseStackFrameIndex(int &FI) { | ||||
1996 | assert(Token.is(MIToken::StackObject))(static_cast <bool> (Token.is(MIToken::StackObject)) ? void (0) : __assert_fail ("Token.is(MIToken::StackObject)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 1996, __extension__ __PRETTY_FUNCTION__)); | ||||
1997 | unsigned ID; | ||||
1998 | if (getUnsigned(ID)) | ||||
1999 | return true; | ||||
2000 | auto ObjectInfo = PFS.StackObjectSlots.find(ID); | ||||
2001 | if (ObjectInfo == PFS.StackObjectSlots.end()) | ||||
2002 | return error(Twine("use of undefined stack object '%stack.") + Twine(ID) + | ||||
2003 | "'"); | ||||
2004 | StringRef Name; | ||||
2005 | if (const auto *Alloca = | ||||
2006 | MF.getFrameInfo().getObjectAllocation(ObjectInfo->second)) | ||||
2007 | Name = Alloca->getName(); | ||||
2008 | if (!Token.stringValue().empty() && Token.stringValue() != Name) | ||||
2009 | return error(Twine("the name of the stack object '%stack.") + Twine(ID) + | ||||
2010 | "' isn't '" + Token.stringValue() + "'"); | ||||
2011 | lex(); | ||||
2012 | FI = ObjectInfo->second; | ||||
2013 | return false; | ||||
2014 | } | ||||
2015 | |||||
2016 | bool MIParser::parseStackObjectOperand(MachineOperand &Dest) { | ||||
2017 | int FI; | ||||
2018 | if (parseStackFrameIndex(FI)) | ||||
2019 | return true; | ||||
2020 | Dest = MachineOperand::CreateFI(FI); | ||||
2021 | return false; | ||||
2022 | } | ||||
2023 | |||||
2024 | bool MIParser::parseFixedStackFrameIndex(int &FI) { | ||||
2025 | assert(Token.is(MIToken::FixedStackObject))(static_cast <bool> (Token.is(MIToken::FixedStackObject )) ? void (0) : __assert_fail ("Token.is(MIToken::FixedStackObject)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2025, __extension__ __PRETTY_FUNCTION__)); | ||||
2026 | unsigned ID; | ||||
2027 | if (getUnsigned(ID)) | ||||
2028 | return true; | ||||
2029 | auto ObjectInfo = PFS.FixedStackObjectSlots.find(ID); | ||||
2030 | if (ObjectInfo == PFS.FixedStackObjectSlots.end()) | ||||
2031 | return error(Twine("use of undefined fixed stack object '%fixed-stack.") + | ||||
2032 | Twine(ID) + "'"); | ||||
2033 | lex(); | ||||
2034 | FI = ObjectInfo->second; | ||||
2035 | return false; | ||||
2036 | } | ||||
2037 | |||||
2038 | bool MIParser::parseFixedStackObjectOperand(MachineOperand &Dest) { | ||||
2039 | int FI; | ||||
2040 | if (parseFixedStackFrameIndex(FI)) | ||||
2041 | return true; | ||||
2042 | Dest = MachineOperand::CreateFI(FI); | ||||
2043 | return false; | ||||
2044 | } | ||||
2045 | |||||
2046 | static bool parseGlobalValue(const MIToken &Token, | ||||
2047 | PerFunctionMIParsingState &PFS, GlobalValue *&GV, | ||||
2048 | ErrorCallbackType ErrCB) { | ||||
2049 | switch (Token.kind()) { | ||||
2050 | case MIToken::NamedGlobalValue: { | ||||
2051 | const Module *M = PFS.MF.getFunction().getParent(); | ||||
2052 | GV = M->getNamedValue(Token.stringValue()); | ||||
2053 | if (!GV) | ||||
2054 | return ErrCB(Token.location(), Twine("use of undefined global value '") + | ||||
2055 | Token.range() + "'"); | ||||
2056 | break; | ||||
2057 | } | ||||
2058 | case MIToken::GlobalValue: { | ||||
2059 | unsigned GVIdx; | ||||
2060 | if (getUnsigned(Token, GVIdx, ErrCB)) | ||||
2061 | return true; | ||||
2062 | if (GVIdx >= PFS.IRSlots.GlobalValues.size()) | ||||
| |||||
2063 | return ErrCB(Token.location(), Twine("use of undefined global value '@") + | ||||
2064 | Twine(GVIdx) + "'"); | ||||
2065 | GV = PFS.IRSlots.GlobalValues[GVIdx]; | ||||
2066 | break; | ||||
2067 | } | ||||
2068 | default: | ||||
2069 | llvm_unreachable("The current token should be a global value")::llvm::llvm_unreachable_internal("The current token should be a global value" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2069); | ||||
2070 | } | ||||
2071 | return false; | ||||
2072 | } | ||||
2073 | |||||
2074 | bool MIParser::parseGlobalValue(GlobalValue *&GV) { | ||||
2075 | return ::parseGlobalValue( | ||||
2076 | Token, PFS, GV, | ||||
2077 | [this](StringRef::iterator Loc, const Twine &Msg) -> bool { | ||||
2078 | return error(Loc, Msg); | ||||
2079 | }); | ||||
2080 | } | ||||
2081 | |||||
2082 | bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) { | ||||
2083 | GlobalValue *GV = nullptr; | ||||
2084 | if (parseGlobalValue(GV)) | ||||
2085 | return true; | ||||
2086 | lex(); | ||||
2087 | Dest = MachineOperand::CreateGA(GV, /*Offset=*/0); | ||||
2088 | if (parseOperandsOffset(Dest)) | ||||
2089 | return true; | ||||
2090 | return false; | ||||
2091 | } | ||||
2092 | |||||
2093 | bool MIParser::parseConstantPoolIndexOperand(MachineOperand &Dest) { | ||||
2094 | assert(Token.is(MIToken::ConstantPoolItem))(static_cast <bool> (Token.is(MIToken::ConstantPoolItem )) ? void (0) : __assert_fail ("Token.is(MIToken::ConstantPoolItem)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2094, __extension__ __PRETTY_FUNCTION__)); | ||||
2095 | unsigned ID; | ||||
2096 | if (getUnsigned(ID)) | ||||
2097 | return true; | ||||
2098 | auto ConstantInfo = PFS.ConstantPoolSlots.find(ID); | ||||
2099 | if (ConstantInfo == PFS.ConstantPoolSlots.end()) | ||||
2100 | return error("use of undefined constant '%const." + Twine(ID) + "'"); | ||||
2101 | lex(); | ||||
2102 | Dest = MachineOperand::CreateCPI(ID, /*Offset=*/0); | ||||
2103 | if (parseOperandsOffset(Dest)) | ||||
2104 | return true; | ||||
2105 | return false; | ||||
2106 | } | ||||
2107 | |||||
2108 | bool MIParser::parseJumpTableIndexOperand(MachineOperand &Dest) { | ||||
2109 | assert(Token.is(MIToken::JumpTableIndex))(static_cast <bool> (Token.is(MIToken::JumpTableIndex)) ? void (0) : __assert_fail ("Token.is(MIToken::JumpTableIndex)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2109, __extension__ __PRETTY_FUNCTION__)); | ||||
2110 | unsigned ID; | ||||
2111 | if (getUnsigned(ID)) | ||||
2112 | return true; | ||||
2113 | auto JumpTableEntryInfo = PFS.JumpTableSlots.find(ID); | ||||
2114 | if (JumpTableEntryInfo == PFS.JumpTableSlots.end()) | ||||
2115 | return error("use of undefined jump table '%jump-table." + Twine(ID) + "'"); | ||||
2116 | lex(); | ||||
2117 | Dest = MachineOperand::CreateJTI(JumpTableEntryInfo->second); | ||||
2118 | return false; | ||||
2119 | } | ||||
2120 | |||||
2121 | bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) { | ||||
2122 | assert(Token.is(MIToken::ExternalSymbol))(static_cast <bool> (Token.is(MIToken::ExternalSymbol)) ? void (0) : __assert_fail ("Token.is(MIToken::ExternalSymbol)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2122, __extension__ __PRETTY_FUNCTION__)); | ||||
2123 | const char *Symbol = MF.createExternalSymbolName(Token.stringValue()); | ||||
2124 | lex(); | ||||
2125 | Dest = MachineOperand::CreateES(Symbol); | ||||
2126 | if (parseOperandsOffset(Dest)) | ||||
2127 | return true; | ||||
2128 | return false; | ||||
2129 | } | ||||
2130 | |||||
2131 | bool MIParser::parseMCSymbolOperand(MachineOperand &Dest) { | ||||
2132 | assert(Token.is(MIToken::MCSymbol))(static_cast <bool> (Token.is(MIToken::MCSymbol)) ? void (0) : __assert_fail ("Token.is(MIToken::MCSymbol)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2132, __extension__ __PRETTY_FUNCTION__)); | ||||
2133 | MCSymbol *Symbol = getOrCreateMCSymbol(Token.stringValue()); | ||||
2134 | lex(); | ||||
2135 | Dest = MachineOperand::CreateMCSymbol(Symbol); | ||||
2136 | if (parseOperandsOffset(Dest)) | ||||
2137 | return true; | ||||
2138 | return false; | ||||
2139 | } | ||||
2140 | |||||
2141 | bool MIParser::parseSubRegisterIndexOperand(MachineOperand &Dest) { | ||||
2142 | assert(Token.is(MIToken::SubRegisterIndex))(static_cast <bool> (Token.is(MIToken::SubRegisterIndex )) ? void (0) : __assert_fail ("Token.is(MIToken::SubRegisterIndex)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2142, __extension__ __PRETTY_FUNCTION__)); | ||||
2143 | StringRef Name = Token.stringValue(); | ||||
2144 | unsigned SubRegIndex = PFS.Target.getSubRegIndex(Token.stringValue()); | ||||
2145 | if (SubRegIndex == 0) | ||||
2146 | return error(Twine("unknown subregister index '") + Name + "'"); | ||||
2147 | lex(); | ||||
2148 | Dest = MachineOperand::CreateImm(SubRegIndex); | ||||
2149 | return false; | ||||
2150 | } | ||||
2151 | |||||
2152 | bool MIParser::parseMDNode(MDNode *&Node) { | ||||
2153 | assert(Token.is(MIToken::exclaim))(static_cast <bool> (Token.is(MIToken::exclaim)) ? void (0) : __assert_fail ("Token.is(MIToken::exclaim)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2153, __extension__ __PRETTY_FUNCTION__)); | ||||
2154 | |||||
2155 | auto Loc = Token.location(); | ||||
2156 | lex(); | ||||
2157 | if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) | ||||
2158 | return error("expected metadata id after '!'"); | ||||
2159 | unsigned ID; | ||||
2160 | if (getUnsigned(ID)) | ||||
2161 | return true; | ||||
2162 | auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID); | ||||
2163 | if (NodeInfo == PFS.IRSlots.MetadataNodes.end()) { | ||||
2164 | NodeInfo = PFS.MachineMetadataNodes.find(ID); | ||||
2165 | if (NodeInfo == PFS.MachineMetadataNodes.end()) | ||||
2166 | return error(Loc, "use of undefined metadata '!" + Twine(ID) + "'"); | ||||
2167 | } | ||||
2168 | lex(); | ||||
2169 | Node = NodeInfo->second.get(); | ||||
2170 | return false; | ||||
2171 | } | ||||
2172 | |||||
2173 | bool MIParser::parseDIExpression(MDNode *&Expr) { | ||||
2174 | assert(Token.is(MIToken::md_diexpr))(static_cast <bool> (Token.is(MIToken::md_diexpr)) ? void (0) : __assert_fail ("Token.is(MIToken::md_diexpr)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2174, __extension__ __PRETTY_FUNCTION__)); | ||||
2175 | lex(); | ||||
2176 | |||||
2177 | // FIXME: Share this parsing with the IL parser. | ||||
2178 | SmallVector<uint64_t, 8> Elements; | ||||
2179 | |||||
2180 | if (expectAndConsume(MIToken::lparen)) | ||||
2181 | return true; | ||||
2182 | |||||
2183 | if (Token.isNot(MIToken::rparen)) { | ||||
2184 | do { | ||||
2185 | if (Token.is(MIToken::Identifier)) { | ||||
2186 | if (unsigned Op = dwarf::getOperationEncoding(Token.stringValue())) { | ||||
2187 | lex(); | ||||
2188 | Elements.push_back(Op); | ||||
2189 | continue; | ||||
2190 | } | ||||
2191 | if (unsigned Enc = dwarf::getAttributeEncoding(Token.stringValue())) { | ||||
2192 | lex(); | ||||
2193 | Elements.push_back(Enc); | ||||
2194 | continue; | ||||
2195 | } | ||||
2196 | return error(Twine("invalid DWARF op '") + Token.stringValue() + "'"); | ||||
2197 | } | ||||
2198 | |||||
2199 | if (Token.isNot(MIToken::IntegerLiteral) || | ||||
2200 | Token.integerValue().isSigned()) | ||||
2201 | return error("expected unsigned integer"); | ||||
2202 | |||||
2203 | auto &U = Token.integerValue(); | ||||
2204 | if (U.ugt(UINT64_MAX(18446744073709551615UL))) | ||||
2205 | return error("element too large, limit is " + Twine(UINT64_MAX(18446744073709551615UL))); | ||||
2206 | Elements.push_back(U.getZExtValue()); | ||||
2207 | lex(); | ||||
2208 | |||||
2209 | } while (consumeIfPresent(MIToken::comma)); | ||||
2210 | } | ||||
2211 | |||||
2212 | if (expectAndConsume(MIToken::rparen)) | ||||
2213 | return true; | ||||
2214 | |||||
2215 | Expr = DIExpression::get(MF.getFunction().getContext(), Elements); | ||||
2216 | return false; | ||||
2217 | } | ||||
2218 | |||||
2219 | bool MIParser::parseDILocation(MDNode *&Loc) { | ||||
2220 | assert(Token.is(MIToken::md_dilocation))(static_cast <bool> (Token.is(MIToken::md_dilocation)) ? void (0) : __assert_fail ("Token.is(MIToken::md_dilocation)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2220, __extension__ __PRETTY_FUNCTION__)); | ||||
2221 | lex(); | ||||
2222 | |||||
2223 | bool HaveLine = false; | ||||
2224 | unsigned Line = 0; | ||||
2225 | unsigned Column = 0; | ||||
2226 | MDNode *Scope = nullptr; | ||||
2227 | MDNode *InlinedAt = nullptr; | ||||
2228 | bool ImplicitCode = false; | ||||
2229 | |||||
2230 | if (expectAndConsume(MIToken::lparen)) | ||||
2231 | return true; | ||||
2232 | |||||
2233 | if (Token.isNot(MIToken::rparen)) { | ||||
2234 | do { | ||||
2235 | if (Token.is(MIToken::Identifier)) { | ||||
2236 | if (Token.stringValue() == "line") { | ||||
2237 | lex(); | ||||
2238 | if (expectAndConsume(MIToken::colon)) | ||||
2239 | return true; | ||||
2240 | if (Token.isNot(MIToken::IntegerLiteral) || | ||||
2241 | Token.integerValue().isSigned()) | ||||
2242 | return error("expected unsigned integer"); | ||||
2243 | Line = Token.integerValue().getZExtValue(); | ||||
2244 | HaveLine = true; | ||||
2245 | lex(); | ||||
2246 | continue; | ||||
2247 | } | ||||
2248 | if (Token.stringValue() == "column") { | ||||
2249 | lex(); | ||||
2250 | if (expectAndConsume(MIToken::colon)) | ||||
2251 | return true; | ||||
2252 | if (Token.isNot(MIToken::IntegerLiteral) || | ||||
2253 | Token.integerValue().isSigned()) | ||||
2254 | return error("expected unsigned integer"); | ||||
2255 | Column = Token.integerValue().getZExtValue(); | ||||
2256 | lex(); | ||||
2257 | continue; | ||||
2258 | } | ||||
2259 | if (Token.stringValue() == "scope") { | ||||
2260 | lex(); | ||||
2261 | if (expectAndConsume(MIToken::colon)) | ||||
2262 | return true; | ||||
2263 | if (parseMDNode(Scope)) | ||||
2264 | return error("expected metadata node"); | ||||
2265 | if (!isa<DIScope>(Scope)) | ||||
2266 | return error("expected DIScope node"); | ||||
2267 | continue; | ||||
2268 | } | ||||
2269 | if (Token.stringValue() == "inlinedAt") { | ||||
2270 | lex(); | ||||
2271 | if (expectAndConsume(MIToken::colon)) | ||||
2272 | return true; | ||||
2273 | if (Token.is(MIToken::exclaim)) { | ||||
2274 | if (parseMDNode(InlinedAt)) | ||||
2275 | return true; | ||||
2276 | } else if (Token.is(MIToken::md_dilocation)) { | ||||
2277 | if (parseDILocation(InlinedAt)) | ||||
2278 | return true; | ||||
2279 | } else | ||||
2280 | return error("expected metadata node"); | ||||
2281 | if (!isa<DILocation>(InlinedAt)) | ||||
2282 | return error("expected DILocation node"); | ||||
2283 | continue; | ||||
2284 | } | ||||
2285 | if (Token.stringValue() == "isImplicitCode") { | ||||
2286 | lex(); | ||||
2287 | if (expectAndConsume(MIToken::colon)) | ||||
2288 | return true; | ||||
2289 | if (!Token.is(MIToken::Identifier)) | ||||
2290 | return error("expected true/false"); | ||||
2291 | // As far as I can see, we don't have any existing need for parsing | ||||
2292 | // true/false in MIR yet. Do it ad-hoc until there's something else | ||||
2293 | // that needs it. | ||||
2294 | if (Token.stringValue() == "true") | ||||
2295 | ImplicitCode = true; | ||||
2296 | else if (Token.stringValue() == "false") | ||||
2297 | ImplicitCode = false; | ||||
2298 | else | ||||
2299 | return error("expected true/false"); | ||||
2300 | lex(); | ||||
2301 | continue; | ||||
2302 | } | ||||
2303 | } | ||||
2304 | return error(Twine("invalid DILocation argument '") + | ||||
2305 | Token.stringValue() + "'"); | ||||
2306 | } while (consumeIfPresent(MIToken::comma)); | ||||
2307 | } | ||||
2308 | |||||
2309 | if (expectAndConsume(MIToken::rparen)) | ||||
2310 | return true; | ||||
2311 | |||||
2312 | if (!HaveLine) | ||||
2313 | return error("DILocation requires line number"); | ||||
2314 | if (!Scope) | ||||
2315 | return error("DILocation requires a scope"); | ||||
2316 | |||||
2317 | Loc = DILocation::get(MF.getFunction().getContext(), Line, Column, Scope, | ||||
2318 | InlinedAt, ImplicitCode); | ||||
2319 | return false; | ||||
2320 | } | ||||
2321 | |||||
2322 | bool MIParser::parseMetadataOperand(MachineOperand &Dest) { | ||||
2323 | MDNode *Node = nullptr; | ||||
2324 | if (Token.is(MIToken::exclaim)) { | ||||
2325 | if (parseMDNode(Node)) | ||||
2326 | return true; | ||||
2327 | } else if (Token.is(MIToken::md_diexpr)) { | ||||
2328 | if (parseDIExpression(Node)) | ||||
2329 | return true; | ||||
2330 | } | ||||
2331 | Dest = MachineOperand::CreateMetadata(Node); | ||||
2332 | return false; | ||||
2333 | } | ||||
2334 | |||||
2335 | bool MIParser::parseCFIOffset(int &Offset) { | ||||
2336 | if (Token.isNot(MIToken::IntegerLiteral)) | ||||
2337 | return error("expected a cfi offset"); | ||||
2338 | if (Token.integerValue().getMinSignedBits() > 32) | ||||
2339 | return error("expected a 32 bit integer (the cfi offset is too large)"); | ||||
2340 | Offset = (int)Token.integerValue().getExtValue(); | ||||
2341 | lex(); | ||||
2342 | return false; | ||||
2343 | } | ||||
2344 | |||||
2345 | bool MIParser::parseCFIRegister(Register &Reg) { | ||||
2346 | if (Token.isNot(MIToken::NamedRegister)) | ||||
2347 | return error("expected a cfi register"); | ||||
2348 | Register LLVMReg; | ||||
2349 | if (parseNamedRegister(LLVMReg)) | ||||
2350 | return true; | ||||
2351 | const auto *TRI = MF.getSubtarget().getRegisterInfo(); | ||||
2352 | assert(TRI && "Expected target register info")(static_cast <bool> (TRI && "Expected target register info" ) ? void (0) : __assert_fail ("TRI && \"Expected target register info\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2352, __extension__ __PRETTY_FUNCTION__)); | ||||
2353 | int DwarfReg = TRI->getDwarfRegNum(LLVMReg, true); | ||||
2354 | if (DwarfReg < 0) | ||||
2355 | return error("invalid DWARF register"); | ||||
2356 | Reg = (unsigned)DwarfReg; | ||||
2357 | lex(); | ||||
2358 | return false; | ||||
2359 | } | ||||
2360 | |||||
2361 | bool MIParser::parseCFIAddressSpace(unsigned &AddressSpace) { | ||||
2362 | if (Token.isNot(MIToken::IntegerLiteral)) | ||||
2363 | return error("expected a cfi address space literal"); | ||||
2364 | if (Token.integerValue().isSigned()) | ||||
2365 | return error("expected an unsigned integer (cfi address space)"); | ||||
2366 | AddressSpace = Token.integerValue().getZExtValue(); | ||||
2367 | lex(); | ||||
2368 | return false; | ||||
2369 | } | ||||
2370 | |||||
2371 | bool MIParser::parseCFIEscapeValues(std::string &Values) { | ||||
2372 | do { | ||||
2373 | if (Token.isNot(MIToken::HexLiteral)) | ||||
2374 | return error("expected a hexadecimal literal"); | ||||
2375 | unsigned Value; | ||||
2376 | if (getUnsigned(Value)) | ||||
2377 | return true; | ||||
2378 | if (Value > UINT8_MAX(255)) | ||||
2379 | return error("expected a 8-bit integer (too large)"); | ||||
2380 | Values.push_back(static_cast<uint8_t>(Value)); | ||||
2381 | lex(); | ||||
2382 | } while (consumeIfPresent(MIToken::comma)); | ||||
2383 | return false; | ||||
2384 | } | ||||
2385 | |||||
2386 | bool MIParser::parseCFIOperand(MachineOperand &Dest) { | ||||
2387 | auto Kind = Token.kind(); | ||||
2388 | lex(); | ||||
2389 | int Offset; | ||||
2390 | Register Reg; | ||||
2391 | unsigned AddressSpace; | ||||
2392 | unsigned CFIIndex; | ||||
2393 | switch (Kind) { | ||||
2394 | case MIToken::kw_cfi_same_value: | ||||
2395 | if (parseCFIRegister(Reg)) | ||||
2396 | return true; | ||||
2397 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createSameValue(nullptr, Reg)); | ||||
2398 | break; | ||||
2399 | case MIToken::kw_cfi_offset: | ||||
2400 | if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || | ||||
2401 | parseCFIOffset(Offset)) | ||||
2402 | return true; | ||||
2403 | CFIIndex = | ||||
2404 | MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset)); | ||||
2405 | break; | ||||
2406 | case MIToken::kw_cfi_rel_offset: | ||||
2407 | if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || | ||||
2408 | parseCFIOffset(Offset)) | ||||
2409 | return true; | ||||
2410 | CFIIndex = MF.addFrameInst( | ||||
2411 | MCCFIInstruction::createRelOffset(nullptr, Reg, Offset)); | ||||
2412 | break; | ||||
2413 | case MIToken::kw_cfi_def_cfa_register: | ||||
2414 | if (parseCFIRegister(Reg)) | ||||
2415 | return true; | ||||
2416 | CFIIndex = | ||||
2417 | MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, Reg)); | ||||
2418 | break; | ||||
2419 | case MIToken::kw_cfi_def_cfa_offset: | ||||
2420 | if (parseCFIOffset(Offset)) | ||||
2421 | return true; | ||||
2422 | CFIIndex = | ||||
2423 | MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, Offset)); | ||||
2424 | break; | ||||
2425 | case MIToken::kw_cfi_adjust_cfa_offset: | ||||
2426 | if (parseCFIOffset(Offset)) | ||||
2427 | return true; | ||||
2428 | CFIIndex = MF.addFrameInst( | ||||
2429 | MCCFIInstruction::createAdjustCfaOffset(nullptr, Offset)); | ||||
2430 | break; | ||||
2431 | case MIToken::kw_cfi_def_cfa: | ||||
2432 | if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || | ||||
2433 | parseCFIOffset(Offset)) | ||||
2434 | return true; | ||||
2435 | CFIIndex = | ||||
2436 | MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, Reg, Offset)); | ||||
2437 | break; | ||||
2438 | case MIToken::kw_cfi_llvm_def_aspace_cfa: | ||||
2439 | if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || | ||||
2440 | parseCFIOffset(Offset) || expectAndConsume(MIToken::comma) || | ||||
2441 | parseCFIAddressSpace(AddressSpace)) | ||||
2442 | return true; | ||||
2443 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createLLVMDefAspaceCfa( | ||||
2444 | nullptr, Reg, Offset, AddressSpace)); | ||||
2445 | break; | ||||
2446 | case MIToken::kw_cfi_remember_state: | ||||
2447 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createRememberState(nullptr)); | ||||
2448 | break; | ||||
2449 | case MIToken::kw_cfi_restore: | ||||
2450 | if (parseCFIRegister(Reg)) | ||||
2451 | return true; | ||||
2452 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg)); | ||||
2453 | break; | ||||
2454 | case MIToken::kw_cfi_restore_state: | ||||
2455 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestoreState(nullptr)); | ||||
2456 | break; | ||||
2457 | case MIToken::kw_cfi_undefined: | ||||
2458 | if (parseCFIRegister(Reg)) | ||||
2459 | return true; | ||||
2460 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createUndefined(nullptr, Reg)); | ||||
2461 | break; | ||||
2462 | case MIToken::kw_cfi_register: { | ||||
2463 | Register Reg2; | ||||
2464 | if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || | ||||
2465 | parseCFIRegister(Reg2)) | ||||
2466 | return true; | ||||
2467 | |||||
2468 | CFIIndex = | ||||
2469 | MF.addFrameInst(MCCFIInstruction::createRegister(nullptr, Reg, Reg2)); | ||||
2470 | break; | ||||
2471 | } | ||||
2472 | case MIToken::kw_cfi_window_save: | ||||
2473 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr)); | ||||
2474 | break; | ||||
2475 | case MIToken::kw_cfi_aarch64_negate_ra_sign_state: | ||||
2476 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); | ||||
2477 | break; | ||||
2478 | case MIToken::kw_cfi_escape: { | ||||
2479 | std::string Values; | ||||
2480 | if (parseCFIEscapeValues(Values)) | ||||
2481 | return true; | ||||
2482 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(nullptr, Values)); | ||||
2483 | break; | ||||
2484 | } | ||||
2485 | default: | ||||
2486 | // TODO: Parse the other CFI operands. | ||||
2487 | llvm_unreachable("The current token should be a cfi operand")::llvm::llvm_unreachable_internal("The current token should be a cfi operand" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2487); | ||||
2488 | } | ||||
2489 | Dest = MachineOperand::CreateCFIIndex(CFIIndex); | ||||
2490 | return false; | ||||
2491 | } | ||||
2492 | |||||
2493 | bool MIParser::parseIRBlock(BasicBlock *&BB, const Function &F) { | ||||
2494 | switch (Token.kind()) { | ||||
2495 | case MIToken::NamedIRBlock: { | ||||
2496 | BB = dyn_cast_or_null<BasicBlock>( | ||||
2497 | F.getValueSymbolTable()->lookup(Token.stringValue())); | ||||
2498 | if (!BB) | ||||
2499 | return error(Twine("use of undefined IR block '") + Token.range() + "'"); | ||||
2500 | break; | ||||
2501 | } | ||||
2502 | case MIToken::IRBlock: { | ||||
2503 | unsigned SlotNumber = 0; | ||||
2504 | if (getUnsigned(SlotNumber)) | ||||
2505 | return true; | ||||
2506 | BB = const_cast<BasicBlock *>(getIRBlock(SlotNumber, F)); | ||||
2507 | if (!BB) | ||||
2508 | return error(Twine("use of undefined IR block '%ir-block.") + | ||||
2509 | Twine(SlotNumber) + "'"); | ||||
2510 | break; | ||||
2511 | } | ||||
2512 | default: | ||||
2513 | llvm_unreachable("The current token should be an IR block reference")::llvm::llvm_unreachable_internal("The current token should be an IR block reference" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2513); | ||||
2514 | } | ||||
2515 | return false; | ||||
2516 | } | ||||
2517 | |||||
2518 | bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) { | ||||
2519 | assert(Token.is(MIToken::kw_blockaddress))(static_cast <bool> (Token.is(MIToken::kw_blockaddress) ) ? void (0) : __assert_fail ("Token.is(MIToken::kw_blockaddress)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2519, __extension__ __PRETTY_FUNCTION__)); | ||||
2520 | lex(); | ||||
2521 | if (expectAndConsume(MIToken::lparen)) | ||||
2522 | return true; | ||||
2523 | if (Token.isNot(MIToken::GlobalValue) && | ||||
2524 | Token.isNot(MIToken::NamedGlobalValue)) | ||||
2525 | return error("expected a global value"); | ||||
2526 | GlobalValue *GV = nullptr; | ||||
2527 | if (parseGlobalValue(GV)) | ||||
2528 | return true; | ||||
2529 | auto *F = dyn_cast<Function>(GV); | ||||
2530 | if (!F) | ||||
2531 | return error("expected an IR function reference"); | ||||
2532 | lex(); | ||||
2533 | if (expectAndConsume(MIToken::comma)) | ||||
2534 | return true; | ||||
2535 | BasicBlock *BB = nullptr; | ||||
2536 | if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock)) | ||||
2537 | return error("expected an IR block reference"); | ||||
2538 | if (parseIRBlock(BB, *F)) | ||||
2539 | return true; | ||||
2540 | lex(); | ||||
2541 | if (expectAndConsume(MIToken::rparen)) | ||||
2542 | return true; | ||||
2543 | Dest = MachineOperand::CreateBA(BlockAddress::get(F, BB), /*Offset=*/0); | ||||
2544 | if (parseOperandsOffset(Dest)) | ||||
2545 | return true; | ||||
2546 | return false; | ||||
2547 | } | ||||
2548 | |||||
2549 | bool MIParser::parseIntrinsicOperand(MachineOperand &Dest) { | ||||
2550 | assert(Token.is(MIToken::kw_intrinsic))(static_cast <bool> (Token.is(MIToken::kw_intrinsic)) ? void (0) : __assert_fail ("Token.is(MIToken::kw_intrinsic)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2550, __extension__ __PRETTY_FUNCTION__)); | ||||
2551 | lex(); | ||||
2552 | if (expectAndConsume(MIToken::lparen)) | ||||
2553 | return error("expected syntax intrinsic(@llvm.whatever)"); | ||||
2554 | |||||
2555 | if (Token.isNot(MIToken::NamedGlobalValue)) | ||||
2556 | return error("expected syntax intrinsic(@llvm.whatever)"); | ||||
2557 | |||||
2558 | std::string Name = std::string(Token.stringValue()); | ||||
2559 | lex(); | ||||
2560 | |||||
2561 | if (expectAndConsume(MIToken::rparen)) | ||||
2562 | return error("expected ')' to terminate intrinsic name"); | ||||
2563 | |||||
2564 | // Find out what intrinsic we're dealing with, first try the global namespace | ||||
2565 | // and then the target's private intrinsics if that fails. | ||||
2566 | const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo(); | ||||
2567 | Intrinsic::ID ID = Function::lookupIntrinsicID(Name); | ||||
2568 | if (ID == Intrinsic::not_intrinsic && TII) | ||||
2569 | ID = static_cast<Intrinsic::ID>(TII->lookupName(Name)); | ||||
2570 | |||||
2571 | if (ID == Intrinsic::not_intrinsic) | ||||
2572 | return error("unknown intrinsic name"); | ||||
2573 | Dest = MachineOperand::CreateIntrinsicID(ID); | ||||
2574 | |||||
2575 | return false; | ||||
2576 | } | ||||
2577 | |||||
2578 | bool MIParser::parsePredicateOperand(MachineOperand &Dest) { | ||||
2579 | assert(Token.is(MIToken::kw_intpred) || Token.is(MIToken::kw_floatpred))(static_cast <bool> (Token.is(MIToken::kw_intpred) || Token .is(MIToken::kw_floatpred)) ? void (0) : __assert_fail ("Token.is(MIToken::kw_intpred) || Token.is(MIToken::kw_floatpred)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2579, __extension__ __PRETTY_FUNCTION__)); | ||||
2580 | bool IsFloat = Token.is(MIToken::kw_floatpred); | ||||
2581 | lex(); | ||||
2582 | |||||
2583 | if (expectAndConsume(MIToken::lparen)) | ||||
2584 | return error("expected syntax intpred(whatever) or floatpred(whatever"); | ||||
2585 | |||||
2586 | if (Token.isNot(MIToken::Identifier)) | ||||
2587 | return error("whatever"); | ||||
2588 | |||||
2589 | CmpInst::Predicate Pred; | ||||
2590 | if (IsFloat) { | ||||
2591 | Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue()) | ||||
2592 | .Case("false", CmpInst::FCMP_FALSE) | ||||
2593 | .Case("oeq", CmpInst::FCMP_OEQ) | ||||
2594 | .Case("ogt", CmpInst::FCMP_OGT) | ||||
2595 | .Case("oge", CmpInst::FCMP_OGE) | ||||
2596 | .Case("olt", CmpInst::FCMP_OLT) | ||||
2597 | .Case("ole", CmpInst::FCMP_OLE) | ||||
2598 | .Case("one", CmpInst::FCMP_ONE) | ||||
2599 | .Case("ord", CmpInst::FCMP_ORD) | ||||
2600 | .Case("uno", CmpInst::FCMP_UNO) | ||||
2601 | .Case("ueq", CmpInst::FCMP_UEQ) | ||||
2602 | .Case("ugt", CmpInst::FCMP_UGT) | ||||
2603 | .Case("uge", CmpInst::FCMP_UGE) | ||||
2604 | .Case("ult", CmpInst::FCMP_ULT) | ||||
2605 | .Case("ule", CmpInst::FCMP_ULE) | ||||
2606 | .Case("une", CmpInst::FCMP_UNE) | ||||
2607 | .Case("true", CmpInst::FCMP_TRUE) | ||||
2608 | .Default(CmpInst::BAD_FCMP_PREDICATE); | ||||
2609 | if (!CmpInst::isFPPredicate(Pred)) | ||||
2610 | return error("invalid floating-point predicate"); | ||||
2611 | } else { | ||||
2612 | Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue()) | ||||
2613 | .Case("eq", CmpInst::ICMP_EQ) | ||||
2614 | .Case("ne", CmpInst::ICMP_NE) | ||||
2615 | .Case("sgt", CmpInst::ICMP_SGT) | ||||
2616 | .Case("sge", CmpInst::ICMP_SGE) | ||||
2617 | .Case("slt", CmpInst::ICMP_SLT) | ||||
2618 | .Case("sle", CmpInst::ICMP_SLE) | ||||
2619 | .Case("ugt", CmpInst::ICMP_UGT) | ||||
2620 | .Case("uge", CmpInst::ICMP_UGE) | ||||
2621 | .Case("ult", CmpInst::ICMP_ULT) | ||||
2622 | .Case("ule", CmpInst::ICMP_ULE) | ||||
2623 | .Default(CmpInst::BAD_ICMP_PREDICATE); | ||||
2624 | if (!CmpInst::isIntPredicate(Pred)) | ||||
2625 | return error("invalid integer predicate"); | ||||
2626 | } | ||||
2627 | |||||
2628 | lex(); | ||||
2629 | Dest = MachineOperand::CreatePredicate(Pred); | ||||
2630 | if (expectAndConsume(MIToken::rparen)) | ||||
2631 | return error("predicate should be terminated by ')'."); | ||||
2632 | |||||
2633 | return false; | ||||
2634 | } | ||||
2635 | |||||
2636 | bool MIParser::parseShuffleMaskOperand(MachineOperand &Dest) { | ||||
2637 | assert(Token.is(MIToken::kw_shufflemask))(static_cast <bool> (Token.is(MIToken::kw_shufflemask)) ? void (0) : __assert_fail ("Token.is(MIToken::kw_shufflemask)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2637, __extension__ __PRETTY_FUNCTION__)); | ||||
2638 | |||||
2639 | lex(); | ||||
2640 | if (expectAndConsume(MIToken::lparen)) | ||||
2641 | return error("expected syntax shufflemask(<integer or undef>, ...)"); | ||||
2642 | |||||
2643 | SmallVector<int, 32> ShufMask; | ||||
2644 | do { | ||||
2645 | if (Token.is(MIToken::kw_undef)) { | ||||
2646 | ShufMask.push_back(-1); | ||||
2647 | } else if (Token.is(MIToken::IntegerLiteral)) { | ||||
2648 | const APSInt &Int = Token.integerValue(); | ||||
2649 | ShufMask.push_back(Int.getExtValue()); | ||||
2650 | } else | ||||
2651 | return error("expected integer constant"); | ||||
2652 | |||||
2653 | lex(); | ||||
2654 | } while (consumeIfPresent(MIToken::comma)); | ||||
2655 | |||||
2656 | if (expectAndConsume(MIToken::rparen)) | ||||
2657 | return error("shufflemask should be terminated by ')'."); | ||||
2658 | |||||
2659 | ArrayRef<int> MaskAlloc = MF.allocateShuffleMask(ShufMask); | ||||
2660 | Dest = MachineOperand::CreateShuffleMask(MaskAlloc); | ||||
2661 | return false; | ||||
2662 | } | ||||
2663 | |||||
2664 | bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) { | ||||
2665 | assert(Token.is(MIToken::kw_target_index))(static_cast <bool> (Token.is(MIToken::kw_target_index) ) ? void (0) : __assert_fail ("Token.is(MIToken::kw_target_index)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2665, __extension__ __PRETTY_FUNCTION__)); | ||||
2666 | lex(); | ||||
2667 | if (expectAndConsume(MIToken::lparen)) | ||||
2668 | return true; | ||||
2669 | if (Token.isNot(MIToken::Identifier)) | ||||
2670 | return error("expected the name of the target index"); | ||||
2671 | int Index = 0; | ||||
2672 | if (PFS.Target.getTargetIndex(Token.stringValue(), Index)) | ||||
2673 | return error("use of undefined target index '" + Token.stringValue() + "'"); | ||||
2674 | lex(); | ||||
2675 | if (expectAndConsume(MIToken::rparen)) | ||||
2676 | return true; | ||||
2677 | Dest = MachineOperand::CreateTargetIndex(unsigned(Index), /*Offset=*/0); | ||||
2678 | if (parseOperandsOffset(Dest)) | ||||
2679 | return true; | ||||
2680 | return false; | ||||
2681 | } | ||||
2682 | |||||
2683 | bool MIParser::parseCustomRegisterMaskOperand(MachineOperand &Dest) { | ||||
2684 | assert(Token.stringValue() == "CustomRegMask" && "Expected a custom RegMask")(static_cast <bool> (Token.stringValue() == "CustomRegMask" && "Expected a custom RegMask") ? void (0) : __assert_fail ("Token.stringValue() == \"CustomRegMask\" && \"Expected a custom RegMask\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2684, __extension__ __PRETTY_FUNCTION__)); | ||||
2685 | lex(); | ||||
2686 | if (expectAndConsume(MIToken::lparen)) | ||||
2687 | return true; | ||||
2688 | |||||
2689 | uint32_t *Mask = MF.allocateRegMask(); | ||||
2690 | while (true) { | ||||
2691 | if (Token.isNot(MIToken::NamedRegister)) | ||||
2692 | return error("expected a named register"); | ||||
2693 | Register Reg; | ||||
2694 | if (parseNamedRegister(Reg)) | ||||
2695 | return true; | ||||
2696 | lex(); | ||||
2697 | Mask[Reg / 32] |= 1U << (Reg % 32); | ||||
2698 | // TODO: Report an error if the same register is used more than once. | ||||
2699 | if (Token.isNot(MIToken::comma)) | ||||
2700 | break; | ||||
2701 | lex(); | ||||
2702 | } | ||||
2703 | |||||
2704 | if (expectAndConsume(MIToken::rparen)) | ||||
2705 | return true; | ||||
2706 | Dest = MachineOperand::CreateRegMask(Mask); | ||||
2707 | return false; | ||||
2708 | } | ||||
2709 | |||||
2710 | bool MIParser::parseLiveoutRegisterMaskOperand(MachineOperand &Dest) { | ||||
2711 | assert(Token.is(MIToken::kw_liveout))(static_cast <bool> (Token.is(MIToken::kw_liveout)) ? void (0) : __assert_fail ("Token.is(MIToken::kw_liveout)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2711, __extension__ __PRETTY_FUNCTION__)); | ||||
2712 | uint32_t *Mask = MF.allocateRegMask(); | ||||
2713 | lex(); | ||||
2714 | if (expectAndConsume(MIToken::lparen)) | ||||
2715 | return true; | ||||
2716 | while (true) { | ||||
2717 | if (Token.isNot(MIToken::NamedRegister)) | ||||
2718 | return error("expected a named register"); | ||||
2719 | Register Reg; | ||||
2720 | if (parseNamedRegister(Reg)) | ||||
2721 | return true; | ||||
2722 | lex(); | ||||
2723 | Mask[Reg / 32] |= 1U << (Reg % 32); | ||||
2724 | // TODO: Report an error if the same register is used more than once. | ||||
2725 | if (Token.isNot(MIToken::comma)) | ||||
2726 | break; | ||||
2727 | lex(); | ||||
2728 | } | ||||
2729 | if (expectAndConsume(MIToken::rparen)) | ||||
2730 | return true; | ||||
2731 | Dest = MachineOperand::CreateRegLiveOut(Mask); | ||||
2732 | return false; | ||||
2733 | } | ||||
2734 | |||||
2735 | bool MIParser::parseMachineOperand(const unsigned OpCode, const unsigned OpIdx, | ||||
2736 | MachineOperand &Dest, | ||||
2737 | Optional<unsigned> &TiedDefIdx) { | ||||
2738 | switch (Token.kind()) { | ||||
2739 | case MIToken::kw_implicit: | ||||
2740 | case MIToken::kw_implicit_define: | ||||
2741 | case MIToken::kw_def: | ||||
2742 | case MIToken::kw_dead: | ||||
2743 | case MIToken::kw_killed: | ||||
2744 | case MIToken::kw_undef: | ||||
2745 | case MIToken::kw_internal: | ||||
2746 | case MIToken::kw_early_clobber: | ||||
2747 | case MIToken::kw_debug_use: | ||||
2748 | case MIToken::kw_renamable: | ||||
2749 | case MIToken::underscore: | ||||
2750 | case MIToken::NamedRegister: | ||||
2751 | case MIToken::VirtualRegister: | ||||
2752 | case MIToken::NamedVirtualRegister: | ||||
2753 | return parseRegisterOperand(Dest, TiedDefIdx); | ||||
2754 | case MIToken::IntegerLiteral: | ||||
2755 | return parseImmediateOperand(Dest); | ||||
2756 | case MIToken::kw_half: | ||||
2757 | case MIToken::kw_float: | ||||
2758 | case MIToken::kw_double: | ||||
2759 | case MIToken::kw_x86_fp80: | ||||
2760 | case MIToken::kw_fp128: | ||||
2761 | case MIToken::kw_ppc_fp128: | ||||
2762 | return parseFPImmediateOperand(Dest); | ||||
2763 | case MIToken::MachineBasicBlock: | ||||
2764 | return parseMBBOperand(Dest); | ||||
2765 | case MIToken::StackObject: | ||||
2766 | return parseStackObjectOperand(Dest); | ||||
2767 | case MIToken::FixedStackObject: | ||||
2768 | return parseFixedStackObjectOperand(Dest); | ||||
2769 | case MIToken::GlobalValue: | ||||
2770 | case MIToken::NamedGlobalValue: | ||||
2771 | return parseGlobalAddressOperand(Dest); | ||||
2772 | case MIToken::ConstantPoolItem: | ||||
2773 | return parseConstantPoolIndexOperand(Dest); | ||||
2774 | case MIToken::JumpTableIndex: | ||||
2775 | return parseJumpTableIndexOperand(Dest); | ||||
2776 | case MIToken::ExternalSymbol: | ||||
2777 | return parseExternalSymbolOperand(Dest); | ||||
2778 | case MIToken::MCSymbol: | ||||
2779 | return parseMCSymbolOperand(Dest); | ||||
2780 | case MIToken::SubRegisterIndex: | ||||
2781 | return parseSubRegisterIndexOperand(Dest); | ||||
2782 | case MIToken::md_diexpr: | ||||
2783 | case MIToken::exclaim: | ||||
2784 | return parseMetadataOperand(Dest); | ||||
2785 | case MIToken::kw_cfi_same_value: | ||||
2786 | case MIToken::kw_cfi_offset: | ||||
2787 | case MIToken::kw_cfi_rel_offset: | ||||
2788 | case MIToken::kw_cfi_def_cfa_register: | ||||
2789 | case MIToken::kw_cfi_def_cfa_offset: | ||||
2790 | case MIToken::kw_cfi_adjust_cfa_offset: | ||||
2791 | case MIToken::kw_cfi_escape: | ||||
2792 | case MIToken::kw_cfi_def_cfa: | ||||
2793 | case MIToken::kw_cfi_llvm_def_aspace_cfa: | ||||
2794 | case MIToken::kw_cfi_register: | ||||
2795 | case MIToken::kw_cfi_remember_state: | ||||
2796 | case MIToken::kw_cfi_restore: | ||||
2797 | case MIToken::kw_cfi_restore_state: | ||||
2798 | case MIToken::kw_cfi_undefined: | ||||
2799 | case MIToken::kw_cfi_window_save: | ||||
2800 | case MIToken::kw_cfi_aarch64_negate_ra_sign_state: | ||||
2801 | return parseCFIOperand(Dest); | ||||
2802 | case MIToken::kw_blockaddress: | ||||
2803 | return parseBlockAddressOperand(Dest); | ||||
2804 | case MIToken::kw_intrinsic: | ||||
2805 | return parseIntrinsicOperand(Dest); | ||||
2806 | case MIToken::kw_target_index: | ||||
2807 | return parseTargetIndexOperand(Dest); | ||||
2808 | case MIToken::kw_liveout: | ||||
2809 | return parseLiveoutRegisterMaskOperand(Dest); | ||||
2810 | case MIToken::kw_floatpred: | ||||
2811 | case MIToken::kw_intpred: | ||||
2812 | return parsePredicateOperand(Dest); | ||||
2813 | case MIToken::kw_shufflemask: | ||||
2814 | return parseShuffleMaskOperand(Dest); | ||||
2815 | case MIToken::Error: | ||||
2816 | return true; | ||||
2817 | case MIToken::Identifier: | ||||
2818 | if (const auto *RegMask = PFS.Target.getRegMask(Token.stringValue())) { | ||||
2819 | Dest = MachineOperand::CreateRegMask(RegMask); | ||||
2820 | lex(); | ||||
2821 | break; | ||||
2822 | } else if (Token.stringValue() == "CustomRegMask") { | ||||
2823 | return parseCustomRegisterMaskOperand(Dest); | ||||
2824 | } else | ||||
2825 | return parseTypedImmediateOperand(Dest); | ||||
2826 | case MIToken::dot: { | ||||
2827 | const auto *TII = MF.getSubtarget().getInstrInfo(); | ||||
2828 | if (const auto *Formatter = TII->getMIRFormatter()) { | ||||
2829 | return parseTargetImmMnemonic(OpCode, OpIdx, Dest, *Formatter); | ||||
2830 | } | ||||
2831 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | ||||
2832 | } | ||||
2833 | default: | ||||
2834 | // FIXME: Parse the MCSymbol machine operand. | ||||
2835 | return error("expected a machine operand"); | ||||
2836 | } | ||||
2837 | return false; | ||||
2838 | } | ||||
2839 | |||||
2840 | bool MIParser::parseMachineOperandAndTargetFlags( | ||||
2841 | const unsigned OpCode, const unsigned OpIdx, MachineOperand &Dest, | ||||
2842 | Optional<unsigned> &TiedDefIdx) { | ||||
2843 | unsigned TF = 0; | ||||
2844 | bool HasTargetFlags = false; | ||||
2845 | if (Token.is(MIToken::kw_target_flags)) { | ||||
2846 | HasTargetFlags = true; | ||||
2847 | lex(); | ||||
2848 | if (expectAndConsume(MIToken::lparen)) | ||||
2849 | return true; | ||||
2850 | if (Token.isNot(MIToken::Identifier)) | ||||
2851 | return error("expected the name of the target flag"); | ||||
2852 | if (PFS.Target.getDirectTargetFlag(Token.stringValue(), TF)) { | ||||
2853 | if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), TF)) | ||||
2854 | return error("use of undefined target flag '" + Token.stringValue() + | ||||
2855 | "'"); | ||||
2856 | } | ||||
2857 | lex(); | ||||
2858 | while (Token.is(MIToken::comma)) { | ||||
2859 | lex(); | ||||
2860 | if (Token.isNot(MIToken::Identifier)) | ||||
2861 | return error("expected the name of the target flag"); | ||||
2862 | unsigned BitFlag = 0; | ||||
2863 | if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), BitFlag)) | ||||
2864 | return error("use of undefined target flag '" + Token.stringValue() + | ||||
2865 | "'"); | ||||
2866 | // TODO: Report an error when using a duplicate bit target flag. | ||||
2867 | TF |= BitFlag; | ||||
2868 | lex(); | ||||
2869 | } | ||||
2870 | if (expectAndConsume(MIToken::rparen)) | ||||
2871 | return true; | ||||
2872 | } | ||||
2873 | auto Loc = Token.location(); | ||||
2874 | if (parseMachineOperand(OpCode, OpIdx, Dest, TiedDefIdx)) | ||||
2875 | return true; | ||||
2876 | if (!HasTargetFlags) | ||||
2877 | return false; | ||||
2878 | if (Dest.isReg()) | ||||
2879 | return error(Loc, "register operands can't have target flags"); | ||||
2880 | Dest.setTargetFlags(TF); | ||||
2881 | return false; | ||||
2882 | } | ||||
2883 | |||||
2884 | bool MIParser::parseOffset(int64_t &Offset) { | ||||
2885 | if (Token.isNot(MIToken::plus) && Token.isNot(MIToken::minus)) | ||||
2886 | return false; | ||||
2887 | StringRef Sign = Token.range(); | ||||
2888 | bool IsNegative = Token.is(MIToken::minus); | ||||
2889 | lex(); | ||||
2890 | if (Token.isNot(MIToken::IntegerLiteral)) | ||||
2891 | return error("expected an integer literal after '" + Sign + "'"); | ||||
2892 | if (Token.integerValue().getMinSignedBits() > 64) | ||||
2893 | return error("expected 64-bit integer (too large)"); | ||||
2894 | Offset = Token.integerValue().getExtValue(); | ||||
2895 | if (IsNegative) | ||||
2896 | Offset = -Offset; | ||||
2897 | lex(); | ||||
2898 | return false; | ||||
2899 | } | ||||
2900 | |||||
2901 | bool MIParser::parseAlignment(unsigned &Alignment) { | ||||
2902 | assert(Token.is(MIToken::kw_align) || Token.is(MIToken::kw_basealign))(static_cast <bool> (Token.is(MIToken::kw_align) || Token .is(MIToken::kw_basealign)) ? void (0) : __assert_fail ("Token.is(MIToken::kw_align) || Token.is(MIToken::kw_basealign)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2902, __extension__ __PRETTY_FUNCTION__)); | ||||
2903 | lex(); | ||||
2904 | if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) | ||||
2905 | return error("expected an integer literal after 'align'"); | ||||
2906 | if (getUnsigned(Alignment)) | ||||
2907 | return true; | ||||
2908 | lex(); | ||||
2909 | |||||
2910 | if (!isPowerOf2_32(Alignment)) | ||||
2911 | return error("expected a power-of-2 literal after 'align'"); | ||||
2912 | |||||
2913 | return false; | ||||
2914 | } | ||||
2915 | |||||
2916 | bool MIParser::parseAddrspace(unsigned &Addrspace) { | ||||
2917 | assert(Token.is(MIToken::kw_addrspace))(static_cast <bool> (Token.is(MIToken::kw_addrspace)) ? void (0) : __assert_fail ("Token.is(MIToken::kw_addrspace)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2917, __extension__ __PRETTY_FUNCTION__)); | ||||
2918 | lex(); | ||||
2919 | if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) | ||||
2920 | return error("expected an integer literal after 'addrspace'"); | ||||
2921 | if (getUnsigned(Addrspace)) | ||||
2922 | return true; | ||||
2923 | lex(); | ||||
2924 | return false; | ||||
2925 | } | ||||
2926 | |||||
2927 | bool MIParser::parseOperandsOffset(MachineOperand &Op) { | ||||
2928 | int64_t Offset = 0; | ||||
2929 | if (parseOffset(Offset)) | ||||
2930 | return true; | ||||
2931 | Op.setOffset(Offset); | ||||
2932 | return false; | ||||
2933 | } | ||||
2934 | |||||
2935 | static bool parseIRValue(const MIToken &Token, PerFunctionMIParsingState &PFS, | ||||
2936 | const Value *&V, ErrorCallbackType ErrCB) { | ||||
2937 | switch (Token.kind()) { | ||||
2938 | case MIToken::NamedIRValue: { | ||||
2939 | V = PFS.MF.getFunction().getValueSymbolTable()->lookup(Token.stringValue()); | ||||
2940 | break; | ||||
2941 | } | ||||
2942 | case MIToken::IRValue: { | ||||
2943 | unsigned SlotNumber = 0; | ||||
2944 | if (getUnsigned(Token, SlotNumber, ErrCB)) | ||||
2945 | return true; | ||||
2946 | V = PFS.getIRValue(SlotNumber); | ||||
2947 | break; | ||||
2948 | } | ||||
2949 | case MIToken::NamedGlobalValue: | ||||
2950 | case MIToken::GlobalValue: { | ||||
2951 | GlobalValue *GV = nullptr; | ||||
2952 | if (parseGlobalValue(Token, PFS, GV, ErrCB)) | ||||
2953 | return true; | ||||
2954 | V = GV; | ||||
2955 | break; | ||||
2956 | } | ||||
2957 | case MIToken::QuotedIRValue: { | ||||
2958 | const Constant *C = nullptr; | ||||
2959 | if (parseIRConstant(Token.location(), Token.stringValue(), PFS, C, ErrCB)) | ||||
2960 | return true; | ||||
2961 | V = C; | ||||
2962 | break; | ||||
2963 | } | ||||
2964 | case MIToken::kw_unknown_address: | ||||
2965 | V = nullptr; | ||||
2966 | return false; | ||||
2967 | default: | ||||
2968 | llvm_unreachable("The current token should be an IR block reference")::llvm::llvm_unreachable_internal("The current token should be an IR block reference" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 2968); | ||||
2969 | } | ||||
2970 | if (!V) | ||||
2971 | return ErrCB(Token.location(), Twine("use of undefined IR value '") + Token.range() + "'"); | ||||
2972 | return false; | ||||
2973 | } | ||||
2974 | |||||
2975 | bool MIParser::parseIRValue(const Value *&V) { | ||||
2976 | return ::parseIRValue( | ||||
2977 | Token, PFS, V, [this](StringRef::iterator Loc, const Twine &Msg) -> bool { | ||||
2978 | return error(Loc, Msg); | ||||
2979 | }); | ||||
2980 | } | ||||
2981 | |||||
2982 | bool MIParser::getUint64(uint64_t &Result) { | ||||
2983 | if (Token.hasIntegerValue()) { | ||||
2984 | if (Token.integerValue().getActiveBits() > 64) | ||||
2985 | return error("expected 64-bit integer (too large)"); | ||||
2986 | Result = Token.integerValue().getZExtValue(); | ||||
2987 | return false; | ||||
2988 | } | ||||
2989 | if (Token.is(MIToken::HexLiteral)) { | ||||
2990 | APInt A; | ||||
2991 | if (getHexUint(A)) | ||||
2992 | return true; | ||||
2993 | if (A.getBitWidth() > 64) | ||||
2994 | return error("expected 64-bit integer (too large)"); | ||||
2995 | Result = A.getZExtValue(); | ||||
2996 | return false; | ||||
2997 | } | ||||
2998 | return true; | ||||
2999 | } | ||||
3000 | |||||
3001 | bool MIParser::getHexUint(APInt &Result) { | ||||
3002 | return ::getHexUint(Token, Result); | ||||
3003 | } | ||||
3004 | |||||
3005 | bool MIParser::parseMemoryOperandFlag(MachineMemOperand::Flags &Flags) { | ||||
3006 | const auto OldFlags = Flags; | ||||
3007 | switch (Token.kind()) { | ||||
3008 | case MIToken::kw_volatile: | ||||
3009 | Flags |= MachineMemOperand::MOVolatile; | ||||
3010 | break; | ||||
3011 | case MIToken::kw_non_temporal: | ||||
3012 | Flags |= MachineMemOperand::MONonTemporal; | ||||
3013 | break; | ||||
3014 | case MIToken::kw_dereferenceable: | ||||
3015 | Flags |= MachineMemOperand::MODereferenceable; | ||||
3016 | break; | ||||
3017 | case MIToken::kw_invariant: | ||||
3018 | Flags |= MachineMemOperand::MOInvariant; | ||||
3019 | break; | ||||
3020 | case MIToken::StringConstant: { | ||||
3021 | MachineMemOperand::Flags TF; | ||||
3022 | if (PFS.Target.getMMOTargetFlag(Token.stringValue(), TF)) | ||||
3023 | return error("use of undefined target MMO flag '" + Token.stringValue() + | ||||
3024 | "'"); | ||||
3025 | Flags |= TF; | ||||
3026 | break; | ||||
3027 | } | ||||
3028 | default: | ||||
3029 | llvm_unreachable("The current token should be a memory operand flag")::llvm::llvm_unreachable_internal("The current token should be a memory operand flag" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 3029); | ||||
3030 | } | ||||
3031 | if (OldFlags == Flags) | ||||
3032 | // We know that the same flag is specified more than once when the flags | ||||
3033 | // weren't modified. | ||||
3034 | return error("duplicate '" + Token.stringValue() + "' memory operand flag"); | ||||
3035 | lex(); | ||||
3036 | return false; | ||||
3037 | } | ||||
3038 | |||||
3039 | bool MIParser::parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV) { | ||||
3040 | switch (Token.kind()) { | ||||
3041 | case MIToken::kw_stack: | ||||
3042 | PSV = MF.getPSVManager().getStack(); | ||||
3043 | break; | ||||
3044 | case MIToken::kw_got: | ||||
3045 | PSV = MF.getPSVManager().getGOT(); | ||||
3046 | break; | ||||
3047 | case MIToken::kw_jump_table: | ||||
3048 | PSV = MF.getPSVManager().getJumpTable(); | ||||
3049 | break; | ||||
3050 | case MIToken::kw_constant_pool: | ||||
3051 | PSV = MF.getPSVManager().getConstantPool(); | ||||
3052 | break; | ||||
3053 | case MIToken::FixedStackObject: { | ||||
3054 | int FI; | ||||
3055 | if (parseFixedStackFrameIndex(FI)) | ||||
3056 | return true; | ||||
3057 | PSV = MF.getPSVManager().getFixedStack(FI); | ||||
3058 | // The token was already consumed, so use return here instead of break. | ||||
3059 | return false; | ||||
3060 | } | ||||
3061 | case MIToken::StackObject: { | ||||
3062 | int FI; | ||||
3063 | if (parseStackFrameIndex(FI)) | ||||
3064 | return true; | ||||
3065 | PSV = MF.getPSVManager().getFixedStack(FI); | ||||
3066 | // The token was already consumed, so use return here instead of break. | ||||
3067 | return false; | ||||
3068 | } | ||||
3069 | case MIToken::kw_call_entry: | ||||
3070 | lex(); | ||||
3071 | switch (Token.kind()) { | ||||
3072 | case MIToken::GlobalValue: | ||||
3073 | case MIToken::NamedGlobalValue: { | ||||
3074 | GlobalValue *GV = nullptr; | ||||
3075 | if (parseGlobalValue(GV)) | ||||
3076 | return true; | ||||
3077 | PSV = MF.getPSVManager().getGlobalValueCallEntry(GV); | ||||
3078 | break; | ||||
3079 | } | ||||
3080 | case MIToken::ExternalSymbol: | ||||
3081 | PSV = MF.getPSVManager().getExternalSymbolCallEntry( | ||||
3082 | MF.createExternalSymbolName(Token.stringValue())); | ||||
3083 | break; | ||||
3084 | default: | ||||
3085 | return error( | ||||
3086 | "expected a global value or an external symbol after 'call-entry'"); | ||||
3087 | } | ||||
3088 | break; | ||||
3089 | case MIToken::kw_custom: { | ||||
3090 | lex(); | ||||
3091 | const auto *TII = MF.getSubtarget().getInstrInfo(); | ||||
3092 | if (const auto *Formatter = TII->getMIRFormatter()) { | ||||
3093 | if (Formatter->parseCustomPseudoSourceValue( | ||||
3094 | Token.stringValue(), MF, PFS, PSV, | ||||
3095 | [this](StringRef::iterator Loc, const Twine &Msg) -> bool { | ||||
3096 | return error(Loc, Msg); | ||||
3097 | })) | ||||
3098 | return true; | ||||
3099 | } else | ||||
3100 | return error("unable to parse target custom pseudo source value"); | ||||
3101 | break; | ||||
3102 | } | ||||
3103 | default: | ||||
3104 | llvm_unreachable("The current token should be pseudo source value")::llvm::llvm_unreachable_internal("The current token should be pseudo source value" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 3104); | ||||
3105 | } | ||||
3106 | lex(); | ||||
3107 | return false; | ||||
3108 | } | ||||
3109 | |||||
3110 | bool MIParser::parseMachinePointerInfo(MachinePointerInfo &Dest) { | ||||
3111 | if (Token.is(MIToken::kw_constant_pool) || Token.is(MIToken::kw_stack) || | ||||
3112 | Token.is(MIToken::kw_got) || Token.is(MIToken::kw_jump_table) || | ||||
3113 | Token.is(MIToken::FixedStackObject) || Token.is(MIToken::StackObject) || | ||||
3114 | Token.is(MIToken::kw_call_entry) || Token.is(MIToken::kw_custom)) { | ||||
3115 | const PseudoSourceValue *PSV = nullptr; | ||||
3116 | if (parseMemoryPseudoSourceValue(PSV)) | ||||
3117 | return true; | ||||
3118 | int64_t Offset = 0; | ||||
3119 | if (parseOffset(Offset)) | ||||
3120 | return true; | ||||
3121 | Dest = MachinePointerInfo(PSV, Offset); | ||||
3122 | return false; | ||||
3123 | } | ||||
3124 | if (Token.isNot(MIToken::NamedIRValue) && Token.isNot(MIToken::IRValue) && | ||||
3125 | Token.isNot(MIToken::GlobalValue) && | ||||
3126 | Token.isNot(MIToken::NamedGlobalValue) && | ||||
3127 | Token.isNot(MIToken::QuotedIRValue) && | ||||
3128 | Token.isNot(MIToken::kw_unknown_address)) | ||||
3129 | return error("expected an IR value reference"); | ||||
3130 | const Value *V = nullptr; | ||||
3131 | if (parseIRValue(V)) | ||||
3132 | return true; | ||||
3133 | if (V && !V->getType()->isPointerTy()) | ||||
3134 | return error("expected a pointer IR value"); | ||||
3135 | lex(); | ||||
3136 | int64_t Offset = 0; | ||||
3137 | if (parseOffset(Offset)) | ||||
3138 | return true; | ||||
3139 | Dest = MachinePointerInfo(V, Offset); | ||||
3140 | return false; | ||||
3141 | } | ||||
3142 | |||||
3143 | bool MIParser::parseOptionalScope(LLVMContext &Context, | ||||
3144 | SyncScope::ID &SSID) { | ||||
3145 | SSID = SyncScope::System; | ||||
3146 | if (Token.is(MIToken::Identifier) && Token.stringValue() == "syncscope") { | ||||
3147 | lex(); | ||||
3148 | if (expectAndConsume(MIToken::lparen)) | ||||
3149 | return error("expected '(' in syncscope"); | ||||
3150 | |||||
3151 | std::string SSN; | ||||
3152 | if (parseStringConstant(SSN)) | ||||
3153 | return true; | ||||
3154 | |||||
3155 | SSID = Context.getOrInsertSyncScopeID(SSN); | ||||
3156 | if (expectAndConsume(MIToken::rparen)) | ||||
3157 | return error("expected ')' in syncscope"); | ||||
3158 | } | ||||
3159 | |||||
3160 | return false; | ||||
3161 | } | ||||
3162 | |||||
3163 | bool MIParser::parseOptionalAtomicOrdering(AtomicOrdering &Order) { | ||||
3164 | Order = AtomicOrdering::NotAtomic; | ||||
3165 | if (Token.isNot(MIToken::Identifier)) | ||||
3166 | return false; | ||||
3167 | |||||
3168 | Order = StringSwitch<AtomicOrdering>(Token.stringValue()) | ||||
3169 | .Case("unordered", AtomicOrdering::Unordered) | ||||
3170 | .Case("monotonic", AtomicOrdering::Monotonic) | ||||
3171 | .Case("acquire", AtomicOrdering::Acquire) | ||||
3172 | .Case("release", AtomicOrdering::Release) | ||||
3173 | .Case("acq_rel", AtomicOrdering::AcquireRelease) | ||||
3174 | .Case("seq_cst", AtomicOrdering::SequentiallyConsistent) | ||||
3175 | .Default(AtomicOrdering::NotAtomic); | ||||
3176 | |||||
3177 | if (Order != AtomicOrdering::NotAtomic) { | ||||
3178 | lex(); | ||||
3179 | return false; | ||||
3180 | } | ||||
3181 | |||||
3182 | return error("expected an atomic scope, ordering or a size specification"); | ||||
3183 | } | ||||
3184 | |||||
3185 | bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) { | ||||
3186 | if (expectAndConsume(MIToken::lparen)) | ||||
3187 | return true; | ||||
3188 | MachineMemOperand::Flags Flags = MachineMemOperand::MONone; | ||||
3189 | while (Token.isMemoryOperandFlag()) { | ||||
3190 | if (parseMemoryOperandFlag(Flags)) | ||||
3191 | return true; | ||||
3192 | } | ||||
3193 | if (Token.isNot(MIToken::Identifier) || | ||||
3194 | (Token.stringValue() != "load" && Token.stringValue() != "store")) | ||||
3195 | return error("expected 'load' or 'store' memory operation"); | ||||
3196 | if (Token.stringValue() == "load") | ||||
3197 | Flags |= MachineMemOperand::MOLoad; | ||||
3198 | else | ||||
3199 | Flags |= MachineMemOperand::MOStore; | ||||
3200 | lex(); | ||||
3201 | |||||
3202 | // Optional 'store' for operands that both load and store. | ||||
3203 | if (Token.is(MIToken::Identifier) && Token.stringValue() == "store") { | ||||
3204 | Flags |= MachineMemOperand::MOStore; | ||||
3205 | lex(); | ||||
3206 | } | ||||
3207 | |||||
3208 | // Optional synchronization scope. | ||||
3209 | SyncScope::ID SSID; | ||||
3210 | if (parseOptionalScope(MF.getFunction().getContext(), SSID)) | ||||
3211 | return true; | ||||
3212 | |||||
3213 | // Up to two atomic orderings (cmpxchg provides guarantees on failure). | ||||
3214 | AtomicOrdering Order, FailureOrder; | ||||
3215 | if (parseOptionalAtomicOrdering(Order)) | ||||
3216 | return true; | ||||
3217 | |||||
3218 | if (parseOptionalAtomicOrdering(FailureOrder)) | ||||
3219 | return true; | ||||
3220 | |||||
3221 | LLT MemoryType; | ||||
3222 | if (Token.isNot(MIToken::IntegerLiteral) && | ||||
3223 | Token.isNot(MIToken::kw_unknown_size) && | ||||
3224 | Token.isNot(MIToken::lparen)) | ||||
3225 | return error("expected memory LLT, the size integer literal or 'unknown-size' after " | ||||
3226 | "memory operation"); | ||||
3227 | |||||
3228 | uint64_t Size = MemoryLocation::UnknownSize; | ||||
3229 | if (Token.is(MIToken::IntegerLiteral)) { | ||||
3230 | if (getUint64(Size)) | ||||
3231 | return true; | ||||
3232 | |||||
3233 | // Convert from bytes to bits for storage. | ||||
3234 | MemoryType = LLT::scalar(8 * Size); | ||||
3235 | lex(); | ||||
3236 | } else if (Token.is(MIToken::kw_unknown_size)) { | ||||
3237 | Size = MemoryLocation::UnknownSize; | ||||
3238 | lex(); | ||||
3239 | } else { | ||||
3240 | if (expectAndConsume(MIToken::lparen)) | ||||
3241 | return true; | ||||
3242 | if (parseLowLevelType(Token.location(), MemoryType)) | ||||
3243 | return true; | ||||
3244 | if (expectAndConsume(MIToken::rparen)) | ||||
3245 | return true; | ||||
3246 | |||||
3247 | Size = MemoryType.getSizeInBytes(); | ||||
3248 | } | ||||
3249 | |||||
3250 | MachinePointerInfo Ptr = MachinePointerInfo(); | ||||
3251 | if (Token.is(MIToken::Identifier)) { | ||||
3252 | const char *Word = | ||||
3253 | ((Flags & MachineMemOperand::MOLoad) && | ||||
3254 | (Flags & MachineMemOperand::MOStore)) | ||||
3255 | ? "on" | ||||
3256 | : Flags & MachineMemOperand::MOLoad ? "from" : "into"; | ||||
3257 | if (Token.stringValue() != Word) | ||||
3258 | return error(Twine("expected '") + Word + "'"); | ||||
3259 | lex(); | ||||
3260 | |||||
3261 | if (parseMachinePointerInfo(Ptr)) | ||||
3262 | return true; | ||||
3263 | } | ||||
3264 | unsigned BaseAlignment = | ||||
3265 | (Size != MemoryLocation::UnknownSize ? PowerOf2Ceil(Size) : 1); | ||||
3266 | AAMDNodes AAInfo; | ||||
3267 | MDNode *Range = nullptr; | ||||
3268 | while (consumeIfPresent(MIToken::comma)) { | ||||
3269 | switch (Token.kind()) { | ||||
3270 | case MIToken::kw_align: | ||||
3271 | // align is printed if it is different than size. | ||||
3272 | if (parseAlignment(BaseAlignment)) | ||||
3273 | return true; | ||||
3274 | break; | ||||
3275 | case MIToken::kw_basealign: | ||||
3276 | // basealign is printed if it is different than align. | ||||
3277 | if (parseAlignment(BaseAlignment)) | ||||
3278 | return true; | ||||
3279 | break; | ||||
3280 | case MIToken::kw_addrspace: | ||||
3281 | if (parseAddrspace(Ptr.AddrSpace)) | ||||
3282 | return true; | ||||
3283 | break; | ||||
3284 | case MIToken::md_tbaa: | ||||
3285 | lex(); | ||||
3286 | if (parseMDNode(AAInfo.TBAA)) | ||||
3287 | return true; | ||||
3288 | break; | ||||
3289 | case MIToken::md_alias_scope: | ||||
3290 | lex(); | ||||
3291 | if (parseMDNode(AAInfo.Scope)) | ||||
3292 | return true; | ||||
3293 | break; | ||||
3294 | case MIToken::md_noalias: | ||||
3295 | lex(); | ||||
3296 | if (parseMDNode(AAInfo.NoAlias)) | ||||
3297 | return true; | ||||
3298 | break; | ||||
3299 | case MIToken::md_range: | ||||
3300 | lex(); | ||||
3301 | if (parseMDNode(Range)) | ||||
3302 | return true; | ||||
3303 | break; | ||||
3304 | // TODO: Report an error on duplicate metadata nodes. | ||||
3305 | default: | ||||
3306 | return error("expected 'align' or '!tbaa' or '!alias.scope' or " | ||||
3307 | "'!noalias' or '!range'"); | ||||
3308 | } | ||||
3309 | } | ||||
3310 | if (expectAndConsume(MIToken::rparen)) | ||||
3311 | return true; | ||||
3312 | Dest = MF.getMachineMemOperand(Ptr, Flags, MemoryType, Align(BaseAlignment), | ||||
3313 | AAInfo, Range, SSID, Order, FailureOrder); | ||||
3314 | return false; | ||||
3315 | } | ||||
3316 | |||||
3317 | bool MIParser::parsePreOrPostInstrSymbol(MCSymbol *&Symbol) { | ||||
3318 | assert((Token.is(MIToken::kw_pre_instr_symbol) ||(static_cast <bool> ((Token.is(MIToken::kw_pre_instr_symbol ) || Token.is(MIToken::kw_post_instr_symbol)) && "Invalid token for a pre- post-instruction symbol!" ) ? void (0) : __assert_fail ("(Token.is(MIToken::kw_pre_instr_symbol) || Token.is(MIToken::kw_post_instr_symbol)) && \"Invalid token for a pre- post-instruction symbol!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 3320, __extension__ __PRETTY_FUNCTION__)) | ||||
3319 | Token.is(MIToken::kw_post_instr_symbol)) &&(static_cast <bool> ((Token.is(MIToken::kw_pre_instr_symbol ) || Token.is(MIToken::kw_post_instr_symbol)) && "Invalid token for a pre- post-instruction symbol!" ) ? void (0) : __assert_fail ("(Token.is(MIToken::kw_pre_instr_symbol) || Token.is(MIToken::kw_post_instr_symbol)) && \"Invalid token for a pre- post-instruction symbol!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 3320, __extension__ __PRETTY_FUNCTION__)) | ||||
3320 | "Invalid token for a pre- post-instruction symbol!")(static_cast <bool> ((Token.is(MIToken::kw_pre_instr_symbol ) || Token.is(MIToken::kw_post_instr_symbol)) && "Invalid token for a pre- post-instruction symbol!" ) ? void (0) : __assert_fail ("(Token.is(MIToken::kw_pre_instr_symbol) || Token.is(MIToken::kw_post_instr_symbol)) && \"Invalid token for a pre- post-instruction symbol!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 3320, __extension__ __PRETTY_FUNCTION__)); | ||||
3321 | lex(); | ||||
3322 | if (Token.isNot(MIToken::MCSymbol)) | ||||
3323 | return error("expected a symbol after 'pre-instr-symbol'"); | ||||
3324 | Symbol = getOrCreateMCSymbol(Token.stringValue()); | ||||
3325 | lex(); | ||||
3326 | if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) || | ||||
3327 | Token.is(MIToken::lbrace)) | ||||
3328 | return false; | ||||
3329 | if (Token.isNot(MIToken::comma)) | ||||
3330 | return error("expected ',' before the next machine operand"); | ||||
3331 | lex(); | ||||
3332 | return false; | ||||
3333 | } | ||||
3334 | |||||
3335 | bool MIParser::parseHeapAllocMarker(MDNode *&Node) { | ||||
3336 | assert(Token.is(MIToken::kw_heap_alloc_marker) &&(static_cast <bool> (Token.is(MIToken::kw_heap_alloc_marker ) && "Invalid token for a heap alloc marker!") ? void (0) : __assert_fail ("Token.is(MIToken::kw_heap_alloc_marker) && \"Invalid token for a heap alloc marker!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 3337, __extension__ __PRETTY_FUNCTION__)) | ||||
3337 | "Invalid token for a heap alloc marker!")(static_cast <bool> (Token.is(MIToken::kw_heap_alloc_marker ) && "Invalid token for a heap alloc marker!") ? void (0) : __assert_fail ("Token.is(MIToken::kw_heap_alloc_marker) && \"Invalid token for a heap alloc marker!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/MIRParser/MIParser.cpp" , 3337, __extension__ __PRETTY_FUNCTION__)); | ||||
3338 | lex(); | ||||
3339 | parseMDNode(Node); | ||||
3340 | if (!Node) | ||||
3341 | return error("expected a MDNode after 'heap-alloc-marker'"); | ||||
3342 | if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) || | ||||
3343 | Token.is(MIToken::lbrace)) | ||||
3344 | return false; | ||||
3345 | if (Token.isNot(MIToken::comma)) | ||||
3346 | return error("expected ',' before the next machine operand"); | ||||
3347 | lex(); | ||||
3348 | return false; | ||||
3349 | } | ||||
3350 | |||||
3351 | static void initSlots2BasicBlocks( | ||||
3352 | const Function &F, | ||||
3353 | DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) { | ||||
3354 | ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false); | ||||
3355 | MST.incorporateFunction(F); | ||||
3356 | for (auto &BB : F) { | ||||
3357 | if (BB.hasName()) | ||||
3358 | continue; | ||||
3359 | int Slot = MST.getLocalSlot(&BB); | ||||
3360 | if (Slot == -1) | ||||
3361 | continue; | ||||
3362 | Slots2BasicBlocks.insert(std::make_pair(unsigned(Slot), &BB)); | ||||
3363 | } | ||||
3364 | } | ||||
3365 | |||||
3366 | static const BasicBlock *getIRBlockFromSlot( | ||||
3367 | unsigned Slot, | ||||
3368 | const DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) { | ||||
3369 | return Slots2BasicBlocks.lookup(Slot); | ||||
3370 | } | ||||
3371 | |||||
3372 | const BasicBlock *MIParser::getIRBlock(unsigned Slot) { | ||||
3373 | if (Slots2BasicBlocks.empty()) | ||||
3374 | initSlots2BasicBlocks(MF.getFunction(), Slots2BasicBlocks); | ||||
3375 | return getIRBlockFromSlot(Slot, Slots2BasicBlocks); | ||||
3376 | } | ||||
3377 | |||||
3378 | const BasicBlock *MIParser::getIRBlock(unsigned Slot, const Function &F) { | ||||
3379 | if (&F == &MF.getFunction()) | ||||
3380 | return getIRBlock(Slot); | ||||
3381 | DenseMap<unsigned, const BasicBlock *> CustomSlots2BasicBlocks; | ||||
3382 | initSlots2BasicBlocks(F, CustomSlots2BasicBlocks); | ||||
3383 | return getIRBlockFromSlot(Slot, CustomSlots2BasicBlocks); | ||||
3384 | } | ||||
3385 | |||||
3386 | MCSymbol *MIParser::getOrCreateMCSymbol(StringRef Name) { | ||||
3387 | // FIXME: Currently we can't recognize temporary or local symbols and call all | ||||
3388 | // of the appropriate forms to create them. However, this handles basic cases | ||||
3389 | // well as most of the special aspects are recognized by a prefix on their | ||||
3390 | // name, and the input names should already be unique. For test cases, keeping | ||||
3391 | // the symbol name out of the symbol table isn't terribly important. | ||||
3392 | return MF.getContext().getOrCreateSymbol(Name); | ||||
3393 | } | ||||
3394 | |||||
3395 | bool MIParser::parseStringConstant(std::string &Result) { | ||||
3396 | if (Token.isNot(MIToken::StringConstant)) | ||||
3397 | return error("expected string constant"); | ||||
3398 | Result = std::string(Token.stringValue()); | ||||
3399 | lex(); | ||||
3400 | return false; | ||||
3401 | } | ||||
3402 | |||||
3403 | bool llvm::parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS, | ||||
3404 | StringRef Src, | ||||
3405 | SMDiagnostic &Error) { | ||||
3406 | return MIParser(PFS, Error, Src).parseBasicBlockDefinitions(PFS.MBBSlots); | ||||
3407 | } | ||||
3408 | |||||
3409 | bool llvm::parseMachineInstructions(PerFunctionMIParsingState &PFS, | ||||
3410 | StringRef Src, SMDiagnostic &Error) { | ||||
3411 | return MIParser(PFS, Error, Src).parseBasicBlocks(); | ||||
3412 | } | ||||
3413 | |||||
3414 | bool llvm::parseMBBReference(PerFunctionMIParsingState &PFS, | ||||
3415 | MachineBasicBlock *&MBB, StringRef Src, | ||||
3416 | SMDiagnostic &Error) { | ||||
3417 | return MIParser(PFS, Error, Src).parseStandaloneMBB(MBB); | ||||
3418 | } | ||||
3419 | |||||
3420 | bool llvm::parseRegisterReference(PerFunctionMIParsingState &PFS, | ||||
3421 | Register &Reg, StringRef Src, | ||||
3422 | SMDiagnostic &Error) { | ||||
3423 | return MIParser(PFS, Error, Src).parseStandaloneRegister(Reg); | ||||
3424 | } | ||||
3425 | |||||
3426 | bool llvm::parseNamedRegisterReference(PerFunctionMIParsingState &PFS, | ||||
3427 | Register &Reg, StringRef Src, | ||||
3428 | SMDiagnostic &Error) { | ||||
3429 | return MIParser(PFS, Error, Src).parseStandaloneNamedRegister(Reg); | ||||
3430 | } | ||||
3431 | |||||
3432 | bool llvm::parseVirtualRegisterReference(PerFunctionMIParsingState &PFS, | ||||
3433 | VRegInfo *&Info, StringRef Src, | ||||
3434 | SMDiagnostic &Error) { | ||||
3435 | return MIParser(PFS, Error, Src).parseStandaloneVirtualRegister(Info); | ||||
3436 | } | ||||
3437 | |||||
3438 | bool llvm::parseStackObjectReference(PerFunctionMIParsingState &PFS, | ||||
3439 | int &FI, StringRef Src, | ||||
3440 | SMDiagnostic &Error) { | ||||
3441 | return MIParser(PFS, Error, Src).parseStandaloneStackObject(FI); | ||||
3442 | } | ||||
3443 | |||||
3444 | bool llvm::parseMDNode(PerFunctionMIParsingState &PFS, | ||||
3445 | MDNode *&Node, StringRef Src, SMDiagnostic &Error) { | ||||
3446 | return MIParser(PFS, Error, Src).parseStandaloneMDNode(Node); | ||||
3447 | } | ||||
3448 | |||||
3449 | bool llvm::parseMachineMetadata(PerFunctionMIParsingState &PFS, StringRef Src, | ||||
3450 | SMRange SrcRange, SMDiagnostic &Error) { | ||||
3451 | return MIParser(PFS, Error, Src, SrcRange).parseMachineMetadata(); | ||||
3452 | } | ||||
3453 | |||||
3454 | bool MIRFormatter::parseIRValue(StringRef Src, MachineFunction &MF, | ||||
3455 | PerFunctionMIParsingState &PFS, const Value *&V, | ||||
3456 | ErrorCallbackType ErrorCallback) { | ||||
3457 | MIToken Token; | ||||
3458 | Src = lexMIToken(Src, Token, [&](StringRef::iterator Loc, const Twine &Msg) { | ||||
3459 | ErrorCallback(Loc, Msg); | ||||
3460 | }); | ||||
3461 | V = nullptr; | ||||
3462 | |||||
3463 | return ::parseIRValue(Token, PFS, V, ErrorCallback); | ||||
| |||||
3464 | } |
1 | //===- MILexer.h - Lexer for machine instructions ---------------*- 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 lexes the machine instruction source | ||||||||
10 | // string. | ||||||||
11 | // | ||||||||
12 | //===----------------------------------------------------------------------===// | ||||||||
13 | |||||||||
14 | #ifndef LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H | ||||||||
15 | #define LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H | ||||||||
16 | |||||||||
17 | #include "llvm/ADT/APSInt.h" | ||||||||
18 | #include "llvm/ADT/StringRef.h" | ||||||||
19 | #include <string> | ||||||||
20 | |||||||||
21 | namespace llvm { | ||||||||
22 | |||||||||
23 | class Twine; | ||||||||
24 | |||||||||
25 | /// A token produced by the machine instruction lexer. | ||||||||
26 | struct MIToken { | ||||||||
27 | enum TokenKind { | ||||||||
28 | // Markers | ||||||||
29 | Eof, | ||||||||
30 | Error, | ||||||||
31 | Newline, | ||||||||
32 | |||||||||
33 | // Tokens with no info. | ||||||||
34 | comma, | ||||||||
35 | equal, | ||||||||
36 | underscore, | ||||||||
37 | colon, | ||||||||
38 | coloncolon, | ||||||||
39 | dot, | ||||||||
40 | exclaim, | ||||||||
41 | lparen, | ||||||||
42 | rparen, | ||||||||
43 | lbrace, | ||||||||
44 | rbrace, | ||||||||
45 | plus, | ||||||||
46 | minus, | ||||||||
47 | less, | ||||||||
48 | greater, | ||||||||
49 | |||||||||
50 | // Keywords | ||||||||
51 | kw_implicit, | ||||||||
52 | kw_implicit_define, | ||||||||
53 | kw_def, | ||||||||
54 | kw_dead, | ||||||||
55 | kw_dereferenceable, | ||||||||
56 | kw_killed, | ||||||||
57 | kw_undef, | ||||||||
58 | kw_internal, | ||||||||
59 | kw_early_clobber, | ||||||||
60 | kw_debug_use, | ||||||||
61 | kw_renamable, | ||||||||
62 | kw_tied_def, | ||||||||
63 | kw_frame_setup, | ||||||||
64 | kw_frame_destroy, | ||||||||
65 | kw_nnan, | ||||||||
66 | kw_ninf, | ||||||||
67 | kw_nsz, | ||||||||
68 | kw_arcp, | ||||||||
69 | kw_contract, | ||||||||
70 | kw_afn, | ||||||||
71 | kw_reassoc, | ||||||||
72 | kw_nuw, | ||||||||
73 | kw_nsw, | ||||||||
74 | kw_exact, | ||||||||
75 | kw_nofpexcept, | ||||||||
76 | kw_debug_location, | ||||||||
77 | kw_debug_instr_number, | ||||||||
78 | kw_cfi_same_value, | ||||||||
79 | kw_cfi_offset, | ||||||||
80 | kw_cfi_rel_offset, | ||||||||
81 | kw_cfi_def_cfa_register, | ||||||||
82 | kw_cfi_def_cfa_offset, | ||||||||
83 | kw_cfi_adjust_cfa_offset, | ||||||||
84 | kw_cfi_escape, | ||||||||
85 | kw_cfi_def_cfa, | ||||||||
86 | kw_cfi_llvm_def_aspace_cfa, | ||||||||
87 | kw_cfi_register, | ||||||||
88 | kw_cfi_remember_state, | ||||||||
89 | kw_cfi_restore, | ||||||||
90 | kw_cfi_restore_state, | ||||||||
91 | kw_cfi_undefined, | ||||||||
92 | kw_cfi_window_save, | ||||||||
93 | kw_cfi_aarch64_negate_ra_sign_state, | ||||||||
94 | kw_blockaddress, | ||||||||
95 | kw_intrinsic, | ||||||||
96 | kw_target_index, | ||||||||
97 | kw_half, | ||||||||
98 | kw_float, | ||||||||
99 | kw_double, | ||||||||
100 | kw_x86_fp80, | ||||||||
101 | kw_fp128, | ||||||||
102 | kw_ppc_fp128, | ||||||||
103 | kw_target_flags, | ||||||||
104 | kw_volatile, | ||||||||
105 | kw_non_temporal, | ||||||||
106 | kw_invariant, | ||||||||
107 | kw_align, | ||||||||
108 | kw_basealign, | ||||||||
109 | kw_addrspace, | ||||||||
110 | kw_stack, | ||||||||
111 | kw_got, | ||||||||
112 | kw_jump_table, | ||||||||
113 | kw_constant_pool, | ||||||||
114 | kw_call_entry, | ||||||||
115 | kw_custom, | ||||||||
116 | kw_liveout, | ||||||||
117 | kw_address_taken, | ||||||||
118 | kw_landing_pad, | ||||||||
119 | kw_ehfunclet_entry, | ||||||||
120 | kw_liveins, | ||||||||
121 | kw_successors, | ||||||||
122 | kw_floatpred, | ||||||||
123 | kw_intpred, | ||||||||
124 | kw_shufflemask, | ||||||||
125 | kw_pre_instr_symbol, | ||||||||
126 | kw_post_instr_symbol, | ||||||||
127 | kw_heap_alloc_marker, | ||||||||
128 | kw_bbsections, | ||||||||
129 | kw_unknown_size, | ||||||||
130 | kw_unknown_address, | ||||||||
131 | |||||||||
132 | // Metadata types. | ||||||||
133 | kw_distinct, | ||||||||
134 | |||||||||
135 | // Named metadata keywords | ||||||||
136 | md_tbaa, | ||||||||
137 | md_alias_scope, | ||||||||
138 | md_noalias, | ||||||||
139 | md_range, | ||||||||
140 | md_diexpr, | ||||||||
141 | md_dilocation, | ||||||||
142 | |||||||||
143 | // Identifier tokens | ||||||||
144 | Identifier, | ||||||||
145 | NamedRegister, | ||||||||
146 | NamedVirtualRegister, | ||||||||
147 | MachineBasicBlockLabel, | ||||||||
148 | MachineBasicBlock, | ||||||||
149 | StackObject, | ||||||||
150 | FixedStackObject, | ||||||||
151 | NamedGlobalValue, | ||||||||
152 | GlobalValue, | ||||||||
153 | ExternalSymbol, | ||||||||
154 | MCSymbol, | ||||||||
155 | |||||||||
156 | // Other tokens | ||||||||
157 | IntegerLiteral, | ||||||||
158 | FloatingPointLiteral, | ||||||||
159 | HexLiteral, | ||||||||
160 | VectorLiteral, | ||||||||
161 | VirtualRegister, | ||||||||
162 | ConstantPoolItem, | ||||||||
163 | JumpTableIndex, | ||||||||
164 | NamedIRBlock, | ||||||||
165 | IRBlock, | ||||||||
166 | NamedIRValue, | ||||||||
167 | IRValue, | ||||||||
168 | QuotedIRValue, // `<constant value>` | ||||||||
169 | SubRegisterIndex, | ||||||||
170 | StringConstant | ||||||||
171 | }; | ||||||||
172 | |||||||||
173 | private: | ||||||||
174 | TokenKind Kind = Error; | ||||||||
175 | StringRef Range; | ||||||||
176 | StringRef StringValue; | ||||||||
177 | std::string StringValueStorage; | ||||||||
178 | APSInt IntVal; | ||||||||
179 | |||||||||
180 | public: | ||||||||
181 | MIToken() = default; | ||||||||
182 | |||||||||
183 | MIToken &reset(TokenKind Kind, StringRef Range); | ||||||||
184 | |||||||||
185 | MIToken &setStringValue(StringRef StrVal); | ||||||||
186 | MIToken &setOwnedStringValue(std::string StrVal); | ||||||||
187 | MIToken &setIntegerValue(APSInt IntVal); | ||||||||
188 | |||||||||
189 | TokenKind kind() const { return Kind; } | ||||||||
190 | |||||||||
191 | bool isError() const { return Kind == Error; } | ||||||||
192 | |||||||||
193 | bool isNewlineOrEOF() const { return Kind == Newline || Kind == Eof; } | ||||||||
194 | |||||||||
195 | bool isErrorOrEOF() const { return Kind == Error || Kind == Eof; } | ||||||||
196 | |||||||||
197 | bool isRegister() const { | ||||||||
198 | return Kind == NamedRegister || Kind == underscore || | ||||||||
199 | Kind == NamedVirtualRegister || Kind == VirtualRegister; | ||||||||
200 | } | ||||||||
201 | |||||||||
202 | bool isRegisterFlag() const { | ||||||||
203 | return Kind == kw_implicit || Kind == kw_implicit_define || | ||||||||
204 | Kind == kw_def || Kind == kw_dead || Kind == kw_killed || | ||||||||
205 | Kind == kw_undef || Kind == kw_internal || | ||||||||
206 | Kind == kw_early_clobber || Kind == kw_debug_use || | ||||||||
207 | Kind == kw_renamable; | ||||||||
208 | } | ||||||||
209 | |||||||||
210 | bool isMemoryOperandFlag() const { | ||||||||
211 | return Kind == kw_volatile || Kind == kw_non_temporal || | ||||||||
212 | Kind == kw_dereferenceable || Kind == kw_invariant || | ||||||||
213 | Kind == StringConstant; | ||||||||
214 | } | ||||||||
215 | |||||||||
216 | bool is(TokenKind K) const { return Kind == K; } | ||||||||
217 | |||||||||
218 | bool isNot(TokenKind K) const { return Kind != K; } | ||||||||
219 | |||||||||
220 | StringRef::iterator location() const { return Range.begin(); } | ||||||||
221 | |||||||||
222 | StringRef range() const { return Range; } | ||||||||
223 | |||||||||
224 | /// Return the token's string value. | ||||||||
225 | StringRef stringValue() const { return StringValue; } | ||||||||
226 | |||||||||
227 | const APSInt &integerValue() const { return IntVal; } | ||||||||
228 | |||||||||
229 | bool hasIntegerValue() const { | ||||||||
230 | return Kind
| ||||||||
231 | Kind
| ||||||||
232 | Kind
| ||||||||
233 | Kind == VirtualRegister || Kind == ConstantPoolItem || | ||||||||
234 | Kind == JumpTableIndex || Kind == IRBlock || Kind == IRValue; | ||||||||
235 | } | ||||||||
236 | }; | ||||||||
237 | |||||||||
238 | /// Consume a single machine instruction token in the given source and return | ||||||||
239 | /// the remaining source string. | ||||||||
240 | StringRef lexMIToken( | ||||||||
241 | StringRef Source, MIToken &Token, | ||||||||
242 | function_ref<void(StringRef::iterator, const Twine &)> ErrorCallback); | ||||||||
243 | |||||||||
244 | } // end namespace llvm | ||||||||
245 | |||||||||
246 | #endif // LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H |