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