LLVM 20.0.0git
MIRParser.cpp
Go to the documentation of this file.
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
15#include "llvm/ADT/DenseMap.h"
16#include "llvm/ADT/StringRef.h"
28#include "llvm/IR/BasicBlock.h"
32#include "llvm/IR/LLVMContext.h"
33#include "llvm/IR/Module.h"
37#include "llvm/Support/SMLoc.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.
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.
100
102 ModuleAnalysisManager *FAM = nullptr);
103
104 /// Parse the machine function in the current YAML document.
105 ///
106 ///
107 /// Return true if an error occurred.
110
111 /// Initialize the machine function to the state that's described in the MIR
112 /// file.
113 ///
114 /// Return true if error occurred.
116 MachineFunction &MF);
117
119 const yaml::MachineFunction &YamlMF);
120
122 const yaml::MachineFunction &YamlMF);
123
125 const yaml::MachineFunction &YamlMF);
126
128 const yaml::MachineFunction &YamlMF);
129
131 std::vector<CalleeSavedInfo> &CSIInfo,
132 const yaml::StringValue &RegisterSource,
133 bool IsRestored, int FrameIdx);
134
135 struct VarExprLoc {
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>
147 const T &Object,
148 int FrameIdx);
149
152 const yaml::MachineFunction &YamlMF);
153
155 const yaml::MachineJumpTable &YamlJTI);
156
158 MachineFunction &MF,
159 const yaml::MachineFunction &YMF);
160
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,
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,
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(SM.AddNewSourceBuffer(std::move(Contents), SMLoc()))
205 ->getBuffer(),
206 nullptr, handleYAMLDiag, this),
207 Filename(Filename), ProcessIRFunction(Callback) {
208 In.setContext(&In);
209}
210
211bool MIRParserImpl::error(const Twine &Message) {
213 DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str())));
214 return true;
215}
216
217bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) {
219 DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message)));
220 return true;
221}
222
224 assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error");
225 reportDiagnostic(diagFromMIStringDiag(Error, SourceRange));
226 return true;
227}
228
231 switch (Diag.getKind()) {
233 Kind = DS_Error;
234 break;
236 Kind = DS_Warning;
237 break;
239 Kind = DS_Note;
240 break;
242 llvm_unreachable("remark unexpected");
243 break;
244 }
245 Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));
246}
247
248std::unique_ptr<Module>
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>(Filename, Context);
256 if (auto LayoutOverride =
257 DataLayoutCallback(M->getTargetTriple(), 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>(In.getCurrentNode())) {
268 M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
269 Context, &IRSlots, DataLayoutCallback);
270 if (!M) {
271 reportDiagnostic(diagFromBlockStringDiag(Error, 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>(Filename, Context);
280 if (auto LayoutOverride =
281 DataLayoutCallback(M->getTargetTriple(), M->getDataLayoutStr()))
282 M->setDataLayout(*LayoutOverride);
283 NoLLVMIR = true;
284 }
285 return M;
286}
287
290 if (NoMIRDocuments)
291 return false;
292
293 // Parse the machine functions.
294 do {
295 if (parseMachineFunction(M, MMI, MAM))
296 return true;
297 In.nextDocument();
298 } while (In.setCurrentDocument());
299
300 return false;
301}
302
304 auto &Context = M.getContext();
305 Function *F =
308 BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
309 new UnreachableInst(Context, BB);
310
311 if (ProcessIRFunction)
312 ProcessIRFunction(*F);
313
314 return F;
315}
316
319 // Parse the yaml.
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(In, 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(FunctionName);
334 if (!F) {
335 if (NoLLVMIR) {
336 F = createDummyFunction(FunctionName, M);
337 } else {
338 return error(Twine("function '") + FunctionName +
339 "' isn't defined in the provided LLVM IR");
340 }
341 }
342
343 if (!MAM) {
344 if (MMI.getMachineFunction(*F) != nullptr)
345 return error(Twine("redefinition of machine function '") + FunctionName +
346 "'");
347
348 // Create the MachineFunction.
350 if (initializeMachineFunction(YamlMF, MF))
351 return true;
352 } else {
353 auto &FAM =
356 return error(Twine("redefinition of machine function '") + FunctionName +
357 "'");
358
359 // Create the MachineFunction.
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) {
372 if (!MRI.hasOneDef(Reg) && !MRI.def_empty(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);
401 if (!MO.isReg() || !MO.getReg())
402 continue;
403 unsigned DefIdx;
404 if (MO.isUse() && MI.isRegTiedToDefOperand(I, &DefIdx)) {
405 HasTiedOps = true;
406 if (MO.getReg() != MI.getOperand(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,
418 // Prefer explicitly given values over the computed properties
419 if (ExplicitProp.value_or(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,
430 return error(MF.getName() +
431 " has explicit property NoPhi, but contains at least one PHI");
432 }
433
434 MF.setHasInlineAsm(HasInlineAsm);
435
436 if (HasTiedOps && AllTiedOpsRewritten)
438
439 if (ComputedPropertyHelper(YamlMF.IsSSA, isSSA(MF),
441 return error(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,
448 return error(
449 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 MF.getName() +
460 " has explicit property hasFakeUses=false, but contains fake uses");
461 MF.setHasFakeUses(YamlMF.HasFakeUses.value_or(HasFakeUses));
462
463 return false;
464}
465
466bool MIRParserImpl::parseMachineInst(MachineFunction &MF,
468 MachineInstr const *&MI) {
469 if (MILoc.BlockNum >= MF.size()) {
470 return error(Twine(MF.getName()) +
471 Twine(" instruction block out of range.") +
472 " Unable to reference bb:" + Twine(MILoc.BlockNum));
473 }
474 auto BB = std::next(MF.begin(), MILoc.BlockNum);
475 if (MILoc.Offset >= BB->size())
476 return error(
477 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(BB->instr_begin(), MILoc.Offset);
481 return false;
482}
483
486 MachineFunction &MF = PFS.MF;
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, CallI))
493 return true;
495 return error(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");
501 for (auto ArgRegPair : YamlCSInfo.ArgForwardingRegs) {
502 Register Reg;
503 if (parseNamedRegisterReference(PFS, Reg, ArgRegPair.Reg.Value, Error))
504 return error(Error, ArgRegPair.Reg.SourceRange);
505 CSInfo.ArgRegPairs.emplace_back(Reg, ArgRegPair.ArgNo);
506 }
507
508 if (TM.Options.EmitCallSiteInfo)
509 MF.addCallSiteInfo(&*CallI, std::move(CSInfo));
510 }
511
512 if (YamlMF.CallSitesInfo.size() && !TM.Options.EmitCallSiteInfo)
513 return error(Twine("Call site info provided but not used"));
514 return false;
515}
516
517void MIRParserImpl::setupDebugValueTracking(
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((unsigned)MI.peekDebugInstrNum(), 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}, 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
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 {
546 }
547
548 MF.setAlignment(YamlMF.Alignment.valueOrOne());
550 MF.setHasWinCFI(YamlMF.HasWinCFI);
551
555 MF.setHasEHScopes(YamlMF.HasEHScopes);
557 MF.setIsOutlined(YamlMF.IsOutlined);
558
559 if (YamlMF.Legalized)
561 if (YamlMF.RegBankSelected)
562 MF.getProperties().set(
564 if (YamlMF.Selected)
566 if (YamlMF.FailedISel)
568 if (YamlMF.FailsVerification)
569 MF.getProperties().set(
571 if (YamlMF.TracksDebugUserValues)
572 MF.getProperties().set(
574
575 PerFunctionMIParsingState PFS(MF, SM, IRSlots, *Target);
576 if (parseRegisterInfo(PFS, YamlMF))
577 return true;
578 if (!YamlMF.Constants.empty()) {
579 auto *ConstantPool = MF.getConstantPool();
580 assert(ConstantPool && "Constant pool must be created");
581 if (initializeConstantPool(PFS, *ConstantPool, YamlMF))
582 return true;
583 }
584 if (!YamlMF.MachineMetadataNodes.empty() &&
585 parseMachineMetadataNodes(PFS, MF, YamlMF))
586 return true;
587
588 StringRef BlockStr = YamlMF.Body.Value.Value;
590 SourceMgr BlockSM;
591 BlockSM.AddNewSourceBuffer(
592 MemoryBuffer::getMemBuffer(BlockStr, "",/*RequiresNullTerminator=*/false),
593 SMLoc());
594 PFS.SM = &BlockSM;
595 if (parseMachineBasicBlockDefinitions(PFS, BlockStr, Error)) {
597 diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
598 return true;
599 }
600 // Check Basic Block Section Flags.
601 if (MF.hasBBSections()) {
603 }
604 PFS.SM = &SM;
605
606 // Initialize the frame information after creating all the MBBs so that the
607 // MBB references in the frame information can be resolved.
608 if (initializeFrameInfo(PFS, YamlMF))
609 return true;
610 // Initialize the jump table after creating all the MBBs so that the MBB
611 // references can be resolved.
612 if (!YamlMF.JumpTableInfo.Entries.empty() &&
614 return true;
615 // Parse the machine instructions after creating all of the MBBs so that the
616 // parser can resolve the MBB references.
617 StringRef InsnStr = YamlMF.Body.Value.Value;
618 SourceMgr InsnSM;
619 InsnSM.AddNewSourceBuffer(
620 MemoryBuffer::getMemBuffer(InsnStr, "", /*RequiresNullTerminator=*/false),
621 SMLoc());
622 PFS.SM = &InsnSM;
623 if (parseMachineInstructions(PFS, InsnStr, Error)) {
625 diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
626 return true;
627 }
628 PFS.SM = &SM;
629
630 if (setupRegisterInfo(PFS, YamlMF))
631 return true;
632
633 if (YamlMF.MachineFuncInfo) {
634 const TargetMachine &TM = MF.getTarget();
635 // Note this is called after the initial constructor of the
636 // MachineFunctionInfo based on the MachineFunction, which may depend on the
637 // IR.
638
639 SMRange SrcRange;
640 if (TM.parseMachineFunctionInfo(*YamlMF.MachineFuncInfo, PFS, Error,
641 SrcRange)) {
642 return error(Error, SrcRange);
643 }
644 }
645
646 // Set the reserved registers after parsing MachineFuncInfo. The target may
647 // have been recording information used to select the reserved registers
648 // there.
649 // FIXME: This is a temporary workaround until the reserved registers can be
650 // serialized.
652 MRI.freezeReservedRegs();
653
654 if (computeFunctionProperties(MF, YamlMF))
655 return true;
656
657 if (initializeCallSiteInfo(PFS, YamlMF))
658 return true;
659
660 if (parseCalledGlobals(PFS, MF, YamlMF))
661 return true;
662
663 setupDebugValueTracking(MF, PFS, YamlMF);
664
666
667 MF.verify(nullptr, nullptr, &errs());
668 return false;
669}
670
672 const yaml::MachineFunction &YamlMF) {
673 MachineFunction &MF = PFS.MF;
674 MachineRegisterInfo &RegInfo = MF.getRegInfo();
675 assert(RegInfo.tracksLiveness());
676 if (!YamlMF.TracksRegLiveness)
677 RegInfo.invalidateLiveness();
678
680 // Parse the virtual register information.
681 for (const auto &VReg : YamlMF.VirtualRegisters) {
682 VRegInfo &Info = PFS.getVRegInfo(VReg.ID.Value);
683 if (Info.Explicit)
684 return error(VReg.ID.SourceRange.Start,
685 Twine("redefinition of virtual register '%") +
686 Twine(VReg.ID.Value) + "'");
687 Info.Explicit = true;
688
689 if (VReg.Class.Value == "_") {
690 Info.Kind = VRegInfo::GENERIC;
691 Info.D.RegBank = nullptr;
692 } else {
693 const auto *RC = Target->getRegClass(VReg.Class.Value);
694 if (RC) {
695 Info.Kind = VRegInfo::NORMAL;
696 Info.D.RC = RC;
697 } else {
698 const RegisterBank *RegBank = Target->getRegBank(VReg.Class.Value);
699 if (!RegBank)
700 return error(
701 VReg.Class.SourceRange.Start,
702 Twine("use of undefined register class or register bank '") +
703 VReg.Class.Value + "'");
704 Info.Kind = VRegInfo::REGBANK;
705 Info.D.RegBank = RegBank;
706 }
707 }
708
709 if (!VReg.PreferredRegister.Value.empty()) {
710 if (Info.Kind != VRegInfo::NORMAL)
711 return error(VReg.Class.SourceRange.Start,
712 Twine("preferred register can only be set for normal vregs"));
713
714 if (parseRegisterReference(PFS, Info.PreferredReg,
715 VReg.PreferredRegister.Value, Error))
716 return error(Error, VReg.PreferredRegister.SourceRange);
717 }
718
719 for (const auto &FlagStringValue : VReg.RegisterFlags) {
720 uint8_t FlagValue;
721 if (Target->getVRegFlagValue(FlagStringValue.Value, FlagValue))
722 return error(FlagStringValue.SourceRange.Start,
723 Twine("use of undefined register flag '") +
724 FlagStringValue.Value + "'");
725 Info.Flags |= FlagValue;
726 }
727 RegInfo.noteNewVirtualRegister(Info.VReg);
728 }
729
730 // Parse the liveins.
731 for (const auto &LiveIn : YamlMF.LiveIns) {
732 Register Reg;
733 if (parseNamedRegisterReference(PFS, Reg, LiveIn.Register.Value, Error))
734 return error(Error, LiveIn.Register.SourceRange);
735 Register VReg;
736 if (!LiveIn.VirtualRegister.Value.empty()) {
737 VRegInfo *Info;
738 if (parseVirtualRegisterReference(PFS, Info, LiveIn.VirtualRegister.Value,
739 Error))
740 return error(Error, LiveIn.VirtualRegister.SourceRange);
741 VReg = Info->VReg;
742 }
743 RegInfo.addLiveIn(Reg, VReg);
744 }
745
746 // Parse the callee saved registers (Registers that will
747 // be saved for the caller).
748 if (YamlMF.CalleeSavedRegisters) {
749 SmallVector<MCPhysReg, 16> CalleeSavedRegisters;
750 for (const auto &RegSource : *YamlMF.CalleeSavedRegisters) {
751 Register Reg;
752 if (parseNamedRegisterReference(PFS, Reg, RegSource.Value, Error))
753 return error(Error, RegSource.SourceRange);
754 CalleeSavedRegisters.push_back(Reg);
755 }
756 RegInfo.setCalleeSavedRegs(CalleeSavedRegisters);
757 }
758
759 return false;
760}
761
763 const yaml::MachineFunction &YamlMF) {
764 MachineFunction &MF = PFS.MF;
767
768 bool Error = false;
769 // Create VRegs
770 auto populateVRegInfo = [&](const VRegInfo &Info, Twine Name) {
771 Register Reg = Info.VReg;
772 switch (Info.Kind) {
774 error(Twine("Cannot determine class/bank of virtual register ") +
775 Name + " in function '" + MF.getName() + "'");
776 Error = true;
777 break;
778 case VRegInfo::NORMAL:
779 if (!Info.D.RC->isAllocatable()) {
780 error(Twine("Cannot use non-allocatable class '") +
781 TRI->getRegClassName(Info.D.RC) + "' for virtual register " +
782 Name + " in function '" + MF.getName() + "'");
783 Error = true;
784 break;
785 }
786
787 MRI.setRegClass(Reg, Info.D.RC);
788 if (Info.PreferredReg != 0)
789 MRI.setSimpleHint(Reg, Info.PreferredReg);
790 break;
792 break;
794 MRI.setRegBank(Reg, *Info.D.RegBank);
795 break;
796 }
797 };
798
799 for (const auto &P : PFS.VRegInfosNamed) {
800 const VRegInfo &Info = *P.second;
801 populateVRegInfo(Info, Twine(P.first()));
802 }
803
804 for (auto P : PFS.VRegInfos) {
805 const VRegInfo &Info = *P.second;
806 populateVRegInfo(Info, Twine(P.first));
807 }
808
809 // Compute MachineRegisterInfo::UsedPhysRegMask
810 for (const MachineBasicBlock &MBB : MF) {
811 // Make sure MRI knows about registers clobbered by unwinder.
812 if (MBB.isEHPad())
813 if (auto *RegMask = TRI->getCustomEHPadPreservedMask(MF))
814 MRI.addPhysRegsUsedFromRegMask(RegMask);
815
816 for (const MachineInstr &MI : MBB) {
817 for (const MachineOperand &MO : MI.operands()) {
818 if (!MO.isRegMask())
819 continue;
820 MRI.addPhysRegsUsedFromRegMask(MO.getRegMask());
821 }
822 }
823 }
824
825 return Error;
826}
827
829 const yaml::MachineFunction &YamlMF) {
830 MachineFunction &MF = PFS.MF;
831 MachineFrameInfo &MFI = MF.getFrameInfo();
833 const Function &F = MF.getFunction();
834 const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
837 MFI.setHasStackMap(YamlMFI.HasStackMap);
838 MFI.setHasPatchPoint(YamlMFI.HasPatchPoint);
839 MFI.setStackSize(YamlMFI.StackSize);
841 if (YamlMFI.MaxAlignment)
843 MFI.setAdjustsStack(YamlMFI.AdjustsStack);
844 MFI.setHasCalls(YamlMFI.HasCalls);
845 if (YamlMFI.MaxCallFrameSize != ~0u)
849 MFI.setHasVAStart(YamlMFI.HasVAStart);
851 MFI.setHasTailCall(YamlMFI.HasTailCall);
854 if (!YamlMFI.SavePoint.Value.empty()) {
855 MachineBasicBlock *MBB = nullptr;
856 if (parseMBBReference(PFS, MBB, YamlMFI.SavePoint))
857 return true;
858 MFI.setSavePoint(MBB);
859 }
860 if (!YamlMFI.RestorePoint.Value.empty()) {
861 MachineBasicBlock *MBB = nullptr;
862 if (parseMBBReference(PFS, MBB, YamlMFI.RestorePoint))
863 return true;
864 MFI.setRestorePoint(MBB);
865 }
866
867 std::vector<CalleeSavedInfo> CSIInfo;
868 // Initialize the fixed frame objects.
869 for (const auto &Object : YamlMF.FixedStackObjects) {
870 int ObjectIdx;
872 ObjectIdx = MFI.CreateFixedObject(Object.Size, Object.Offset,
873 Object.IsImmutable, Object.IsAliased);
874 else
875 ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
876
877 if (!TFI->isSupportedStackID(Object.StackID))
878 return error(Object.ID.SourceRange.Start,
879 Twine("StackID is not supported by target"));
880 MFI.setStackID(ObjectIdx, Object.StackID);
881 MFI.setObjectAlignment(ObjectIdx, Object.Alignment.valueOrOne());
882 if (!PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID.Value,
883 ObjectIdx))
884 .second)
885 return error(Object.ID.SourceRange.Start,
886 Twine("redefinition of fixed stack object '%fixed-stack.") +
887 Twine(Object.ID.Value) + "'");
888 if (parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister,
889 Object.CalleeSavedRestored, ObjectIdx))
890 return true;
891 if (parseStackObjectsDebugInfo(PFS, Object, ObjectIdx))
892 return true;
893 }
894
895 for (const auto &Object : YamlMF.EntryValueObjects) {
897 Register Reg;
898 if (parseNamedRegisterReference(PFS, Reg, Object.EntryValueRegister.Value,
899 Error))
900 return error(Error, Object.EntryValueRegister.SourceRange);
901 if (!Reg.isPhysical())
902 return error(Object.EntryValueRegister.SourceRange.Start,
903 "Expected physical register for entry value field");
904 std::optional<VarExprLoc> MaybeInfo = parseVarExprLoc(
905 PFS, Object.DebugVar, Object.DebugExpr, Object.DebugLoc);
906 if (!MaybeInfo)
907 return true;
908 if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc)
909 PFS.MF.setVariableDbgInfo(MaybeInfo->DIVar, MaybeInfo->DIExpr,
910 Reg.asMCReg(), MaybeInfo->DILoc);
911 }
912
913 // Initialize the ordinary frame objects.
914 for (const auto &Object : YamlMF.StackObjects) {
915 int ObjectIdx;
916 const AllocaInst *Alloca = nullptr;
917 const yaml::StringValue &Name = Object.Name;
918 if (!Name.Value.empty()) {
919 Alloca = dyn_cast_or_null<AllocaInst>(
920 F.getValueSymbolTable()->lookup(Name.Value));
921 if (!Alloca)
922 return error(Name.SourceRange.Start,
923 "alloca instruction named '" + Name.Value +
924 "' isn't defined in the function '" + F.getName() +
925 "'");
926 }
927 if (!TFI->isSupportedStackID(Object.StackID))
928 return error(Object.ID.SourceRange.Start,
929 Twine("StackID is not supported by target"));
931 ObjectIdx =
932 MFI.CreateVariableSizedObject(Object.Alignment.valueOrOne(), Alloca);
933 else
934 ObjectIdx = MFI.CreateStackObject(
935 Object.Size, Object.Alignment.valueOrOne(),
936 Object.Type == yaml::MachineStackObject::SpillSlot, Alloca,
937 Object.StackID);
938 MFI.setObjectOffset(ObjectIdx, Object.Offset);
939
940 if (!PFS.StackObjectSlots.insert(std::make_pair(Object.ID.Value, ObjectIdx))
941 .second)
942 return error(Object.ID.SourceRange.Start,
943 Twine("redefinition of stack object '%stack.") +
944 Twine(Object.ID.Value) + "'");
945 if (parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister,
946 Object.CalleeSavedRestored, ObjectIdx))
947 return true;
948 if (Object.LocalOffset)
949 MFI.mapLocalFrameObject(ObjectIdx, *Object.LocalOffset);
950 if (parseStackObjectsDebugInfo(PFS, Object, ObjectIdx))
951 return true;
952 }
953 MFI.setCalleeSavedInfo(CSIInfo);
954 if (!CSIInfo.empty())
955 MFI.setCalleeSavedInfoValid(true);
956
957 // Initialize the various stack object references after initializing the
958 // stack objects.
959 if (!YamlMFI.StackProtector.Value.empty()) {
961 int FI;
963 return error(Error, YamlMFI.StackProtector.SourceRange);
965 }
966
967 if (!YamlMFI.FunctionContext.Value.empty()) {
969 int FI;
971 return error(Error, YamlMFI.FunctionContext.SourceRange);
973 }
974
975 return false;
976}
977
979 std::vector<CalleeSavedInfo> &CSIInfo,
980 const yaml::StringValue &RegisterSource, bool IsRestored, int FrameIdx) {
981 if (RegisterSource.Value.empty())
982 return false;
983 Register Reg;
985 if (parseNamedRegisterReference(PFS, Reg, RegisterSource.Value, Error))
986 return error(Error, RegisterSource.SourceRange);
987 CalleeSavedInfo CSI(Reg, FrameIdx);
988 CSI.setRestored(IsRestored);
989 CSIInfo.push_back(CSI);
990 return false;
991}
992
993/// Verify that given node is of a certain type. Return true on error.
994template <typename T>
995static bool typecheckMDNode(T *&Result, MDNode *Node,
996 const yaml::StringValue &Source,
997 StringRef TypeString, MIRParserImpl &Parser) {
998 if (!Node)
999 return false;
1000 Result = dyn_cast<T>(Node);
1001 if (!Result)
1002 return Parser.error(Source.SourceRange.Start,
1003 "expected a reference to a '" + TypeString +
1004 "' metadata node");
1005 return false;
1006}
1007
1008std::optional<MIRParserImpl::VarExprLoc> MIRParserImpl::parseVarExprLoc(
1009 PerFunctionMIParsingState &PFS, const yaml::StringValue &VarStr,
1010 const yaml::StringValue &ExprStr, const yaml::StringValue &LocStr) {
1011 MDNode *Var = nullptr;
1012 MDNode *Expr = nullptr;
1013 MDNode *Loc = nullptr;
1014 if (parseMDNode(PFS, Var, VarStr) || parseMDNode(PFS, Expr, ExprStr) ||
1015 parseMDNode(PFS, Loc, LocStr))
1016 return std::nullopt;
1017 DILocalVariable *DIVar = nullptr;
1018 DIExpression *DIExpr = nullptr;
1019 DILocation *DILoc = nullptr;
1020 if (typecheckMDNode(DIVar, Var, VarStr, "DILocalVariable", *this) ||
1021 typecheckMDNode(DIExpr, Expr, ExprStr, "DIExpression", *this) ||
1022 typecheckMDNode(DILoc, Loc, LocStr, "DILocation", *this))
1023 return std::nullopt;
1024 return VarExprLoc{DIVar, DIExpr, DILoc};
1025}
1026
1027template <typename T>
1029 const T &Object, int FrameIdx) {
1030 std::optional<VarExprLoc> MaybeInfo =
1031 parseVarExprLoc(PFS, Object.DebugVar, Object.DebugExpr, Object.DebugLoc);
1032 if (!MaybeInfo)
1033 return true;
1034 // Debug information can only be attached to stack objects; Fixed stack
1035 // objects aren't supported.
1036 if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc)
1037 PFS.MF.setVariableDbgInfo(MaybeInfo->DIVar, MaybeInfo->DIExpr, FrameIdx,
1038 MaybeInfo->DILoc);
1039 return false;
1040}
1041
1042bool MIRParserImpl::parseMDNode(PerFunctionMIParsingState &PFS,
1043 MDNode *&Node, const yaml::StringValue &Source) {
1044 if (Source.Value.empty())
1045 return false;
1047 if (llvm::parseMDNode(PFS, Node, Source.Value, Error))
1048 return error(Error, Source.SourceRange);
1049 return false;
1050}
1051
1054 DenseMap<unsigned, unsigned> &ConstantPoolSlots = PFS.ConstantPoolSlots;
1055 const MachineFunction &MF = PFS.MF;
1056 const auto &M = *MF.getFunction().getParent();
1058 for (const auto &YamlConstant : YamlMF.Constants) {
1059 if (YamlConstant.IsTargetSpecific)
1060 // FIXME: Support target-specific constant pools
1061 return error(YamlConstant.Value.SourceRange.Start,
1062 "Can't parse target-specific constant pool entries yet");
1063 const Constant *Value = dyn_cast_or_null<Constant>(
1064 parseConstantValue(YamlConstant.Value.Value, Error, M));
1065 if (!Value)
1066 return error(Error, YamlConstant.Value.SourceRange);
1067 const Align PrefTypeAlign =
1068 M.getDataLayout().getPrefTypeAlign(Value->getType());
1069 const Align Alignment = YamlConstant.Alignment.value_or(PrefTypeAlign);
1070 unsigned Index = ConstantPool.getConstantPoolIndex(Value, Alignment);
1071 if (!ConstantPoolSlots.insert(std::make_pair(YamlConstant.ID.Value, Index))
1072 .second)
1073 return error(YamlConstant.ID.SourceRange.Start,
1074 Twine("redefinition of constant pool item '%const.") +
1075 Twine(YamlConstant.ID.Value) + "'");
1076 }
1077 return false;
1078}
1079
1081 const yaml::MachineJumpTable &YamlJTI) {
1083 for (const auto &Entry : YamlJTI.Entries) {
1084 std::vector<MachineBasicBlock *> Blocks;
1085 for (const auto &MBBSource : Entry.Blocks) {
1086 MachineBasicBlock *MBB = nullptr;
1087 if (parseMBBReference(PFS, MBB, MBBSource.Value))
1088 return true;
1089 Blocks.push_back(MBB);
1090 }
1091 unsigned Index = JTI->createJumpTableIndex(Blocks);
1092 if (!PFS.JumpTableSlots.insert(std::make_pair(Entry.ID.Value, Index))
1093 .second)
1094 return error(Entry.ID.SourceRange.Start,
1095 Twine("redefinition of jump table entry '%jump-table.") +
1096 Twine(Entry.ID.Value) + "'");
1097 }
1098 return false;
1099}
1100
1101bool MIRParserImpl::parseMBBReference(PerFunctionMIParsingState &PFS,
1103 const yaml::StringValue &Source) {
1105 if (llvm::parseMBBReference(PFS, MBB, Source.Value, Error))
1106 return error(Error, Source.SourceRange);
1107 return false;
1108}
1109
1110bool MIRParserImpl::parseMachineMetadata(PerFunctionMIParsingState &PFS,
1111 const yaml::StringValue &Source) {
1113 if (llvm::parseMachineMetadata(PFS, Source.Value, Source.SourceRange, Error))
1114 return error(Error, Source.SourceRange);
1115 return false;
1116}
1117
1120 const yaml::MachineFunction &YMF) {
1121 for (const auto &MDS : YMF.MachineMetadataNodes) {
1122 if (parseMachineMetadata(PFS, MDS))
1123 return true;
1124 }
1125 // Report missing definitions from forward referenced nodes.
1126 if (!PFS.MachineForwardRefMDNodes.empty())
1127 return error(PFS.MachineForwardRefMDNodes.begin()->second.second,
1128 "use of undefined metadata '!" +
1129 Twine(PFS.MachineForwardRefMDNodes.begin()->first) + "'");
1130 return false;
1131}
1132
1134 MachineFunction &MF,
1135 const yaml::MachineFunction &YMF) {
1136 Function &F = MF.getFunction();
1137 for (const auto &YamlCG : YMF.CalledGlobals) {
1138 yaml::MachineInstrLoc MILoc = YamlCG.CallSite;
1139 const MachineInstr *CallI;
1140 if (parseMachineInst(MF, MILoc, CallI))
1141 return true;
1143 return error(Twine(MF.getName()) +
1144 Twine(" called global should reference call "
1145 "instruction. Instruction at bb:") +
1146 Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset) +
1147 " is not a call instruction");
1148
1149 auto Callee =
1150 F.getParent()->getValueSymbolTable().lookup(YamlCG.Callee.Value);
1151 if (!Callee)
1152 return error(YamlCG.Callee.SourceRange.Start,
1153 "use of undefined global '" + YamlCG.Callee.Value + "'");
1154 if (!isa<GlobalValue>(Callee))
1155 return error(YamlCG.Callee.SourceRange.Start,
1156 "use of non-global value '" + YamlCG.Callee.Value + "'");
1157
1158 MF.addCalledGlobal(CallI, {cast<GlobalValue>(Callee), YamlCG.Flags});
1159 }
1160
1161 return false;
1162}
1163
1164SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
1165 SMRange SourceRange) {
1166 assert(SourceRange.isValid() && "Invalid source range");
1167 SMLoc Loc = SourceRange.Start;
1168 bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
1169 *Loc.getPointer() == '\'';
1170 // Translate the location of the error from the location in the MI string to
1171 // the corresponding location in the MIR file.
1172 Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +
1173 (HasQuote ? 1 : 0));
1174
1175 // TODO: Translate any source ranges as well.
1176 return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), {},
1177 Error.getFixIts());
1178}
1179
1180SMDiagnostic MIRParserImpl::diagFromBlockStringDiag(const SMDiagnostic &Error,
1181 SMRange SourceRange) {
1182 assert(SourceRange.isValid());
1183
1184 // Translate the location of the error from the location in the llvm IR string
1185 // to the corresponding location in the MIR file.
1186 auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);
1187 unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
1188 unsigned Column = Error.getColumnNo();
1189 StringRef LineStr = Error.getLineContents();
1190 SMLoc Loc = Error.getLoc();
1191
1192 // Get the full line and adjust the column number by taking the indentation of
1193 // LLVM IR into account.
1194 for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;
1195 L != E; ++L) {
1196 if (L.line_number() == Line) {
1197 LineStr = *L;
1198 Loc = SMLoc::getFromPointer(LineStr.data());
1199 auto Indent = LineStr.find(Error.getLineContents());
1200 if (Indent != StringRef::npos)
1201 Column += Indent;
1202 break;
1203 }
1204 }
1205
1206 return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
1207 Error.getMessage(), LineStr, Error.getRanges(),
1208 Error.getFixIts());
1209}
1210
1211MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
1212 : Impl(std::move(Impl)) {}
1213
1214MIRParser::~MIRParser() = default;
1215
1216std::unique_ptr<Module>
1218 return Impl->parseIRModule(DataLayoutCallback);
1219}
1220
1222 return Impl->parseMachineFunctions(M, MMI);
1223}
1224
1226 auto &MMI = MAM.getResult<MachineModuleAnalysis>(M).getMMI();
1227 return Impl->parseMachineFunctions(M, MMI, &MAM);
1228}
1229
1230std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(
1231 StringRef Filename, SMDiagnostic &Error, LLVMContext &Context,
1232 std::function<void(Function &)> ProcessIRFunction) {
1233 auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
1234 if (std::error_code EC = FileOrErr.getError()) {
1236 "Could not open input file: " + EC.message());
1237 return nullptr;
1238 }
1239 return createMIRParser(std::move(FileOrErr.get()), Context,
1240 ProcessIRFunction);
1241}
1242
1243std::unique_ptr<MIRParser>
1244llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
1245 LLVMContext &Context,
1246 std::function<void(Function &)> ProcessIRFunction) {
1247 auto Filename = Contents->getBufferIdentifier();
1248 if (Context.shouldDiscardValueNames()) {
1250 DS_Error,
1252 Filename, SourceMgr::DK_Error,
1253 "Can't read MIR with a Context that discards named Values")));
1254 return nullptr;
1255 }
1256 return std::make_unique<MIRParser>(std::make_unique<MIRParserImpl>(
1257 std::move(Contents), Filename, Context, ProcessIRFunction));
1258}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
This file defines the DenseMap class.
std::string Name
DenseMap< Block *, BlockRelaxAux > Blocks
Definition: ELF_riscv.cpp:507
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
static bool isSSA(const MachineFunction &MF)
Definition: MIRParser.cpp:368
static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context)
Definition: MIRParser.cpp:196
static bool typecheckMDNode(T *&Result, MDNode *Node, const yaml::StringValue &Source, StringRef TypeString, MIRParserImpl &Parser)
Verify that given node is of a certain type. Return true on error.
Definition: MIRParser.cpp:995
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
unsigned const TargetRegisterInfo * TRI
#define P(N)
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
#define error(X)
an instruction to allocate memory on the stack
Definition: Instructions.h:63
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
Definition: PassManager.h:429
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:410
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:212
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
This is an important base class in LLVM.
Definition: Constant.h:42
DWARF expression.
Debug location.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:211
Diagnostic information for machine IR parser.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:173
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:656
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:52
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:567
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
bool shouldDiscardValueNames() const
Return true if the Context runtime configuration is set to discard all value names.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Metadata node.
Definition: Metadata.h:1069
This class implements the parsing of LLVM IR that's embedded inside a MIR file.
Definition: MIRParser.cpp:51
bool error(const Twine &Message)
Report an error with the given message at unknown location.
Definition: MIRParser.cpp:211
void reportDiagnostic(const SMDiagnostic &Diag)
Definition: MIRParser.cpp:229
bool setupRegisterInfo(const PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF)
Definition: MIRParser.cpp:762
bool parseRegisterInfo(PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF)
Definition: MIRParser.cpp:671
bool initializeFrameInfo(PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF)
Definition: MIRParser.cpp:828
Function * createDummyFunction(StringRef Name, Module &M)
Create an empty function with the given name.
Definition: MIRParser.cpp:303
bool parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS, const T &Object, int FrameIdx)
Definition: MIRParser.cpp:1028
bool initializeMachineFunction(const yaml::MachineFunction &YamlMF, MachineFunction &MF)
Initialize the machine function to the state that's described in the MIR file.
Definition: MIRParser.cpp:538
std::unique_ptr< Module > parseIRModule(DataLayoutCallbackTy DataLayoutCallback)
Try to parse the optional LLVM module and the machine functions in the MIR file.
Definition: MIRParser.cpp:249
bool initializeJumpTableInfo(PerFunctionMIParsingState &PFS, const yaml::MachineJumpTable &YamlJTI)
Definition: MIRParser.cpp:1080
bool initializeConstantPool(PerFunctionMIParsingState &PFS, MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF)
Definition: MIRParser.cpp:1052
MIRParserImpl(std::unique_ptr< MemoryBuffer > Contents, StringRef Filename, LLVMContext &Context, std::function< void(Function &)> ProcessIRFunction)
Definition: MIRParser.cpp:200
std::optional< VarExprLoc > parseVarExprLoc(PerFunctionMIParsingState &PFS, const yaml::StringValue &VarStr, const yaml::StringValue &ExprStr, const yaml::StringValue &LocStr)
Definition: MIRParser.cpp:1008
bool parseCalledGlobals(PerFunctionMIParsingState &PFS, MachineFunction &MF, const yaml::MachineFunction &YMF)
Definition: MIRParser.cpp:1133
bool parseCalleeSavedRegister(PerFunctionMIParsingState &PFS, std::vector< CalleeSavedInfo > &CSIInfo, const yaml::StringValue &RegisterSource, bool IsRestored, int FrameIdx)
Definition: MIRParser.cpp:978
bool parseMachineMetadataNodes(PerFunctionMIParsingState &PFS, MachineFunction &MF, const yaml::MachineFunction &YMF)
Definition: MIRParser.cpp:1118
bool initializeCallSiteInfo(PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF)
Definition: MIRParser.cpp:484
bool parseMachineFunction(Module &M, MachineModuleInfo &MMI, ModuleAnalysisManager *FAM)
Parse the machine function in the current YAML document.
Definition: MIRParser.cpp:317
bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI, ModuleAnalysisManager *FAM=nullptr)
Definition: MIRParser.cpp:288
MIRParser(std::unique_ptr< MIRParserImpl > Impl)
Definition: MIRParser.cpp:1211
std::unique_ptr< Module > parseIRModule(DataLayoutCallbackTy DataLayoutCallback=[](StringRef, StringRef) { return std::nullopt;})
Parses the optional LLVM IR module in the MIR file.
Definition: MIRParser.cpp:1217
bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI)
Parses MachineFunctions in the MIR file and add them to the given MachineModuleInfo MMI.
Definition: MIRParser.cpp:1221
bool isEHPad() const
Returns true if the block is a landing pad.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
void setRestorePoint(MachineBasicBlock *NewRestore)
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void ensureMaxAlignment(Align Alignment)
Make sure the function is at least Align bytes aligned.
void setHasPatchPoint(bool s=true)
void setLocalFrameSize(int64_t sz)
Set the size of the local object blob.
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
void setFrameAddressIsTaken(bool T)
void setHasStackMap(bool s=true)
void setCVBytesOfCalleeSavedRegisters(unsigned S)
void setStackID(int ObjectIdx, uint8_t ID)
void setHasTailCall(bool V=true)
void setStackProtectorIndex(int I)
void setCalleeSavedInfoValid(bool v)
void setReturnAddressIsTaken(bool s)
void mapLocalFrameObject(int ObjectIndex, int64_t Offset)
Map a frame index into the local object block.
void setHasOpaqueSPAdjustment(bool B)
void setCalleeSavedInfo(std::vector< CalleeSavedInfo > CSI)
Used by prolog/epilog inserter to set the function's callee saved information.
int CreateVariableSizedObject(Align Alignment, const AllocaInst *Alloca)
Notify the MachineFrameInfo object that a variable sized object has been created.
void setSavePoint(MachineBasicBlock *NewSave)
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
void setStackSize(uint64_t Size)
Set the size of the stack.
void setHasMustTailInVarArgFunc(bool B)
void setObjectAlignment(int ObjectIdx, Align Alignment)
setObjectAlignment - Change the alignment of the specified stack object.
void setOffsetAdjustment(int64_t Adj)
Set the correction for frame offsets.
void setFunctionContextIndex(int I)
This analysis create MachineFunction for given Function.
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
MachineFunctionProperties & reset(Property P)
void setCallsUnwindInit(bool b)
void setHasEHFunclets(bool V)
void setExposesReturnsTwice(bool B)
setCallsSetJmp - Set a flag that indicates if there's a call to a "returns twice" function.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineJumpTableInfo * getOrCreateJumpTableInfo(unsigned JTEntryKind)
getOrCreateJumpTableInfo - Get the JumpTableInfo for this function, if it does already exist,...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
void setHasEHCatchret(bool V)
void setCallsEHReturn(bool b)
void setAlignment(Align A)
setAlignment - Set the alignment of the function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
bool hasBBSections() const
Returns true if this function has basic block sections enabled.
unsigned size() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool verify(Pass *p=nullptr, const char *Banner=nullptr, raw_ostream *OS=nullptr, bool AbortOnError=true) const
Run the current MachineFunction through the machine code verifier, useful for debugger use.
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
void addCallSiteInfo(const MachineInstr *CallI, CallSiteInfo &&CallInfo)
Start tracking the arguments passed to the call CallI.
const MachineFunctionProperties & getProperties() const
Get the function properties.
void setVariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr, int Slot, const DILocation *Loc)
Collect information used to emit debugging information of a variable in a stack slot.
void addCalledGlobal(const MachineInstr *MI, CalledGlobalInfo Details)
Notes the global and target flags for a call site.
void assignBeginEndSections()
Assign IsBeginSection IsEndSection fields for basic blocks in this function.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
Definition: MachineInstr.h:69
bool isCall(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:956
unsigned createJumpTableIndex(const std::vector< MachineBasicBlock * > &DestBBs)
createJumpTableIndex - Create a new jump table.
An analysis that produces MachineModuleInfo for a module.
This class contains meta information specific to a module.
MachineFunction & getOrCreateMachineFunction(Function &F)
Returns the MachineFunction constructed for the IR function F.
const TargetMachine & getTarget() const
MachineFunction * getMachineFunction(const Function &F) const
Returns the MachineFunction associated to IR function F if there is one, otherwise nullptr.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
Register getReg() const
getReg - Returns the register number.
const uint32_t * getRegMask() const
getRegMask - Returns a bit mask of registers preserved by this RegMask operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool tracksLiveness() const
tracksLiveness - Returns true when tracking register liveness accurately.
void invalidateLiveness()
invalidateLiveness - Indicates that register liveness is no longer being tracked accurately.
void noteNewVirtualRegister(Register Reg)
void setCalleeSavedRegs(ArrayRef< MCPhysReg > CSRs)
Sets the updated Callee Saved Registers list.
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
This class implements the register bank concept.
Definition: RegisterBank.h:28
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition: Register.h:84
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition: SourceMgr.h:281
SourceMgr::DiagKind getKind() const
Definition: SourceMgr.h:310
Represents a location in source code.
Definition: SMLoc.h:23
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
constexpr const char * getPointer() const
Definition: SMLoc.h:34
Represents a range in source code.
Definition: SMLoc.h:48
bool isValid() const
Definition: SMLoc.h:59
SMLoc Start
Definition: SMLoc.h:50
SMLoc End
Definition: SMLoc.h:50
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
Definition: SourceMgr.h:31
unsigned getMainFileID() const
Definition: SourceMgr.h:132
std::pair< unsigned, unsigned > getLineAndColumn(SMLoc Loc, unsigned BufferID=0) const
Find the line and column number for the specified location in the specified file.
Definition: SourceMgr.cpp:192
const MemoryBuffer * getMemoryBuffer(unsigned i) const
Definition: SourceMgr.h:125
SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges={}, ArrayRef< SMFixIt > FixIts={}) const
Return an SMDiagnostic at the specified location with the specified string.
Definition: SourceMgr.cpp:274
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
Definition: SourceMgr.h:144
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:144
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:297
static constexpr size_t npos
Definition: StringRef.h:53
Information about stack frame layout on the target.
virtual bool isSupportedStackID(TargetStackID::Value ID) const
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual void mirFileLoaded(MachineFunction &MF) const
This is called after a .mir file was loaded.
virtual const TargetFrameLowering * getFrameLowering() const
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:17
static Type * getVoidTy(LLVMContext &C)
This function has undefined behavior.
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
An efficient, type-erasing, non-owning reference to a callable.
A forward iterator which reads text lines from a buffer.
Definition: LineIterator.h:33
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool parseStackObjectReference(PerFunctionMIParsingState &PFS, int &FI, StringRef Src, SMDiagnostic &Error)
Definition: MIParser.cpp:3620
bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node, StringRef Src, SMDiagnostic &Error)
Definition: MIParser.cpp:3626
bool parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS, StringRef Src, SMDiagnostic &Error)
Parse the machine basic block definitions, and skip the machine instructions.
Definition: MIParser.cpp:3585
bool parseMBBReference(PerFunctionMIParsingState &PFS, MachineBasicBlock *&MBB, StringRef Src, SMDiagnostic &Error)
Definition: MIParser.cpp:3596
std::unique_ptr< MIRParser > createMIRParserFromFile(StringRef Filename, SMDiagnostic &Error, LLVMContext &Context, std::function< void(Function &)> ProcessIRFunction=nullptr)
This function is the main interface to the MIR serialization format parser.
Definition: MIRParser.cpp:1230
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
std::unique_ptr< MIRParser > createMIRParser(std::unique_ptr< MemoryBuffer > Contents, LLVMContext &Context, std::function< void(Function &)> ProcessIRFunction=nullptr)
This function is another interface to the MIR serialization format parser.
Definition: MIRParser.cpp:1244
std::unique_ptr< Module > parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, SlotMapping *Slots=nullptr, DataLayoutCallbackTy DataLayoutCallback=[](StringRef, StringRef) { return std::nullopt;})
parseAssemblyFile and parseAssemblyString are wrappers around this function.
Definition: Parser.cpp:47
bool parseMachineInstructions(PerFunctionMIParsingState &PFS, StringRef Src, SMDiagnostic &Error)
Parse the machine instructions.
Definition: MIParser.cpp:3591
bool parseRegisterReference(PerFunctionMIParsingState &PFS, Register &Reg, StringRef Src, SMDiagnostic &Error)
Definition: MIParser.cpp:3602
Constant * parseConstantValue(StringRef Asm, SMDiagnostic &Err, const Module &M, const SlotMapping *Slots=nullptr)
Parse a type and a constant value in the given string.
Definition: Parser.cpp:188
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1873
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
@ DS_Warning
@ DS_Error
bool parseMachineMetadata(PerFunctionMIParsingState &PFS, StringRef Src, SMRange SourceRange, SMDiagnostic &Error)
Definition: MIParser.cpp:3631
bool parseVirtualRegisterReference(PerFunctionMIParsingState &PFS, VRegInfo *&Info, StringRef Src, SMDiagnostic &Error)
Definition: MIParser.cpp:3614
bool parseNamedRegisterReference(PerFunctionMIParsingState &PFS, Register &Reg, StringRef Src, SMDiagnostic &Error)
Definition: MIParser.cpp:3608
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
SmallVector< ArgRegPair, 1 > ArgRegPairs
Vector of call argument and its forwarding register.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition: Alignment.h:141
DenseMap< unsigned, unsigned > JumpTableSlots
Definition: MIParser.h:181
VRegInfo & getVRegInfo(Register Num)
Definition: MIParser.cpp:329
DenseMap< unsigned, int > FixedStackObjectSlots
Definition: MIParser.h:178
DenseMap< unsigned, unsigned > ConstantPoolSlots
Definition: MIParser.h:180
StringMap< VRegInfo * > VRegInfosNamed
Definition: MIParser.h:177
DenseMap< unsigned, int > StackObjectSlots
Definition: MIParser.h:179
std::map< unsigned, std::pair< TempMDTuple, SMLoc > > MachineForwardRefMDNodes
Definition: MIParser.h:173
DenseMap< Register, VRegInfo * > VRegInfos
Definition: MIParser.h:176
This struct contains the mappings from the slot numbers to unnamed metadata nodes,...
Definition: SlotMapping.h:33
Serializable representation of MachineFrameInfo.
unsigned MaxCallFrameSize
~0u means: not computed yet.
std::vector< MachineStackObject > StackObjects
std::vector< StringValue > MachineMetadataNodes
std::optional< std::vector< FlowStringValue > > CalleeSavedRegisters
std::vector< CalledGlobal > CalledGlobals
std::optional< bool > HasFakeUses
std::vector< EntryValueObject > EntryValueObjects
std::optional< bool > NoPHIs
std::vector< MachineConstantPoolValue > Constants
std::optional< bool > NoVRegs
std::vector< CallSiteInfo > CallSitesInfo
std::vector< MachineFunctionLiveIn > LiveIns
std::vector< VirtualRegisterDefinition > VirtualRegisters
std::vector< FixedMachineStackObject > FixedStackObjects
std::optional< bool > IsSSA
std::vector< DebugValueSubstitution > DebugValueSubstitutions
std::unique_ptr< MachineFunctionInfo > MachineFuncInfo
Constant pool.
MachineJumpTable JumpTableInfo
Identifies call instruction location in machine function.
std::vector< Entry > Entries
MachineJumpTableInfo::JTEntryKind Kind
A wrapper around std::string which contains a source range that's being set during parsing.