1//===- MIRParser.cpp - MIR serialization format 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 class that parses the optional LLVM IR and machine
10// functions that are stored in MIR files.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/CodeGen/MIRParser/MIRParser.h"
15#include "llvm/ADT/DenseMap.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/AsmParser/Parser.h"
18#include "llvm/AsmParser/SlotMapping.h"
19#include "llvm/CodeGen/MIRParser/MIParser.h"
20#include "llvm/CodeGen/MIRYamlMapping.h"
21#include "llvm/CodeGen/MachineConstantPool.h"
22#include "llvm/CodeGen/MachineFrameInfo.h"
23#include "llvm/CodeGen/MachineFunction.h"
24#include "llvm/CodeGen/MachineFunctionAnalysis.h"
25#include "llvm/CodeGen/MachineModuleInfo.h"
26#include "llvm/CodeGen/MachineRegisterInfo.h"
27#include "llvm/CodeGen/TargetFrameLowering.h"
28#include "llvm/IR/BasicBlock.h"
29#include "llvm/IR/DebugInfoMetadata.h"
30#include "llvm/IR/DiagnosticInfo.h"
31#include "llvm/IR/Instructions.h"
32#include "llvm/IR/LLVMContext.h"
33#include "llvm/IR/Module.h"
34#include "llvm/IR/ValueSymbolTable.h"
35#include "llvm/Support/LineIterator.h"
36#include "llvm/Support/MemoryBuffer.h"
37#include "llvm/Support/SMLoc.h"
38#include "llvm/Support/SourceMgr.h"
39#include "llvm/Support/YAMLTraits.h"
40#include "llvm/Target/TargetMachine.h"
41#include <memory>
42
43using namespace llvm;
44
45namespace llvm {
46class MDNode;
47class RegisterBank;
48
49/// This class implements the parsing of LLVM IR that's embedded inside a MIR
50/// file.
51class MIRParserImpl {
52 SourceMgr SM;
53 LLVMContext &Context;
54 yaml::Input In;
55 StringRef Filename;
56 SlotMapping IRSlots;
57 std::unique_ptr<PerTargetMIParsingState> Target;
58
59 /// True when the MIR file doesn't have LLVM IR. Dummy IR functions are
60 /// created and inserted into the given module when this is true.
61 bool NoLLVMIR = false;
62 /// True when a well formed MIR file does not contain any MIR/machine function
63 /// parts.
64 bool NoMIRDocuments = false;
65
66 std::function<void(Function &)> ProcessIRFunction;
67
68public:
69 MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
70 LLVMContext &Context,
71 std::function<void(Function &)> ProcessIRFunction);
72
73 void reportDiagnostic(const SMDiagnostic &Diag);
74
75 /// Report an error with the given message at unknown location.
76 ///
77 /// Always returns true.
78 bool error(const Twine &Message);
79
80 /// Report an error with the given message at the given location.
81 ///
82 /// Always returns true.
83 bool error(SMLoc Loc, const Twine &Message);
84
85 /// Report a given error with the location translated from the location in an
86 /// embedded string literal to a location in the MIR file.
87 ///
88 /// Always returns true.
89 bool error(const SMDiagnostic &Error, SMRange SourceRange);
90
91 /// Try to parse the optional LLVM module and the machine functions in the MIR
92 /// file.
93 ///
94 /// Return null if an error occurred.
95 std::unique_ptr<Module>
96 parseIRModule(DataLayoutCallbackTy DataLayoutCallback);
97
98 /// Create an empty function with the given name.
99 Function *createDummyFunction(StringRef Name, Module &M);
100
101 bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI,
102 ModuleAnalysisManager *FAM = nullptr);
103
104 /// Parse the machine function in the current YAML document.
105 ///
106 ///
107 /// Return true if an error occurred.
108 bool parseMachineFunction(Module &M, MachineModuleInfo &MMI,
109 ModuleAnalysisManager *FAM);
110
111 /// Initialize the machine function to the state that's described in the MIR
112 /// file.
113 ///
114 /// Return true if error occurred.
115 bool initializeMachineFunction(const yaml::MachineFunction &YamlMF,
116 MachineFunction &MF);
117
118 bool parseRegisterInfo(PerFunctionMIParsingState &PFS,
119 const yaml::MachineFunction &YamlMF);
120
121 bool setupRegisterInfo(const PerFunctionMIParsingState &PFS,
122 const yaml::MachineFunction &YamlMF);
123
124 bool initializeFrameInfo(PerFunctionMIParsingState &PFS,
125 const yaml::MachineFunction &YamlMF);
126
127 bool initializeCallSiteInfo(PerFunctionMIParsingState &PFS,
128 const yaml::MachineFunction &YamlMF);
129
130 bool parseCalleeSavedRegister(PerFunctionMIParsingState &PFS,
131 std::vector<CalleeSavedInfo> &CSIInfo,
132 const yaml::StringValue &RegisterSource,
133 bool IsRestored, int FrameIdx);
134
135 struct VarExprLoc {
136 DILocalVariable *DIVar = nullptr;
137 DIExpression *DIExpr = nullptr;
138 DILocation *DILoc = nullptr;
139 };
140
141 std::optional<VarExprLoc> parseVarExprLoc(PerFunctionMIParsingState &PFS,
142 const yaml::StringValue &VarStr,
143 const yaml::StringValue &ExprStr,
144 const yaml::StringValue &LocStr);
145 template <typename T>
146 bool parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS,
147 const T &Object,
148 int FrameIdx);
149
150 bool initializeConstantPool(PerFunctionMIParsingState &PFS,
151 MachineConstantPool &ConstantPool,
152 const yaml::MachineFunction &YamlMF);
153
154 bool initializeJumpTableInfo(PerFunctionMIParsingState &PFS,
155 const yaml::MachineJumpTable &YamlJTI);
156
157 bool parseMachineMetadataNodes(PerFunctionMIParsingState &PFS,
158 MachineFunction &MF,
159 const yaml::MachineFunction &YMF);
160
161 bool parseCalledGlobals(PerFunctionMIParsingState &PFS, MachineFunction &MF,
162 const yaml::MachineFunction &YMF);
163
164private:
165 bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node,
166 const yaml::StringValue &Source);
167
168 bool parseMBBReference(PerFunctionMIParsingState &PFS,
169 MachineBasicBlock *&MBB,
170 const yaml::StringValue &Source);
171
172 bool parseMachineMetadata(PerFunctionMIParsingState &PFS,
173 const yaml::StringValue &Source);
174
175 /// Return a MIR diagnostic converted from an MI string diagnostic.
176 SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
177 SMRange SourceRange);
178
179 /// Return a MIR diagnostic converted from a diagnostic located in a YAML
180 /// block scalar string.
181 SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error,
182 SMRange SourceRange);
183
184 bool computeFunctionProperties(MachineFunction &MF,
185 const yaml::MachineFunction &YamlMF);
186
187 void setupDebugValueTracking(MachineFunction &MF,
188 PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF);
189
190 bool parseMachineInst(MachineFunction &MF, yaml::MachineInstrLoc MILoc,
191 MachineInstr const *&MI);
192};
193
194} // end namespace llvm
195
196static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
197 reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
198}
199
200MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
201 StringRef Filename, LLVMContext &Context,
202 std::function<void(Function &)> Callback)
203 : Context(Context),
204 In(SM.getMemoryBuffer(i: SM.AddNewSourceBuffer(F: std::move(Contents), IncludeLoc: SMLoc()))
205 ->getBuffer(),
206 nullptr, handleYAMLDiag, this),
207 Filename(Filename), ProcessIRFunction(Callback) {
208 In.setContext(&In);
209}
210
211bool MIRParserImpl::error(const Twine &Message) {
212 Context.diagnose(DI: DiagnosticInfoMIRParser(
213 DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str())));
214 return true;
215}
216
217bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) {
218 Context.diagnose(DI: DiagnosticInfoMIRParser(
219 DS_Error, SM.GetMessage(Loc, Kind: SourceMgr::DK_Error, Msg: Message)));
220 return true;
221}
222
223bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) {
224 assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error");
225 reportDiagnostic(Diag: diagFromMIStringDiag(Error, SourceRange));
226 return true;
227}
228
229void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {
230 DiagnosticSeverity Kind;
231 switch (Diag.getKind()) {
232 case SourceMgr::DK_Error:
233 Kind = DS_Error;
234 break;
235 case SourceMgr::DK_Warning:
236 Kind = DS_Warning;
237 break;
238 case SourceMgr::DK_Note:
239 Kind = DS_Note;
240 break;
241 case SourceMgr::DK_Remark:
242 llvm_unreachable("remark unexpected");
243 break;
244 }
245 Context.diagnose(DI: DiagnosticInfoMIRParser(Kind, Diag));
246}
247
248std::unique_ptr<Module>
249MIRParserImpl::parseIRModule(DataLayoutCallbackTy DataLayoutCallback) {
250 if (!In.setCurrentDocument()) {
251 if (In.error())
252 return nullptr;
253 // Create an empty module when the MIR file is empty.
254 NoMIRDocuments = true;
255 auto M = std::make_unique<Module>(args&: Filename, args&: Context);
256 if (auto LayoutOverride = DataLayoutCallback(M->getTargetTriple().str(),
257 M->getDataLayoutStr()))
258 M->setDataLayout(*LayoutOverride);
259 return M;
260 }
261
262 std::unique_ptr<Module> M;
263 // Parse the block scalar manually so that we can return unique pointer
264 // without having to go trough YAML traits.
265 if (const auto *BSN =
266 dyn_cast_or_null<yaml::BlockScalarNode>(Val: In.getCurrentNode())) {
267 SMDiagnostic Error;
268 M = parseAssembly(F: MemoryBufferRef(BSN->getValue(), Filename), Err&: Error,
269 Context, Slots: &IRSlots, DataLayoutCallback);
270 if (!M) {
271 reportDiagnostic(Diag: diagFromBlockStringDiag(Error, SourceRange: BSN->getSourceRange()));
272 return nullptr;
273 }
274 In.nextDocument();
275 if (!In.setCurrentDocument())
276 NoMIRDocuments = true;
277 } else {
278 // Create an new, empty module.
279 M = std::make_unique<Module>(args&: Filename, args&: Context);
280 if (auto LayoutOverride = DataLayoutCallback(M->getTargetTriple().str(),
281 M->getDataLayoutStr()))
282 M->setDataLayout(*LayoutOverride);
283 NoLLVMIR = true;
284 }
285 return M;
286}
287
288bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI,
289 ModuleAnalysisManager *MAM) {
290 if (NoMIRDocuments)
291 return false;
292
293 // Parse the machine functions.
294 do {
295 if (parseMachineFunction(M, MMI, FAM: MAM))
296 return true;
297 In.nextDocument();
298 } while (In.setCurrentDocument());
299
300 return false;
301}
302
303Function *MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {
304 auto &Context = M.getContext();
305 Function *F =
306 Function::Create(Ty: FunctionType::get(Result: Type::getVoidTy(C&: Context), isVarArg: false),
307 Linkage: Function::ExternalLinkage, N: Name, M);
308 BasicBlock *BB = BasicBlock::Create(Context, Name: "entry", Parent: F);
309 new UnreachableInst(Context, BB);
310
311 if (ProcessIRFunction)
312 ProcessIRFunction(*F);
313
314 return F;
315}
316
317bool MIRParserImpl::parseMachineFunction(Module &M, MachineModuleInfo &MMI,
318 ModuleAnalysisManager *MAM) {
319 // Parse the yaml.
320 yaml::MachineFunction YamlMF;
321 yaml::EmptyContext Ctx;
322
323 const TargetMachine &TM = MMI.getTarget();
324 YamlMF.MachineFuncInfo = std::unique_ptr<yaml::MachineFunctionInfo>(
325 TM.createDefaultFuncInfoYAML());
326
327 yaml::yamlize(io&: In, Val&: YamlMF, false, Ctx);
328 if (In.error())
329 return true;
330
331 // Search for the corresponding IR function.
332 StringRef FunctionName = YamlMF.Name;
333 Function *F = M.getFunction(Name: FunctionName);
334 if (!F) {
335 if (NoLLVMIR) {
336 F = createDummyFunction(Name: FunctionName, M);
337 } else {
338 return error(Message: Twine("function '") + FunctionName +
339 "' isn't defined in the provided LLVM IR");
340 }
341 }
342
343 if (!MAM) {
344 if (MMI.getMachineFunction(F: *F) != nullptr)
345 return error(Message: Twine("redefinition of machine function '") + FunctionName +
346 "'");
347
348 // Create the MachineFunction.
349 MachineFunction &MF = MMI.getOrCreateMachineFunction(F&: *F);
350 if (initializeMachineFunction(YamlMF, MF))
351 return true;
352 } else {
353 auto &FAM =
354 MAM->getResult<FunctionAnalysisManagerModuleProxy>(IR&: M).getManager();
355 if (FAM.getCachedResult<MachineFunctionAnalysis>(IR&: *F))
356 return error(Message: Twine("redefinition of machine function '") + FunctionName +
357 "'");
358
359 // Create the MachineFunction.
360 MachineFunction &MF = FAM.getResult<MachineFunctionAnalysis>(IR&: *F).getMF();
361 if (initializeMachineFunction(YamlMF, MF))
362 return true;
363 }
364
365 return false;
366}
367
368static bool isSSA(const MachineFunction &MF) {
369 const MachineRegisterInfo &MRI = MF.getRegInfo();
370 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
371 Register Reg = Register::index2VirtReg(Index: I);
372 if (!MRI.hasOneDef(RegNo: Reg) && !MRI.def_empty(RegNo: Reg))
373 return false;
374
375 // Subregister defs are invalid in SSA.
376 const MachineOperand *RegDef = MRI.getOneDef(Reg);
377 if (RegDef && RegDef->getSubReg() != 0)
378 return false;
379 }
380 return true;
381}
382
383bool MIRParserImpl::computeFunctionProperties(
384 MachineFunction &MF, const yaml::MachineFunction &YamlMF) {
385 MachineFunctionProperties &Properties = MF.getProperties();
386
387 bool HasPHI = false;
388 bool HasInlineAsm = false;
389 bool HasFakeUses = false;
390 bool AllTiedOpsRewritten = true, HasTiedOps = false;
391 for (const MachineBasicBlock &MBB : MF) {
392 for (const MachineInstr &MI : MBB) {
393 if (MI.isPHI())
394 HasPHI = true;
395 if (MI.isInlineAsm())
396 HasInlineAsm = true;
397 if (MI.isFakeUse())
398 HasFakeUses = true;
399 for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
400 const MachineOperand &MO = MI.getOperand(i: I);
401 if (!MO.isReg() || !MO.getReg())
402 continue;
403 unsigned DefIdx;
404 if (MO.isUse() && MI.isRegTiedToDefOperand(UseOpIdx: I, DefOpIdx: &DefIdx)) {
405 HasTiedOps = true;
406 if (MO.getReg() != MI.getOperand(i: DefIdx).getReg())
407 AllTiedOpsRewritten = false;
408 }
409 }
410 }
411 }
412
413 // Helper function to sanity-check and set properties that are computed, but
414 // may be explicitly set from the input MIR
415 auto ComputedPropertyHelper =
416 [&Properties](std::optional<bool> ExplicitProp, bool ComputedProp,
417 MachineFunctionProperties::Property P) -> bool {
418 // Prefer explicitly given values over the computed properties
419 if (ExplicitProp.value_or(u&: ComputedProp))
420 Properties.set(P);
421 else
422 Properties.reset(P);
423
424 // Check for conflict between the explicit values and the computed ones
425 return ExplicitProp && *ExplicitProp && !ComputedProp;
426 };
427
428 if (ComputedPropertyHelper(YamlMF.NoPHIs, !HasPHI,
429 MachineFunctionProperties::Property::NoPHIs)) {
430 return error(Message: MF.getName() +
431 " has explicit property NoPhi, but contains at least one PHI");
432 }
433
434 MF.setHasInlineAsm(HasInlineAsm);
435
436 if (HasTiedOps && AllTiedOpsRewritten)
437 Properties.setTiedOpsRewritten();
438
439 if (ComputedPropertyHelper(YamlMF.IsSSA, isSSA(MF),
440 MachineFunctionProperties::Property::IsSSA)) {
441 return error(Message: MF.getName() +
442 " has explicit property IsSSA, but is not valid SSA");
443 }
444
445 const MachineRegisterInfo &MRI = MF.getRegInfo();
446 if (ComputedPropertyHelper(YamlMF.NoVRegs, MRI.getNumVirtRegs() == 0,
447 MachineFunctionProperties::Property::NoVRegs)) {
448 return error(
449 Message: MF.getName() +
450 " has explicit property NoVRegs, but contains virtual registers");
451 }
452
453 // For hasFakeUses we follow similar logic to the ComputedPropertyHelper,
454 // except for caring about the inverse case only, i.e. when the property is
455 // explicitly set to false and Fake Uses are present; having HasFakeUses=true
456 // on a function without fake uses is harmless.
457 if (YamlMF.HasFakeUses && !*YamlMF.HasFakeUses && HasFakeUses)
458 return error(
459 Message: MF.getName() +
460 " has explicit property hasFakeUses=false, but contains fake uses");
461 MF.setHasFakeUses(YamlMF.HasFakeUses.value_or(u&: HasFakeUses));
462
463 return false;
464}
465
466bool MIRParserImpl::parseMachineInst(MachineFunction &MF,
467 yaml::MachineInstrLoc MILoc,
468 MachineInstr const *&MI) {
469 if (MILoc.BlockNum >= MF.size()) {
470 return error(Message: Twine(MF.getName()) +
471 Twine(" instruction block out of range.") +
472 " Unable to reference bb:" + Twine(MILoc.BlockNum));
473 }
474 auto BB = std::next(x: MF.begin(), n: MILoc.BlockNum);
475 if (MILoc.Offset >= BB->size())
476 return error(
477 Message: Twine(MF.getName()) + Twine(" instruction offset out of range.") +
478 " Unable to reference instruction at bb: " + Twine(MILoc.BlockNum) +
479 " at offset:" + Twine(MILoc.Offset));
480 MI = &*std::next(x: BB->instr_begin(), n: MILoc.Offset);
481 return false;
482}
483
484bool MIRParserImpl::initializeCallSiteInfo(
485 PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF) {
486 MachineFunction &MF = PFS.MF;
487 SMDiagnostic Error;
488 const TargetMachine &TM = MF.getTarget();
489 for (auto &YamlCSInfo : YamlMF.CallSitesInfo) {
490 yaml::MachineInstrLoc MILoc = YamlCSInfo.CallLocation;
491 const MachineInstr *CallI;
492 if (parseMachineInst(MF, MILoc, MI&: CallI))
493 return true;
494 if (!CallI->isCall(Type: MachineInstr::IgnoreBundle))
495 return error(Message: Twine(MF.getName()) +
496 Twine(" call site info should reference call "
497 "instruction. Instruction at bb:") +
498 Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset) +
499 " is not a call instruction");
500 MachineFunction::CallSiteInfo CSInfo;
501 for (auto ArgRegPair : YamlCSInfo.ArgForwardingRegs) {
502 Register Reg;
503 if (parseNamedRegisterReference(PFS, Reg, Src: ArgRegPair.Reg.Value, Error))
504 return error(Error, SourceRange: ArgRegPair.Reg.SourceRange);
505 CSInfo.ArgRegPairs.emplace_back(Args&: Reg, Args&: ArgRegPair.ArgNo);
506 }
507
508 if (TM.Options.EmitCallSiteInfo)
509 MF.addCallSiteInfo(CallI: &*CallI, CallInfo: std::move(CSInfo));
510 }
511
512 if (YamlMF.CallSitesInfo.size() && !TM.Options.EmitCallSiteInfo)
513 return error(Message: Twine("Call site info provided but not used"));
514 return false;
515}
516
517void MIRParserImpl::setupDebugValueTracking(
518 MachineFunction &MF, PerFunctionMIParsingState &PFS,
519 const yaml::MachineFunction &YamlMF) {
520 // Compute the value of the "next instruction number" field.
521 unsigned MaxInstrNum = 0;
522 for (auto &MBB : MF)
523 for (auto &MI : MBB)
524 MaxInstrNum = std::max(a: (unsigned)MI.peekDebugInstrNum(), b: MaxInstrNum);
525 MF.setDebugInstrNumberingCount(MaxInstrNum);
526
527 // Load any substitutions.
528 for (const auto &Sub : YamlMF.DebugValueSubstitutions) {
529 MF.makeDebugValueSubstitution({Sub.SrcInst, Sub.SrcOp},
530 {Sub.DstInst, Sub.DstOp}, SubReg: Sub.Subreg);
531 }
532
533 // Flag for whether we're supposed to be using DBG_INSTR_REF.
534 MF.setUseDebugInstrRef(YamlMF.UseDebugInstrRef);
535}
536
537bool
538MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
539 MachineFunction &MF) {
540 // TODO: Recreate the machine function.
541 if (Target) {
542 // Avoid clearing state if we're using the same subtarget again.
543 Target->setTarget(MF.getSubtarget());
544 } else {
545 Target.reset(p: new PerTargetMIParsingState(MF.getSubtarget()));
546 }
547
548 MF.setAlignment(YamlMF.Alignment.valueOrOne());
549 MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
550 MF.setHasWinCFI(YamlMF.HasWinCFI);
551
552 MF.setCallsEHReturn(YamlMF.CallsEHReturn);
553 MF.setCallsUnwindInit(YamlMF.CallsUnwindInit);
554 MF.setHasEHContTarget(YamlMF.HasEHContTarget);
555 MF.setHasEHScopes(YamlMF.HasEHScopes);
556 MF.setHasEHFunclets(YamlMF.HasEHFunclets);
557 MF.setIsOutlined(YamlMF.IsOutlined);
558
559 MachineFunctionProperties &Props = MF.getProperties();
560 if (YamlMF.Legalized)
561 Props.setLegalized();
562 if (YamlMF.RegBankSelected)
563 Props.setRegBankSelected();
564 if (YamlMF.Selected)
565 Props.setSelected();
566 if (YamlMF.FailedISel)
567 Props.setFailedISel();
568 if (YamlMF.FailsVerification)
569 Props.setFailsVerification();
570 if (YamlMF.TracksDebugUserValues)
571 Props.setTracksDebugUserValues();
572
573 PerFunctionMIParsingState PFS(MF, SM, IRSlots, *Target);
574 if (parseRegisterInfo(PFS, YamlMF))
575 return true;
576 if (!YamlMF.Constants.empty()) {
577 auto *ConstantPool = MF.getConstantPool();
578 assert(ConstantPool && "Constant pool must be created");
579 if (initializeConstantPool(PFS, ConstantPool&: *ConstantPool, YamlMF))
580 return true;
581 }
582 if (!YamlMF.MachineMetadataNodes.empty() &&
583 parseMachineMetadataNodes(PFS, MF, YMF: YamlMF))
584 return true;
585
586 StringRef BlockStr = YamlMF.Body.Value.Value;
587 SMDiagnostic Error;
588 SourceMgr BlockSM;
589 BlockSM.AddNewSourceBuffer(
590 F: MemoryBuffer::getMemBuffer(InputData: BlockStr, BufferName: "",/*RequiresNullTerminator=*/false),
591 IncludeLoc: SMLoc());
592 PFS.SM = &BlockSM;
593 if (parseMachineBasicBlockDefinitions(PFS, Src: BlockStr, Error)) {
594 reportDiagnostic(
595 Diag: diagFromBlockStringDiag(Error, SourceRange: YamlMF.Body.Value.SourceRange));
596 return true;
597 }
598 // Check Basic Block Section Flags.
599 if (MF.hasBBSections()) {
600 MF.assignBeginEndSections();
601 }
602 PFS.SM = &SM;
603
604 // Initialize the frame information after creating all the MBBs so that the
605 // MBB references in the frame information can be resolved.
606 if (initializeFrameInfo(PFS, YamlMF))
607 return true;
608 // Initialize the jump table after creating all the MBBs so that the MBB
609 // references can be resolved.
610 if (!YamlMF.JumpTableInfo.Entries.empty() &&
611 initializeJumpTableInfo(PFS, YamlJTI: YamlMF.JumpTableInfo))
612 return true;
613 // Parse the machine instructions after creating all of the MBBs so that the
614 // parser can resolve the MBB references.
615 StringRef InsnStr = YamlMF.Body.Value.Value;
616 SourceMgr InsnSM;
617 InsnSM.AddNewSourceBuffer(
618 F: MemoryBuffer::getMemBuffer(InputData: InsnStr, BufferName: "", /*RequiresNullTerminator=*/false),
619 IncludeLoc: SMLoc());
620 PFS.SM = &InsnSM;
621 if (parseMachineInstructions(PFS, Src: InsnStr, Error)) {
622 reportDiagnostic(
623 Diag: diagFromBlockStringDiag(Error, SourceRange: YamlMF.Body.Value.SourceRange));
624 return true;
625 }
626 PFS.SM = &SM;
627
628 if (setupRegisterInfo(PFS, YamlMF))
629 return true;
630
631 if (YamlMF.MachineFuncInfo) {
632 const TargetMachine &TM = MF.getTarget();
633 // Note this is called after the initial constructor of the
634 // MachineFunctionInfo based on the MachineFunction, which may depend on the
635 // IR.
636
637 SMRange SrcRange;
638 if (TM.parseMachineFunctionInfo(*YamlMF.MachineFuncInfo, PFS, Error,
639 SourceRange&: SrcRange)) {
640 return error(Error, SourceRange: SrcRange);
641 }
642 }
643
644 // Set the reserved registers after parsing MachineFuncInfo. The target may
645 // have been recording information used to select the reserved registers
646 // there.
647 // FIXME: This is a temporary workaround until the reserved registers can be
648 // serialized.
649 MachineRegisterInfo &MRI = MF.getRegInfo();
650 MRI.freezeReservedRegs();
651
652 if (computeFunctionProperties(MF, YamlMF))
653 return true;
654
655 if (initializeCallSiteInfo(PFS, YamlMF))
656 return true;
657
658 if (parseCalledGlobals(PFS, MF, YMF: YamlMF))
659 return true;
660
661 setupDebugValueTracking(MF, PFS, YamlMF);
662
663 MF.getSubtarget().mirFileLoaded(MF);
664
665 MF.verify(p: nullptr, Banner: nullptr, OS: &errs());
666 return false;
667}
668
669bool MIRParserImpl::parseRegisterInfo(PerFunctionMIParsingState &PFS,
670 const yaml::MachineFunction &YamlMF) {
671 MachineFunction &MF = PFS.MF;
672 MachineRegisterInfo &RegInfo = MF.getRegInfo();
673 assert(RegInfo.tracksLiveness());
674 if (!YamlMF.TracksRegLiveness)
675 RegInfo.invalidateLiveness();
676
677 SMDiagnostic Error;
678 // Parse the virtual register information.
679 for (const auto &VReg : YamlMF.VirtualRegisters) {
680 VRegInfo &Info = PFS.getVRegInfo(Num: VReg.ID.Value);
681 if (Info.Explicit)
682 return error(Loc: VReg.ID.SourceRange.Start,
683 Message: Twine("redefinition of virtual register '%") +
684 Twine(VReg.ID.Value) + "'");
685 Info.Explicit = true;
686
687 if (VReg.Class.Value == "_") {
688 Info.Kind = VRegInfo::GENERIC;
689 Info.D.RegBank = nullptr;
690 } else {
691 const auto *RC = Target->getRegClass(Name: VReg.Class.Value);
692 if (RC) {
693 Info.Kind = VRegInfo::NORMAL;
694 Info.D.RC = RC;
695 } else {
696 const RegisterBank *RegBank = Target->getRegBank(Name: VReg.Class.Value);
697 if (!RegBank)
698 return error(
699 Loc: VReg.Class.SourceRange.Start,
700 Message: Twine("use of undefined register class or register bank '") +
701 VReg.Class.Value + "'");
702 Info.Kind = VRegInfo::REGBANK;
703 Info.D.RegBank = RegBank;
704 }
705 }
706
707 if (!VReg.PreferredRegister.Value.empty()) {
708 if (Info.Kind != VRegInfo::NORMAL)
709 return error(Loc: VReg.Class.SourceRange.Start,
710 Message: Twine("preferred register can only be set for normal vregs"));
711
712 if (parseRegisterReference(PFS, Reg&: Info.PreferredReg,
713 Src: VReg.PreferredRegister.Value, Error))
714 return error(Error, SourceRange: VReg.PreferredRegister.SourceRange);
715 }
716
717 for (const auto &FlagStringValue : VReg.RegisterFlags) {
718 uint8_t FlagValue;
719 if (Target->getVRegFlagValue(FlagName: FlagStringValue.Value, FlagValue))
720 return error(Loc: FlagStringValue.SourceRange.Start,
721 Message: Twine("use of undefined register flag '") +
722 FlagStringValue.Value + "'");
723 Info.Flags |= FlagValue;
724 }
725 RegInfo.noteNewVirtualRegister(Reg: Info.VReg);
726 }
727
728 // Parse the liveins.
729 for (const auto &LiveIn : YamlMF.LiveIns) {
730 Register Reg;
731 if (parseNamedRegisterReference(PFS, Reg, Src: LiveIn.Register.Value, Error))
732 return error(Error, SourceRange: LiveIn.Register.SourceRange);
733 Register VReg;
734 if (!LiveIn.VirtualRegister.Value.empty()) {
735 VRegInfo *Info;
736 if (parseVirtualRegisterReference(PFS, Info, Src: LiveIn.VirtualRegister.Value,
737 Error))
738 return error(Error, SourceRange: LiveIn.VirtualRegister.SourceRange);
739 VReg = Info->VReg;
740 }
741 RegInfo.addLiveIn(Reg, vreg: VReg);
742 }
743
744 // Parse the callee saved registers (Registers that will
745 // be saved for the caller).
746 if (YamlMF.CalleeSavedRegisters) {
747 SmallVector<MCPhysReg, 16> CalleeSavedRegisters;
748 for (const auto &RegSource : *YamlMF.CalleeSavedRegisters) {
749 Register Reg;
750 if (parseNamedRegisterReference(PFS, Reg, Src: RegSource.Value, Error))
751 return error(Error, SourceRange: RegSource.SourceRange);
752 CalleeSavedRegisters.push_back(Elt: Reg.id());
753 }
754 RegInfo.setCalleeSavedRegs(CalleeSavedRegisters);
755 }
756
757 return false;
758}
759
760bool MIRParserImpl::setupRegisterInfo(const PerFunctionMIParsingState &PFS,
761 const yaml::MachineFunction &YamlMF) {
762 MachineFunction &MF = PFS.MF;
763 MachineRegisterInfo &MRI = MF.getRegInfo();
764 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
765
766 SmallVector<std::string> Errors;
767
768 // Create VRegs
769 auto populateVRegInfo = [&](const VRegInfo &Info, const Twine &Name) {
770 Register Reg = Info.VReg;
771 switch (Info.Kind) {
772 case VRegInfo::UNKNOWN:
773 Errors.push_back(
774 Elt: (Twine("Cannot determine class/bank of virtual register ") + Name +
775 " in function '" + MF.getName() + "'")
776 .str());
777 break;
778 case VRegInfo::NORMAL:
779 if (!Info.D.RC->isAllocatable()) {
780 Errors.push_back(Elt: (Twine("Cannot use non-allocatable class '") +
781 TRI->getRegClassName(Class: Info.D.RC) +
782 "' for virtual register " + Name + " in function '" +
783 MF.getName() + "'")
784 .str());
785 break;
786 }
787
788 MRI.setRegClass(Reg, RC: Info.D.RC);
789 if (Info.PreferredReg != 0)
790 MRI.setSimpleHint(VReg: Reg, PrefReg: Info.PreferredReg);
791 break;
792 case VRegInfo::GENERIC:
793 break;
794 case VRegInfo::REGBANK:
795 MRI.setRegBank(Reg, RegBank: *Info.D.RegBank);
796 break;
797 }
798 };
799
800 for (const auto &P : PFS.VRegInfosNamed) {
801 const VRegInfo &Info = *P.second;
802 populateVRegInfo(Info, Twine(P.first()));
803 }
804
805 for (auto P : PFS.VRegInfos) {
806 const VRegInfo &Info = *P.second;
807 populateVRegInfo(Info, Twine(P.first.id()));
808 }
809
810 // Compute MachineRegisterInfo::UsedPhysRegMask
811 for (const MachineBasicBlock &MBB : MF) {
812 // Make sure MRI knows about registers clobbered by unwinder.
813 if (MBB.isEHPad())
814 if (auto *RegMask = TRI->getCustomEHPadPreservedMask(MF))
815 MRI.addPhysRegsUsedFromRegMask(RegMask);
816
817 for (const MachineInstr &MI : MBB) {
818 for (const MachineOperand &MO : MI.operands()) {
819 if (!MO.isRegMask())
820 continue;
821 MRI.addPhysRegsUsedFromRegMask(RegMask: MO.getRegMask());
822 }
823 }
824 }
825
826 if (Errors.empty())
827 return false;
828
829 // Report errors in a deterministic order.
830 sort(C&: Errors);
831 for (auto &E : Errors)
832 error(Message: E);
833 return true;
834}
835
836bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS,
837 const yaml::MachineFunction &YamlMF) {
838 MachineFunction &MF = PFS.MF;
839 MachineFrameInfo &MFI = MF.getFrameInfo();
840 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
841 const Function &F = MF.getFunction();
842 const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
843 MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
844 MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
845 MFI.setHasStackMap(YamlMFI.HasStackMap);
846 MFI.setHasPatchPoint(YamlMFI.HasPatchPoint);
847 MFI.setStackSize(YamlMFI.StackSize);
848 MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment);
849 if (YamlMFI.MaxAlignment)
850 MFI.ensureMaxAlignment(Alignment: Align(YamlMFI.MaxAlignment));
851 MFI.setAdjustsStack(YamlMFI.AdjustsStack);
852 MFI.setHasCalls(YamlMFI.HasCalls);
853 if (YamlMFI.MaxCallFrameSize != ~0u)
854 MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize);
855 MFI.setCVBytesOfCalleeSavedRegisters(YamlMFI.CVBytesOfCalleeSavedRegisters);
856 MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment);
857 MFI.setHasVAStart(YamlMFI.HasVAStart);
858 MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
859 MFI.setHasTailCall(YamlMFI.HasTailCall);
860 MFI.setCalleeSavedInfoValid(YamlMFI.IsCalleeSavedInfoValid);
861 MFI.setLocalFrameSize(YamlMFI.LocalFrameSize);
862 if (!YamlMFI.SavePoint.Value.empty()) {
863 MachineBasicBlock *MBB = nullptr;
864 if (parseMBBReference(PFS, MBB, Source: YamlMFI.SavePoint))
865 return true;
866 MFI.setSavePoint(MBB);
867 }
868 if (!YamlMFI.RestorePoint.Value.empty()) {
869 MachineBasicBlock *MBB = nullptr;
870 if (parseMBBReference(PFS, MBB, Source: YamlMFI.RestorePoint))
871 return true;
872 MFI.setRestorePoint(MBB);
873 }
874
875 std::vector<CalleeSavedInfo> CSIInfo;
876 // Initialize the fixed frame objects.
877 for (const auto &Object : YamlMF.FixedStackObjects) {
878 int ObjectIdx;
879 if (Object.Type != yaml::FixedMachineStackObject::SpillSlot)
880 ObjectIdx = MFI.CreateFixedObject(Size: Object.Size, SPOffset: Object.Offset,
881 IsImmutable: Object.IsImmutable, isAliased: Object.IsAliased);
882 else
883 ObjectIdx = MFI.CreateFixedSpillStackObject(Size: Object.Size, SPOffset: Object.Offset);
884
885 if (!TFI->isSupportedStackID(ID: Object.StackID))
886 return error(Loc: Object.ID.SourceRange.Start,
887 Message: Twine("StackID is not supported by target"));
888 MFI.setStackID(ObjectIdx, ID: Object.StackID);
889 MFI.setObjectAlignment(ObjectIdx, Alignment: Object.Alignment.valueOrOne());
890 if (!PFS.FixedStackObjectSlots.insert(KV: std::make_pair(x: Object.ID.Value,
891 y&: ObjectIdx))
892 .second)
893 return error(Loc: Object.ID.SourceRange.Start,
894 Message: Twine("redefinition of fixed stack object '%fixed-stack.") +
895 Twine(Object.ID.Value) + "'");
896 if (parseCalleeSavedRegister(PFS, CSIInfo, RegisterSource: Object.CalleeSavedRegister,
897 IsRestored: Object.CalleeSavedRestored, FrameIdx: ObjectIdx))
898 return true;
899 if (parseStackObjectsDebugInfo(PFS, Object, FrameIdx: ObjectIdx))
900 return true;
901 }
902
903 for (const auto &Object : YamlMF.EntryValueObjects) {
904 SMDiagnostic Error;
905 Register Reg;
906 if (parseNamedRegisterReference(PFS, Reg, Src: Object.EntryValueRegister.Value,
907 Error))
908 return error(Error, SourceRange: Object.EntryValueRegister.SourceRange);
909 if (!Reg.isPhysical())
910 return error(Loc: Object.EntryValueRegister.SourceRange.Start,
911 Message: "Expected physical register for entry value field");
912 std::optional<VarExprLoc> MaybeInfo = parseVarExprLoc(
913 PFS, VarStr: Object.DebugVar, ExprStr: Object.DebugExpr, LocStr: Object.DebugLoc);
914 if (!MaybeInfo)
915 return true;
916 if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc)
917 PFS.MF.setVariableDbgInfo(Var: MaybeInfo->DIVar, Expr: MaybeInfo->DIExpr,
918 Reg: Reg.asMCReg(), Loc: MaybeInfo->DILoc);
919 }
920
921 // Initialize the ordinary frame objects.
922 for (const auto &Object : YamlMF.StackObjects) {
923 int ObjectIdx;
924 const AllocaInst *Alloca = nullptr;
925 const yaml::StringValue &Name = Object.Name;
926 if (!Name.Value.empty()) {
927 Alloca = dyn_cast_or_null<AllocaInst>(
928 Val: F.getValueSymbolTable()->lookup(Name: Name.Value));
929 if (!Alloca)
930 return error(Loc: Name.SourceRange.Start,
931 Message: "alloca instruction named '" + Name.Value +
932 "' isn't defined in the function '" + F.getName() +
933 "'");
934 }
935 if (!TFI->isSupportedStackID(ID: Object.StackID))
936 return error(Loc: Object.ID.SourceRange.Start,
937 Message: Twine("StackID is not supported by target"));
938 if (Object.Type == yaml::MachineStackObject::VariableSized)
939 ObjectIdx =
940 MFI.CreateVariableSizedObject(Alignment: Object.Alignment.valueOrOne(), Alloca);
941 else
942 ObjectIdx = MFI.CreateStackObject(
943 Size: Object.Size, Alignment: Object.Alignment.valueOrOne(),
944 isSpillSlot: Object.Type == yaml::MachineStackObject::SpillSlot, Alloca,
945 ID: Object.StackID);
946 MFI.setObjectOffset(ObjectIdx, SPOffset: Object.Offset);
947
948 if (!PFS.StackObjectSlots.insert(KV: std::make_pair(x: Object.ID.Value, y&: ObjectIdx))
949 .second)
950 return error(Loc: Object.ID.SourceRange.Start,
951 Message: Twine("redefinition of stack object '%stack.") +
952 Twine(Object.ID.Value) + "'");
953 if (parseCalleeSavedRegister(PFS, CSIInfo, RegisterSource: Object.CalleeSavedRegister,
954 IsRestored: Object.CalleeSavedRestored, FrameIdx: ObjectIdx))
955 return true;
956 if (Object.LocalOffset)
957 MFI.mapLocalFrameObject(ObjectIndex: ObjectIdx, Offset: *Object.LocalOffset);
958 if (parseStackObjectsDebugInfo(PFS, Object, FrameIdx: ObjectIdx))
959 return true;
960 }
961 MFI.setCalleeSavedInfo(CSIInfo);
962 if (!CSIInfo.empty())
963 MFI.setCalleeSavedInfoValid(true);
964
965 // Initialize the various stack object references after initializing the
966 // stack objects.
967 if (!YamlMFI.StackProtector.Value.empty()) {
968 SMDiagnostic Error;
969 int FI;
970 if (parseStackObjectReference(PFS, FI, Src: YamlMFI.StackProtector.Value, Error))
971 return error(Error, SourceRange: YamlMFI.StackProtector.SourceRange);
972 MFI.setStackProtectorIndex(FI);
973 }
974
975 if (!YamlMFI.FunctionContext.Value.empty()) {
976 SMDiagnostic Error;
977 int FI;
978 if (parseStackObjectReference(PFS, FI, Src: YamlMFI.FunctionContext.Value, Error))
979 return error(Error, SourceRange: YamlMFI.FunctionContext.SourceRange);
980 MFI.setFunctionContextIndex(FI);
981 }
982
983 return false;
984}
985
986bool MIRParserImpl::parseCalleeSavedRegister(PerFunctionMIParsingState &PFS,
987 std::vector<CalleeSavedInfo> &CSIInfo,
988 const yaml::StringValue &RegisterSource, bool IsRestored, int FrameIdx) {
989 if (RegisterSource.Value.empty())
990 return false;
991 Register Reg;
992 SMDiagnostic Error;
993 if (parseNamedRegisterReference(PFS, Reg, Src: RegisterSource.Value, Error))
994 return error(Error, SourceRange: RegisterSource.SourceRange);
995 CalleeSavedInfo CSI(Reg, FrameIdx);
996 CSI.setRestored(IsRestored);
997 CSIInfo.push_back(x: CSI);
998 return false;
999}
1000
1001/// Verify that given node is of a certain type. Return true on error.
1002template <typename T>
1003static bool typecheckMDNode(T *&Result, MDNode *Node,
1004 const yaml::StringValue &Source,
1005 StringRef TypeString, MIRParserImpl &Parser) {
1006 if (!Node)
1007 return false;
1008 Result = dyn_cast<T>(Node);
1009 if (!Result)
1010 return Parser.error(Loc: Source.SourceRange.Start,
1011 Message: "expected a reference to a '" + TypeString +
1012 "' metadata node");
1013 return false;
1014}
1015
1016std::optional<MIRParserImpl::VarExprLoc> MIRParserImpl::parseVarExprLoc(
1017 PerFunctionMIParsingState &PFS, const yaml::StringValue &VarStr,
1018 const yaml::StringValue &ExprStr, const yaml::StringValue &LocStr) {
1019 MDNode *Var = nullptr;
1020 MDNode *Expr = nullptr;
1021 MDNode *Loc = nullptr;
1022 if (parseMDNode(PFS, Node&: Var, Source: VarStr) || parseMDNode(PFS, Node&: Expr, Source: ExprStr) ||
1023 parseMDNode(PFS, Node&: Loc, Source: LocStr))
1024 return std::nullopt;
1025 DILocalVariable *DIVar = nullptr;
1026 DIExpression *DIExpr = nullptr;
1027 DILocation *DILoc = nullptr;
1028 if (typecheckMDNode(Result&: DIVar, Node: Var, Source: VarStr, TypeString: "DILocalVariable", Parser&: *this) ||
1029 typecheckMDNode(Result&: DIExpr, Node: Expr, Source: ExprStr, TypeString: "DIExpression", Parser&: *this) ||
1030 typecheckMDNode(Result&: DILoc, Node: Loc, Source: LocStr, TypeString: "DILocation", Parser&: *this))
1031 return std::nullopt;
1032 return VarExprLoc{.DIVar: DIVar, .DIExpr: DIExpr, .DILoc: DILoc};
1033}
1034
1035template <typename T>
1036bool MIRParserImpl::parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS,
1037 const T &Object, int FrameIdx) {
1038 std::optional<VarExprLoc> MaybeInfo =
1039 parseVarExprLoc(PFS, VarStr: Object.DebugVar, ExprStr: Object.DebugExpr, LocStr: Object.DebugLoc);
1040 if (!MaybeInfo)
1041 return true;
1042 // Debug information can only be attached to stack objects; Fixed stack
1043 // objects aren't supported.
1044 if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc)
1045 PFS.MF.setVariableDbgInfo(Var: MaybeInfo->DIVar, Expr: MaybeInfo->DIExpr, Slot: FrameIdx,
1046 Loc: MaybeInfo->DILoc);
1047 return false;
1048}
1049
1050bool MIRParserImpl::parseMDNode(PerFunctionMIParsingState &PFS,
1051 MDNode *&Node, const yaml::StringValue &Source) {
1052 if (Source.Value.empty())
1053 return false;
1054 SMDiagnostic Error;
1055 if (llvm::parseMDNode(PFS, Node, Src: Source.Value, Error))
1056 return error(Error, SourceRange: Source.SourceRange);
1057 return false;
1058}
1059
1060bool MIRParserImpl::initializeConstantPool(PerFunctionMIParsingState &PFS,
1061 MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF) {
1062 DenseMap<unsigned, unsigned> &ConstantPoolSlots = PFS.ConstantPoolSlots;
1063 const MachineFunction &MF = PFS.MF;
1064 const auto &M = *MF.getFunction().getParent();
1065 SMDiagnostic Error;
1066 for (const auto &YamlConstant : YamlMF.Constants) {
1067 if (YamlConstant.IsTargetSpecific)
1068 // FIXME: Support target-specific constant pools
1069 return error(Loc: YamlConstant.Value.SourceRange.Start,
1070 Message: "Can't parse target-specific constant pool entries yet");
1071 const Constant *Value = dyn_cast_or_null<Constant>(
1072 Val: parseConstantValue(Asm: YamlConstant.Value.Value, Err&: Error, M));
1073 if (!Value)
1074 return error(Error, SourceRange: YamlConstant.Value.SourceRange);
1075 const Align PrefTypeAlign =
1076 M.getDataLayout().getPrefTypeAlign(Ty: Value->getType());
1077 const Align Alignment = YamlConstant.Alignment.value_or(u: PrefTypeAlign);
1078 unsigned Index = ConstantPool.getConstantPoolIndex(C: Value, Alignment);
1079 if (!ConstantPoolSlots.insert(KV: std::make_pair(x: YamlConstant.ID.Value, y&: Index))
1080 .second)
1081 return error(Loc: YamlConstant.ID.SourceRange.Start,
1082 Message: Twine("redefinition of constant pool item '%const.") +
1083 Twine(YamlConstant.ID.Value) + "'");
1084 }
1085 return false;
1086}
1087
1088bool MIRParserImpl::initializeJumpTableInfo(PerFunctionMIParsingState &PFS,
1089 const yaml::MachineJumpTable &YamlJTI) {
1090 MachineJumpTableInfo *JTI = PFS.MF.getOrCreateJumpTableInfo(JTEntryKind: YamlJTI.Kind);
1091 for (const auto &Entry : YamlJTI.Entries) {
1092 std::vector<MachineBasicBlock *> Blocks;
1093 for (const auto &MBBSource : Entry.Blocks) {
1094 MachineBasicBlock *MBB = nullptr;
1095 if (parseMBBReference(PFS, MBB, Source: MBBSource.Value))
1096 return true;
1097 Blocks.push_back(x: MBB);
1098 }
1099 unsigned Index = JTI->createJumpTableIndex(DestBBs: Blocks);
1100 if (!PFS.JumpTableSlots.insert(KV: std::make_pair(x: Entry.ID.Value, y&: Index))
1101 .second)
1102 return error(Loc: Entry.ID.SourceRange.Start,
1103 Message: Twine("redefinition of jump table entry '%jump-table.") +
1104 Twine(Entry.ID.Value) + "'");
1105 }
1106 return false;
1107}
1108
1109bool MIRParserImpl::parseMBBReference(PerFunctionMIParsingState &PFS,
1110 MachineBasicBlock *&MBB,
1111 const yaml::StringValue &Source) {
1112 SMDiagnostic Error;
1113 if (llvm::parseMBBReference(PFS, MBB, Src: Source.Value, Error))
1114 return error(Error, SourceRange: Source.SourceRange);
1115 return false;
1116}
1117
1118bool MIRParserImpl::parseMachineMetadata(PerFunctionMIParsingState &PFS,
1119 const yaml::StringValue &Source) {
1120 SMDiagnostic Error;
1121 if (llvm::parseMachineMetadata(PFS, Src: Source.Value, SourceRange: Source.SourceRange, Error))
1122 return error(Error, SourceRange: Source.SourceRange);
1123 return false;
1124}
1125
1126bool MIRParserImpl::parseMachineMetadataNodes(
1127 PerFunctionMIParsingState &PFS, MachineFunction &MF,
1128 const yaml::MachineFunction &YMF) {
1129 for (const auto &MDS : YMF.MachineMetadataNodes) {
1130 if (parseMachineMetadata(PFS, Source: MDS))
1131 return true;
1132 }
1133 // Report missing definitions from forward referenced nodes.
1134 if (!PFS.MachineForwardRefMDNodes.empty())
1135 return error(Loc: PFS.MachineForwardRefMDNodes.begin()->second.second,
1136 Message: "use of undefined metadata '!" +
1137 Twine(PFS.MachineForwardRefMDNodes.begin()->first) + "'");
1138 return false;
1139}
1140
1141bool MIRParserImpl::parseCalledGlobals(PerFunctionMIParsingState &PFS,
1142 MachineFunction &MF,
1143 const yaml::MachineFunction &YMF) {
1144 Function &F = MF.getFunction();
1145 for (const auto &YamlCG : YMF.CalledGlobals) {
1146 yaml::MachineInstrLoc MILoc = YamlCG.CallSite;
1147 const MachineInstr *CallI;
1148 if (parseMachineInst(MF, MILoc, MI&: CallI))
1149 return true;
1150 if (!CallI->isCall(Type: MachineInstr::IgnoreBundle))
1151 return error(Message: Twine(MF.getName()) +
1152 Twine(" called global should reference call "
1153 "instruction. Instruction at bb:") +
1154 Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset) +
1155 " is not a call instruction");
1156
1157 auto Callee =
1158 F.getParent()->getValueSymbolTable().lookup(Name: YamlCG.Callee.Value);
1159 if (!Callee)
1160 return error(Loc: YamlCG.Callee.SourceRange.Start,
1161 Message: "use of undefined global '" + YamlCG.Callee.Value + "'");
1162 if (!isa<GlobalValue>(Val: Callee))
1163 return error(Loc: YamlCG.Callee.SourceRange.Start,
1164 Message: "use of non-global value '" + YamlCG.Callee.Value + "'");
1165
1166 MF.addCalledGlobal(MI: CallI, Details: {.Callee: cast<GlobalValue>(Val: Callee), .TargetFlags: YamlCG.Flags});
1167 }
1168
1169 return false;
1170}
1171
1172SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
1173 SMRange SourceRange) {
1174 assert(SourceRange.isValid() && "Invalid source range");
1175 SMLoc Loc = SourceRange.Start;
1176 bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
1177 *Loc.getPointer() == '\'';
1178 // Translate the location of the error from the location in the MI string to
1179 // the corresponding location in the MIR file.
1180 Loc = Loc.getFromPointer(Ptr: Loc.getPointer() + Error.getColumnNo() +
1181 (HasQuote ? 1 : 0));
1182
1183 // TODO: Translate any source ranges as well.
1184 return SM.GetMessage(Loc, Kind: Error.getKind(), Msg: Error.getMessage(), Ranges: {},
1185 FixIts: Error.getFixIts());
1186}
1187
1188SMDiagnostic MIRParserImpl::diagFromBlockStringDiag(const SMDiagnostic &Error,
1189 SMRange SourceRange) {
1190 assert(SourceRange.isValid());
1191
1192 // Translate the location of the error from the location in the llvm IR string
1193 // to the corresponding location in the MIR file.
1194 auto LineAndColumn = SM.getLineAndColumn(Loc: SourceRange.Start);
1195 unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
1196 unsigned Column = Error.getColumnNo();
1197 StringRef LineStr = Error.getLineContents();
1198 SMLoc Loc = Error.getLoc();
1199
1200 // Get the full line and adjust the column number by taking the indentation of
1201 // LLVM IR into account.
1202 for (line_iterator L(*SM.getMemoryBuffer(i: SM.getMainFileID()), false), E;
1203 L != E; ++L) {
1204 if (L.line_number() == Line) {
1205 LineStr = *L;
1206 Loc = SMLoc::getFromPointer(Ptr: LineStr.data());
1207 auto Indent = LineStr.find(Str: Error.getLineContents());
1208 if (Indent != StringRef::npos)
1209 Column += Indent;
1210 break;
1211 }
1212 }
1213
1214 return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
1215 Error.getMessage(), LineStr, Error.getRanges(),
1216 Error.getFixIts());
1217}
1218
1219MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
1220 : Impl(std::move(Impl)) {}
1221
1222MIRParser::~MIRParser() = default;
1223
1224std::unique_ptr<Module>
1225MIRParser::parseIRModule(DataLayoutCallbackTy DataLayoutCallback) {
1226 return Impl->parseIRModule(DataLayoutCallback);
1227}
1228
1229bool MIRParser::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
1230 return Impl->parseMachineFunctions(M, MMI);
1231}
1232
1233bool MIRParser::parseMachineFunctions(Module &M, ModuleAnalysisManager &MAM) {
1234 auto &MMI = MAM.getResult<MachineModuleAnalysis>(IR&: M).getMMI();
1235 return Impl->parseMachineFunctions(M, MMI, MAM: &MAM);
1236}
1237
1238std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(
1239 StringRef Filename, SMDiagnostic &Error, LLVMContext &Context,
1240 std::function<void(Function &)> ProcessIRFunction) {
1241 auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
1242 if (std::error_code EC = FileOrErr.getError()) {
1243 Error = SMDiagnostic(Filename, SourceMgr::DK_Error,
1244 "Could not open input file: " + EC.message());
1245 return nullptr;
1246 }
1247 return createMIRParser(Contents: std::move(FileOrErr.get()), Context,
1248 ProcessIRFunction);
1249}
1250
1251std::unique_ptr<MIRParser>
1252llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
1253 LLVMContext &Context,
1254 std::function<void(Function &)> ProcessIRFunction) {
1255 auto Filename = Contents->getBufferIdentifier();
1256 if (Context.shouldDiscardValueNames()) {
1257 Context.diagnose(DI: DiagnosticInfoMIRParser(
1258 DS_Error,
1259 SMDiagnostic(
1260 Filename, SourceMgr::DK_Error,
1261 "Can't read MIR with a Context that discards named Values")));
1262 return nullptr;
1263 }
1264 return std::make_unique<MIRParser>(args: std::make_unique<MIRParserImpl>(
1265 args: std::move(Contents), args&: Filename, args&: Context, args&: ProcessIRFunction));
1266}
1267