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