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
161private:
162 bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node,
163 const yaml::StringValue &Source);
164
165 bool parseMBBReference(PerFunctionMIParsingState &PFS,
167 const yaml::StringValue &Source);
168
169 bool parseMachineMetadata(PerFunctionMIParsingState &PFS,
170 const yaml::StringValue &Source);
171
172 /// Return a MIR diagnostic converted from an MI string diagnostic.
173 SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
174 SMRange SourceRange);
175
176 /// Return a MIR diagnostic converted from a diagnostic located in a YAML
177 /// block scalar string.
178 SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error,
179 SMRange SourceRange);
180
181 bool computeFunctionProperties(MachineFunction &MF,
182 const yaml::MachineFunction &YamlMF);
183
184 void setupDebugValueTracking(MachineFunction &MF,
186};
187
188} // end namespace llvm
189
190static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
191 reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
192}
193
194MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
195 StringRef Filename, LLVMContext &Context,
196 std::function<void(Function &)> Callback)
197 : Context(Context),
198 In(SM.getMemoryBuffer(SM.AddNewSourceBuffer(std::move(Contents), SMLoc()))
199 ->getBuffer(),
200 nullptr, handleYAMLDiag, this),
201 Filename(Filename), ProcessIRFunction(Callback) {
202 In.setContext(&In);
203}
204
205bool MIRParserImpl::error(const Twine &Message) {
207 DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str())));
208 return true;
209}
210
211bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) {
213 DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message)));
214 return true;
215}
216
218 assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error");
219 reportDiagnostic(diagFromMIStringDiag(Error, SourceRange));
220 return true;
221}
222
225 switch (Diag.getKind()) {
227 Kind = DS_Error;
228 break;
230 Kind = DS_Warning;
231 break;
233 Kind = DS_Note;
234 break;
236 llvm_unreachable("remark unexpected");
237 break;
238 }
239 Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));
240}
241
242std::unique_ptr<Module>
244 if (!In.setCurrentDocument()) {
245 if (In.error())
246 return nullptr;
247 // Create an empty module when the MIR file is empty.
248 NoMIRDocuments = true;
249 auto M = std::make_unique<Module>(Filename, Context);
250 if (auto LayoutOverride =
251 DataLayoutCallback(M->getTargetTriple(), M->getDataLayoutStr()))
252 M->setDataLayout(*LayoutOverride);
253 return M;
254 }
255
256 std::unique_ptr<Module> M;
257 // Parse the block scalar manually so that we can return unique pointer
258 // without having to go trough YAML traits.
259 if (const auto *BSN =
260 dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
262 M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
263 Context, &IRSlots, DataLayoutCallback);
264 if (!M) {
265 reportDiagnostic(diagFromBlockStringDiag(Error, BSN->getSourceRange()));
266 return nullptr;
267 }
268 In.nextDocument();
269 if (!In.setCurrentDocument())
270 NoMIRDocuments = true;
271 } else {
272 // Create an new, empty module.
273 M = std::make_unique<Module>(Filename, Context);
274 if (auto LayoutOverride =
275 DataLayoutCallback(M->getTargetTriple(), M->getDataLayoutStr()))
276 M->setDataLayout(*LayoutOverride);
277 NoLLVMIR = true;
278 }
279 return M;
280}
281
284 if (NoMIRDocuments)
285 return false;
286
287 // Parse the machine functions.
288 do {
289 if (parseMachineFunction(M, MMI, MAM))
290 return true;
291 In.nextDocument();
292 } while (In.setCurrentDocument());
293
294 return false;
295}
296
298 auto &Context = M.getContext();
299 Function *F =
302 BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
303 new UnreachableInst(Context, BB);
304
305 if (ProcessIRFunction)
306 ProcessIRFunction(*F);
307
308 return F;
309}
310
313 // Parse the yaml.
315 yaml::EmptyContext Ctx;
316
317 const TargetMachine &TM = MMI.getTarget();
318 YamlMF.MachineFuncInfo = std::unique_ptr<yaml::MachineFunctionInfo>(
319 TM.createDefaultFuncInfoYAML());
320
321 yaml::yamlize(In, YamlMF, false, Ctx);
322 if (In.error())
323 return true;
324
325 // Search for the corresponding IR function.
326 StringRef FunctionName = YamlMF.Name;
327 Function *F = M.getFunction(FunctionName);
328 if (!F) {
329 if (NoLLVMIR) {
330 F = createDummyFunction(FunctionName, M);
331 } else {
332 return error(Twine("function '") + FunctionName +
333 "' isn't defined in the provided LLVM IR");
334 }
335 }
336
337 if (!MAM) {
338 if (MMI.getMachineFunction(*F) != nullptr)
339 return error(Twine("redefinition of machine function '") + FunctionName +
340 "'");
341
342 // Create the MachineFunction.
344 if (initializeMachineFunction(YamlMF, MF))
345 return true;
346 } else {
347 auto &FAM =
350 return error(Twine("redefinition of machine function '") + FunctionName +
351 "'");
352
353 // Create the MachineFunction.
355 if (initializeMachineFunction(YamlMF, MF))
356 return true;
357 }
358
359 return false;
360}
361
362static bool isSSA(const MachineFunction &MF) {
363 const MachineRegisterInfo &MRI = MF.getRegInfo();
364 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
366 if (!MRI.hasOneDef(Reg) && !MRI.def_empty(Reg))
367 return false;
368
369 // Subregister defs are invalid in SSA.
370 const MachineOperand *RegDef = MRI.getOneDef(Reg);
371 if (RegDef && RegDef->getSubReg() != 0)
372 return false;
373 }
374 return true;
375}
376
377bool MIRParserImpl::computeFunctionProperties(
378 MachineFunction &MF, const yaml::MachineFunction &YamlMF) {
379 MachineFunctionProperties &Properties = MF.getProperties();
380
381 bool HasPHI = false;
382 bool HasInlineAsm = false;
383 bool HasFakeUses = false;
384 bool AllTiedOpsRewritten = true, HasTiedOps = false;
385 for (const MachineBasicBlock &MBB : MF) {
386 for (const MachineInstr &MI : MBB) {
387 if (MI.isPHI())
388 HasPHI = true;
389 if (MI.isInlineAsm())
390 HasInlineAsm = true;
391 if (MI.isFakeUse())
392 HasFakeUses = true;
393 for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
394 const MachineOperand &MO = MI.getOperand(I);
395 if (!MO.isReg() || !MO.getReg())
396 continue;
397 unsigned DefIdx;
398 if (MO.isUse() && MI.isRegTiedToDefOperand(I, &DefIdx)) {
399 HasTiedOps = true;
400 if (MO.getReg() != MI.getOperand(DefIdx).getReg())
401 AllTiedOpsRewritten = false;
402 }
403 }
404 }
405 }
406
407 // Helper function to sanity-check and set properties that are computed, but
408 // may be explicitly set from the input MIR
409 auto ComputedPropertyHelper =
410 [&Properties](std::optional<bool> ExplicitProp, bool ComputedProp,
412 // Prefer explicitly given values over the computed properties
413 if (ExplicitProp.value_or(ComputedProp))
414 Properties.set(P);
415 else
416 Properties.reset(P);
417
418 // Check for conflict between the explicit values and the computed ones
419 return ExplicitProp && *ExplicitProp && !ComputedProp;
420 };
421
422 if (ComputedPropertyHelper(YamlMF.NoPHIs, !HasPHI,
424 return error(MF.getName() +
425 " has explicit property NoPhi, but contains at least one PHI");
426 }
427
428 MF.setHasInlineAsm(HasInlineAsm);
429
430 if (HasTiedOps && AllTiedOpsRewritten)
432
433 if (ComputedPropertyHelper(YamlMF.IsSSA, isSSA(MF),
435 return error(MF.getName() +
436 " has explicit property IsSSA, but is not valid SSA");
437 }
438
439 const MachineRegisterInfo &MRI = MF.getRegInfo();
440 if (ComputedPropertyHelper(YamlMF.NoVRegs, MRI.getNumVirtRegs() == 0,
442 return error(
443 MF.getName() +
444 " has explicit property NoVRegs, but contains virtual registers");
445 }
446
447 // For hasFakeUses we follow similar logic to the ComputedPropertyHelper,
448 // except for caring about the inverse case only, i.e. when the property is
449 // explicitly set to false and Fake Uses are present; having HasFakeUses=true
450 // on a function without fake uses is harmless.
451 if (YamlMF.HasFakeUses && !*YamlMF.HasFakeUses && HasFakeUses)
452 return error(
453 MF.getName() +
454 " has explicit property hasFakeUses=false, but contains fake uses");
455 MF.setHasFakeUses(YamlMF.HasFakeUses.value_or(HasFakeUses));
456
457 return false;
458}
459
462 MachineFunction &MF = PFS.MF;
464 const TargetMachine &TM = MF.getTarget();
465 for (auto &YamlCSInfo : YamlMF.CallSitesInfo) {
466 yaml::CallSiteInfo::MachineInstrLoc MILoc = YamlCSInfo.CallLocation;
467 if (MILoc.BlockNum >= MF.size())
468 return error(Twine(MF.getName()) +
469 Twine(" call instruction block out of range.") +
470 " Unable to reference bb:" + Twine(MILoc.BlockNum));
471 auto CallB = std::next(MF.begin(), MILoc.BlockNum);
472 if (MILoc.Offset >= CallB->size())
473 return error(Twine(MF.getName()) +
474 Twine(" call instruction offset out of range.") +
475 " Unable to reference instruction at bb: " +
476 Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset));
477 auto CallI = std::next(CallB->instr_begin(), MILoc.Offset);
478 if (!CallI->isCall(MachineInstr::IgnoreBundle))
479 return error(Twine(MF.getName()) +
480 Twine(" call site info should reference call "
481 "instruction. Instruction at bb:") +
482 Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset) +
483 " is not a call instruction");
485 for (auto ArgRegPair : YamlCSInfo.ArgForwardingRegs) {
486 Register Reg;
487 if (parseNamedRegisterReference(PFS, Reg, ArgRegPair.Reg.Value, Error))
488 return error(Error, ArgRegPair.Reg.SourceRange);
489 CSInfo.ArgRegPairs.emplace_back(Reg, ArgRegPair.ArgNo);
490 }
491
492 if (TM.Options.EmitCallSiteInfo)
493 MF.addCallSiteInfo(&*CallI, std::move(CSInfo));
494 }
495
496 if (YamlMF.CallSitesInfo.size() && !TM.Options.EmitCallSiteInfo)
497 return error(Twine("Call site info provided but not used"));
498 return false;
499}
500
501void MIRParserImpl::setupDebugValueTracking(
503 const yaml::MachineFunction &YamlMF) {
504 // Compute the value of the "next instruction number" field.
505 unsigned MaxInstrNum = 0;
506 for (auto &MBB : MF)
507 for (auto &MI : MBB)
508 MaxInstrNum = std::max((unsigned)MI.peekDebugInstrNum(), MaxInstrNum);
509 MF.setDebugInstrNumberingCount(MaxInstrNum);
510
511 // Load any substitutions.
512 for (const auto &Sub : YamlMF.DebugValueSubstitutions) {
513 MF.makeDebugValueSubstitution({Sub.SrcInst, Sub.SrcOp},
514 {Sub.DstInst, Sub.DstOp}, Sub.Subreg);
515 }
516
517 // Flag for whether we're supposed to be using DBG_INSTR_REF.
518 MF.setUseDebugInstrRef(YamlMF.UseDebugInstrRef);
519}
520
521bool
523 MachineFunction &MF) {
524 // TODO: Recreate the machine function.
525 if (Target) {
526 // Avoid clearing state if we're using the same subtarget again.
527 Target->setTarget(MF.getSubtarget());
528 } else {
530 }
531
532 MF.setAlignment(YamlMF.Alignment.valueOrOne());
534 MF.setHasWinCFI(YamlMF.HasWinCFI);
535
539 MF.setHasEHScopes(YamlMF.HasEHScopes);
541 MF.setIsOutlined(YamlMF.IsOutlined);
542
543 if (YamlMF.Legalized)
545 if (YamlMF.RegBankSelected)
546 MF.getProperties().set(
548 if (YamlMF.Selected)
550 if (YamlMF.FailedISel)
552 if (YamlMF.FailsVerification)
553 MF.getProperties().set(
555 if (YamlMF.TracksDebugUserValues)
556 MF.getProperties().set(
558
559 PerFunctionMIParsingState PFS(MF, SM, IRSlots, *Target);
560 if (parseRegisterInfo(PFS, YamlMF))
561 return true;
562 if (!YamlMF.Constants.empty()) {
563 auto *ConstantPool = MF.getConstantPool();
564 assert(ConstantPool && "Constant pool must be created");
565 if (initializeConstantPool(PFS, *ConstantPool, YamlMF))
566 return true;
567 }
568 if (!YamlMF.MachineMetadataNodes.empty() &&
569 parseMachineMetadataNodes(PFS, MF, YamlMF))
570 return true;
571
572 StringRef BlockStr = YamlMF.Body.Value.Value;
574 SourceMgr BlockSM;
575 BlockSM.AddNewSourceBuffer(
576 MemoryBuffer::getMemBuffer(BlockStr, "",/*RequiresNullTerminator=*/false),
577 SMLoc());
578 PFS.SM = &BlockSM;
579 if (parseMachineBasicBlockDefinitions(PFS, BlockStr, Error)) {
581 diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
582 return true;
583 }
584 // Check Basic Block Section Flags.
585 if (MF.hasBBSections()) {
587 }
588 PFS.SM = &SM;
589
590 // Initialize the frame information after creating all the MBBs so that the
591 // MBB references in the frame information can be resolved.
592 if (initializeFrameInfo(PFS, YamlMF))
593 return true;
594 // Initialize the jump table after creating all the MBBs so that the MBB
595 // references can be resolved.
596 if (!YamlMF.JumpTableInfo.Entries.empty() &&
598 return true;
599 // Parse the machine instructions after creating all of the MBBs so that the
600 // parser can resolve the MBB references.
601 StringRef InsnStr = YamlMF.Body.Value.Value;
602 SourceMgr InsnSM;
603 InsnSM.AddNewSourceBuffer(
604 MemoryBuffer::getMemBuffer(InsnStr, "", /*RequiresNullTerminator=*/false),
605 SMLoc());
606 PFS.SM = &InsnSM;
607 if (parseMachineInstructions(PFS, InsnStr, Error)) {
609 diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
610 return true;
611 }
612 PFS.SM = &SM;
613
614 if (setupRegisterInfo(PFS, YamlMF))
615 return true;
616
617 if (YamlMF.MachineFuncInfo) {
618 const TargetMachine &TM = MF.getTarget();
619 // Note this is called after the initial constructor of the
620 // MachineFunctionInfo based on the MachineFunction, which may depend on the
621 // IR.
622
623 SMRange SrcRange;
624 if (TM.parseMachineFunctionInfo(*YamlMF.MachineFuncInfo, PFS, Error,
625 SrcRange)) {
626 return error(Error, SrcRange);
627 }
628 }
629
630 // Set the reserved registers after parsing MachineFuncInfo. The target may
631 // have been recording information used to select the reserved registers
632 // there.
633 // FIXME: This is a temporary workaround until the reserved registers can be
634 // serialized.
636 MRI.freezeReservedRegs();
637
638 if (computeFunctionProperties(MF, YamlMF))
639 return true;
640
641 if (initializeCallSiteInfo(PFS, YamlMF))
642 return true;
643
644 setupDebugValueTracking(MF, PFS, YamlMF);
645
647
648 MF.verify(nullptr, nullptr, &errs());
649 return false;
650}
651
653 const yaml::MachineFunction &YamlMF) {
654 MachineFunction &MF = PFS.MF;
655 MachineRegisterInfo &RegInfo = MF.getRegInfo();
656 assert(RegInfo.tracksLiveness());
657 if (!YamlMF.TracksRegLiveness)
658 RegInfo.invalidateLiveness();
659
661 // Parse the virtual register information.
662 for (const auto &VReg : YamlMF.VirtualRegisters) {
663 VRegInfo &Info = PFS.getVRegInfo(VReg.ID.Value);
664 if (Info.Explicit)
665 return error(VReg.ID.SourceRange.Start,
666 Twine("redefinition of virtual register '%") +
667 Twine(VReg.ID.Value) + "'");
668 Info.Explicit = true;
669
670 if (VReg.Class.Value == "_") {
671 Info.Kind = VRegInfo::GENERIC;
672 Info.D.RegBank = nullptr;
673 } else {
674 const auto *RC = Target->getRegClass(VReg.Class.Value);
675 if (RC) {
676 Info.Kind = VRegInfo::NORMAL;
677 Info.D.RC = RC;
678 } else {
679 const RegisterBank *RegBank = Target->getRegBank(VReg.Class.Value);
680 if (!RegBank)
681 return error(
682 VReg.Class.SourceRange.Start,
683 Twine("use of undefined register class or register bank '") +
684 VReg.Class.Value + "'");
685 Info.Kind = VRegInfo::REGBANK;
686 Info.D.RegBank = RegBank;
687 }
688 }
689
690 if (!VReg.PreferredRegister.Value.empty()) {
691 if (Info.Kind != VRegInfo::NORMAL)
692 return error(VReg.Class.SourceRange.Start,
693 Twine("preferred register can only be set for normal vregs"));
694
695 if (parseRegisterReference(PFS, Info.PreferredReg,
696 VReg.PreferredRegister.Value, Error))
697 return error(Error, VReg.PreferredRegister.SourceRange);
698 }
699
700 for (const auto &FlagStringValue : VReg.RegisterFlags) {
701 uint8_t FlagValue;
702 if (Target->getVRegFlagValue(FlagStringValue.Value, FlagValue))
703 return error(FlagStringValue.SourceRange.Start,
704 Twine("use of undefined register flag '") +
705 FlagStringValue.Value + "'");
706 Info.Flags |= FlagValue;
707 }
708 RegInfo.noteNewVirtualRegister(Info.VReg);
709 }
710
711 // Parse the liveins.
712 for (const auto &LiveIn : YamlMF.LiveIns) {
713 Register Reg;
714 if (parseNamedRegisterReference(PFS, Reg, LiveIn.Register.Value, Error))
715 return error(Error, LiveIn.Register.SourceRange);
716 Register VReg;
717 if (!LiveIn.VirtualRegister.Value.empty()) {
718 VRegInfo *Info;
719 if (parseVirtualRegisterReference(PFS, Info, LiveIn.VirtualRegister.Value,
720 Error))
721 return error(Error, LiveIn.VirtualRegister.SourceRange);
722 VReg = Info->VReg;
723 }
724 RegInfo.addLiveIn(Reg, VReg);
725 }
726
727 // Parse the callee saved registers (Registers that will
728 // be saved for the caller).
729 if (YamlMF.CalleeSavedRegisters) {
730 SmallVector<MCPhysReg, 16> CalleeSavedRegisters;
731 for (const auto &RegSource : *YamlMF.CalleeSavedRegisters) {
732 Register Reg;
733 if (parseNamedRegisterReference(PFS, Reg, RegSource.Value, Error))
734 return error(Error, RegSource.SourceRange);
735 CalleeSavedRegisters.push_back(Reg);
736 }
737 RegInfo.setCalleeSavedRegs(CalleeSavedRegisters);
738 }
739
740 return false;
741}
742
744 const yaml::MachineFunction &YamlMF) {
745 MachineFunction &MF = PFS.MF;
748
749 bool Error = false;
750 // Create VRegs
751 auto populateVRegInfo = [&](const VRegInfo &Info, Twine Name) {
752 Register Reg = Info.VReg;
753 switch (Info.Kind) {
755 error(Twine("Cannot determine class/bank of virtual register ") +
756 Name + " in function '" + MF.getName() + "'");
757 Error = true;
758 break;
759 case VRegInfo::NORMAL:
760 if (!Info.D.RC->isAllocatable()) {
761 error(Twine("Cannot use non-allocatable class '") +
762 TRI->getRegClassName(Info.D.RC) + "' for virtual register " +
763 Name + " in function '" + MF.getName() + "'");
764 Error = true;
765 break;
766 }
767
768 MRI.setRegClass(Reg, Info.D.RC);
769 if (Info.PreferredReg != 0)
770 MRI.setSimpleHint(Reg, Info.PreferredReg);
771 break;
773 break;
775 MRI.setRegBank(Reg, *Info.D.RegBank);
776 break;
777 }
778 };
779
780 for (const auto &P : PFS.VRegInfosNamed) {
781 const VRegInfo &Info = *P.second;
782 populateVRegInfo(Info, Twine(P.first()));
783 }
784
785 for (auto P : PFS.VRegInfos) {
786 const VRegInfo &Info = *P.second;
787 populateVRegInfo(Info, Twine(P.first));
788 }
789
790 // Compute MachineRegisterInfo::UsedPhysRegMask
791 for (const MachineBasicBlock &MBB : MF) {
792 // Make sure MRI knows about registers clobbered by unwinder.
793 if (MBB.isEHPad())
794 if (auto *RegMask = TRI->getCustomEHPadPreservedMask(MF))
795 MRI.addPhysRegsUsedFromRegMask(RegMask);
796
797 for (const MachineInstr &MI : MBB) {
798 for (const MachineOperand &MO : MI.operands()) {
799 if (!MO.isRegMask())
800 continue;
801 MRI.addPhysRegsUsedFromRegMask(MO.getRegMask());
802 }
803 }
804 }
805
806 return Error;
807}
808
810 const yaml::MachineFunction &YamlMF) {
811 MachineFunction &MF = PFS.MF;
812 MachineFrameInfo &MFI = MF.getFrameInfo();
814 const Function &F = MF.getFunction();
815 const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
818 MFI.setHasStackMap(YamlMFI.HasStackMap);
819 MFI.setHasPatchPoint(YamlMFI.HasPatchPoint);
820 MFI.setStackSize(YamlMFI.StackSize);
822 if (YamlMFI.MaxAlignment)
824 MFI.setAdjustsStack(YamlMFI.AdjustsStack);
825 MFI.setHasCalls(YamlMFI.HasCalls);
826 if (YamlMFI.MaxCallFrameSize != ~0u)
830 MFI.setHasVAStart(YamlMFI.HasVAStart);
832 MFI.setHasTailCall(YamlMFI.HasTailCall);
835 if (!YamlMFI.SavePoint.Value.empty()) {
836 MachineBasicBlock *MBB = nullptr;
837 if (parseMBBReference(PFS, MBB, YamlMFI.SavePoint))
838 return true;
839 MFI.setSavePoint(MBB);
840 }
841 if (!YamlMFI.RestorePoint.Value.empty()) {
842 MachineBasicBlock *MBB = nullptr;
843 if (parseMBBReference(PFS, MBB, YamlMFI.RestorePoint))
844 return true;
845 MFI.setRestorePoint(MBB);
846 }
847
848 std::vector<CalleeSavedInfo> CSIInfo;
849 // Initialize the fixed frame objects.
850 for (const auto &Object : YamlMF.FixedStackObjects) {
851 int ObjectIdx;
853 ObjectIdx = MFI.CreateFixedObject(Object.Size, Object.Offset,
854 Object.IsImmutable, Object.IsAliased);
855 else
856 ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
857
858 if (!TFI->isSupportedStackID(Object.StackID))
859 return error(Object.ID.SourceRange.Start,
860 Twine("StackID is not supported by target"));
861 MFI.setStackID(ObjectIdx, Object.StackID);
862 MFI.setObjectAlignment(ObjectIdx, Object.Alignment.valueOrOne());
863 if (!PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID.Value,
864 ObjectIdx))
865 .second)
866 return error(Object.ID.SourceRange.Start,
867 Twine("redefinition of fixed stack object '%fixed-stack.") +
868 Twine(Object.ID.Value) + "'");
869 if (parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister,
870 Object.CalleeSavedRestored, ObjectIdx))
871 return true;
872 if (parseStackObjectsDebugInfo(PFS, Object, ObjectIdx))
873 return true;
874 }
875
876 for (const auto &Object : YamlMF.EntryValueObjects) {
878 Register Reg;
879 if (parseNamedRegisterReference(PFS, Reg, Object.EntryValueRegister.Value,
880 Error))
881 return error(Error, Object.EntryValueRegister.SourceRange);
882 if (!Reg.isPhysical())
883 return error(Object.EntryValueRegister.SourceRange.Start,
884 "Expected physical register for entry value field");
885 std::optional<VarExprLoc> MaybeInfo = parseVarExprLoc(
886 PFS, Object.DebugVar, Object.DebugExpr, Object.DebugLoc);
887 if (!MaybeInfo)
888 return true;
889 if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc)
890 PFS.MF.setVariableDbgInfo(MaybeInfo->DIVar, MaybeInfo->DIExpr,
891 Reg.asMCReg(), MaybeInfo->DILoc);
892 }
893
894 // Initialize the ordinary frame objects.
895 for (const auto &Object : YamlMF.StackObjects) {
896 int ObjectIdx;
897 const AllocaInst *Alloca = nullptr;
898 const yaml::StringValue &Name = Object.Name;
899 if (!Name.Value.empty()) {
900 Alloca = dyn_cast_or_null<AllocaInst>(
901 F.getValueSymbolTable()->lookup(Name.Value));
902 if (!Alloca)
903 return error(Name.SourceRange.Start,
904 "alloca instruction named '" + Name.Value +
905 "' isn't defined in the function '" + F.getName() +
906 "'");
907 }
908 if (!TFI->isSupportedStackID(Object.StackID))
909 return error(Object.ID.SourceRange.Start,
910 Twine("StackID is not supported by target"));
912 ObjectIdx =
913 MFI.CreateVariableSizedObject(Object.Alignment.valueOrOne(), Alloca);
914 else
915 ObjectIdx = MFI.CreateStackObject(
916 Object.Size, Object.Alignment.valueOrOne(),
917 Object.Type == yaml::MachineStackObject::SpillSlot, Alloca,
918 Object.StackID);
919 MFI.setObjectOffset(ObjectIdx, Object.Offset);
920
921 if (!PFS.StackObjectSlots.insert(std::make_pair(Object.ID.Value, ObjectIdx))
922 .second)
923 return error(Object.ID.SourceRange.Start,
924 Twine("redefinition of stack object '%stack.") +
925 Twine(Object.ID.Value) + "'");
926 if (parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister,
927 Object.CalleeSavedRestored, ObjectIdx))
928 return true;
929 if (Object.LocalOffset)
930 MFI.mapLocalFrameObject(ObjectIdx, *Object.LocalOffset);
931 if (parseStackObjectsDebugInfo(PFS, Object, ObjectIdx))
932 return true;
933 }
934 MFI.setCalleeSavedInfo(CSIInfo);
935 if (!CSIInfo.empty())
936 MFI.setCalleeSavedInfoValid(true);
937
938 // Initialize the various stack object references after initializing the
939 // stack objects.
940 if (!YamlMFI.StackProtector.Value.empty()) {
942 int FI;
944 return error(Error, YamlMFI.StackProtector.SourceRange);
946 }
947
948 if (!YamlMFI.FunctionContext.Value.empty()) {
950 int FI;
952 return error(Error, YamlMFI.FunctionContext.SourceRange);
954 }
955
956 return false;
957}
958
960 std::vector<CalleeSavedInfo> &CSIInfo,
961 const yaml::StringValue &RegisterSource, bool IsRestored, int FrameIdx) {
962 if (RegisterSource.Value.empty())
963 return false;
964 Register Reg;
966 if (parseNamedRegisterReference(PFS, Reg, RegisterSource.Value, Error))
967 return error(Error, RegisterSource.SourceRange);
968 CalleeSavedInfo CSI(Reg, FrameIdx);
969 CSI.setRestored(IsRestored);
970 CSIInfo.push_back(CSI);
971 return false;
972}
973
974/// Verify that given node is of a certain type. Return true on error.
975template <typename T>
976static bool typecheckMDNode(T *&Result, MDNode *Node,
977 const yaml::StringValue &Source,
978 StringRef TypeString, MIRParserImpl &Parser) {
979 if (!Node)
980 return false;
981 Result = dyn_cast<T>(Node);
982 if (!Result)
983 return Parser.error(Source.SourceRange.Start,
984 "expected a reference to a '" + TypeString +
985 "' metadata node");
986 return false;
987}
988
989std::optional<MIRParserImpl::VarExprLoc> MIRParserImpl::parseVarExprLoc(
991 const yaml::StringValue &ExprStr, const yaml::StringValue &LocStr) {
992 MDNode *Var = nullptr;
993 MDNode *Expr = nullptr;
994 MDNode *Loc = nullptr;
995 if (parseMDNode(PFS, Var, VarStr) || parseMDNode(PFS, Expr, ExprStr) ||
996 parseMDNode(PFS, Loc, LocStr))
997 return std::nullopt;
998 DILocalVariable *DIVar = nullptr;
999 DIExpression *DIExpr = nullptr;
1000 DILocation *DILoc = nullptr;
1001 if (typecheckMDNode(DIVar, Var, VarStr, "DILocalVariable", *this) ||
1002 typecheckMDNode(DIExpr, Expr, ExprStr, "DIExpression", *this) ||
1003 typecheckMDNode(DILoc, Loc, LocStr, "DILocation", *this))
1004 return std::nullopt;
1005 return VarExprLoc{DIVar, DIExpr, DILoc};
1006}
1007
1008template <typename T>
1010 const T &Object, int FrameIdx) {
1011 std::optional<VarExprLoc> MaybeInfo =
1012 parseVarExprLoc(PFS, Object.DebugVar, Object.DebugExpr, Object.DebugLoc);
1013 if (!MaybeInfo)
1014 return true;
1015 // Debug information can only be attached to stack objects; Fixed stack
1016 // objects aren't supported.
1017 if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc)
1018 PFS.MF.setVariableDbgInfo(MaybeInfo->DIVar, MaybeInfo->DIExpr, FrameIdx,
1019 MaybeInfo->DILoc);
1020 return false;
1021}
1022
1023bool MIRParserImpl::parseMDNode(PerFunctionMIParsingState &PFS,
1024 MDNode *&Node, const yaml::StringValue &Source) {
1025 if (Source.Value.empty())
1026 return false;
1028 if (llvm::parseMDNode(PFS, Node, Source.Value, Error))
1029 return error(Error, Source.SourceRange);
1030 return false;
1031}
1032
1035 DenseMap<unsigned, unsigned> &ConstantPoolSlots = PFS.ConstantPoolSlots;
1036 const MachineFunction &MF = PFS.MF;
1037 const auto &M = *MF.getFunction().getParent();
1039 for (const auto &YamlConstant : YamlMF.Constants) {
1040 if (YamlConstant.IsTargetSpecific)
1041 // FIXME: Support target-specific constant pools
1042 return error(YamlConstant.Value.SourceRange.Start,
1043 "Can't parse target-specific constant pool entries yet");
1044 const Constant *Value = dyn_cast_or_null<Constant>(
1045 parseConstantValue(YamlConstant.Value.Value, Error, M));
1046 if (!Value)
1047 return error(Error, YamlConstant.Value.SourceRange);
1048 const Align PrefTypeAlign =
1049 M.getDataLayout().getPrefTypeAlign(Value->getType());
1050 const Align Alignment = YamlConstant.Alignment.value_or(PrefTypeAlign);
1051 unsigned Index = ConstantPool.getConstantPoolIndex(Value, Alignment);
1052 if (!ConstantPoolSlots.insert(std::make_pair(YamlConstant.ID.Value, Index))
1053 .second)
1054 return error(YamlConstant.ID.SourceRange.Start,
1055 Twine("redefinition of constant pool item '%const.") +
1056 Twine(YamlConstant.ID.Value) + "'");
1057 }
1058 return false;
1059}
1060
1062 const yaml::MachineJumpTable &YamlJTI) {
1064 for (const auto &Entry : YamlJTI.Entries) {
1065 std::vector<MachineBasicBlock *> Blocks;
1066 for (const auto &MBBSource : Entry.Blocks) {
1067 MachineBasicBlock *MBB = nullptr;
1068 if (parseMBBReference(PFS, MBB, MBBSource.Value))
1069 return true;
1070 Blocks.push_back(MBB);
1071 }
1072 unsigned Index = JTI->createJumpTableIndex(Blocks);
1073 if (!PFS.JumpTableSlots.insert(std::make_pair(Entry.ID.Value, Index))
1074 .second)
1075 return error(Entry.ID.SourceRange.Start,
1076 Twine("redefinition of jump table entry '%jump-table.") +
1077 Twine(Entry.ID.Value) + "'");
1078 }
1079 return false;
1080}
1081
1082bool MIRParserImpl::parseMBBReference(PerFunctionMIParsingState &PFS,
1084 const yaml::StringValue &Source) {
1086 if (llvm::parseMBBReference(PFS, MBB, Source.Value, Error))
1087 return error(Error, Source.SourceRange);
1088 return false;
1089}
1090
1091bool MIRParserImpl::parseMachineMetadata(PerFunctionMIParsingState &PFS,
1092 const yaml::StringValue &Source) {
1094 if (llvm::parseMachineMetadata(PFS, Source.Value, Source.SourceRange, Error))
1095 return error(Error, Source.SourceRange);
1096 return false;
1097}
1098
1101 const yaml::MachineFunction &YMF) {
1102 for (const auto &MDS : YMF.MachineMetadataNodes) {
1103 if (parseMachineMetadata(PFS, MDS))
1104 return true;
1105 }
1106 // Report missing definitions from forward referenced nodes.
1107 if (!PFS.MachineForwardRefMDNodes.empty())
1108 return error(PFS.MachineForwardRefMDNodes.begin()->second.second,
1109 "use of undefined metadata '!" +
1110 Twine(PFS.MachineForwardRefMDNodes.begin()->first) + "'");
1111 return false;
1112}
1113
1114SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
1115 SMRange SourceRange) {
1116 assert(SourceRange.isValid() && "Invalid source range");
1117 SMLoc Loc = SourceRange.Start;
1118 bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
1119 *Loc.getPointer() == '\'';
1120 // Translate the location of the error from the location in the MI string to
1121 // the corresponding location in the MIR file.
1122 Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +
1123 (HasQuote ? 1 : 0));
1124
1125 // TODO: Translate any source ranges as well.
1126 return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), {},
1127 Error.getFixIts());
1128}
1129
1130SMDiagnostic MIRParserImpl::diagFromBlockStringDiag(const SMDiagnostic &Error,
1131 SMRange SourceRange) {
1132 assert(SourceRange.isValid());
1133
1134 // Translate the location of the error from the location in the llvm IR string
1135 // to the corresponding location in the MIR file.
1136 auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);
1137 unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
1138 unsigned Column = Error.getColumnNo();
1139 StringRef LineStr = Error.getLineContents();
1140 SMLoc Loc = Error.getLoc();
1141
1142 // Get the full line and adjust the column number by taking the indentation of
1143 // LLVM IR into account.
1144 for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;
1145 L != E; ++L) {
1146 if (L.line_number() == Line) {
1147 LineStr = *L;
1148 Loc = SMLoc::getFromPointer(LineStr.data());
1149 auto Indent = LineStr.find(Error.getLineContents());
1150 if (Indent != StringRef::npos)
1151 Column += Indent;
1152 break;
1153 }
1154 }
1155
1156 return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
1157 Error.getMessage(), LineStr, Error.getRanges(),
1158 Error.getFixIts());
1159}
1160
1161MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
1162 : Impl(std::move(Impl)) {}
1163
1164MIRParser::~MIRParser() = default;
1165
1166std::unique_ptr<Module>
1168 return Impl->parseIRModule(DataLayoutCallback);
1169}
1170
1172 return Impl->parseMachineFunctions(M, MMI);
1173}
1174
1176 auto &MMI = MAM.getResult<MachineModuleAnalysis>(M).getMMI();
1177 return Impl->parseMachineFunctions(M, MMI, &MAM);
1178}
1179
1180std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(
1181 StringRef Filename, SMDiagnostic &Error, LLVMContext &Context,
1182 std::function<void(Function &)> ProcessIRFunction) {
1183 auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
1184 if (std::error_code EC = FileOrErr.getError()) {
1186 "Could not open input file: " + EC.message());
1187 return nullptr;
1188 }
1189 return createMIRParser(std::move(FileOrErr.get()), Context,
1190 ProcessIRFunction);
1191}
1192
1193std::unique_ptr<MIRParser>
1194llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
1195 LLVMContext &Context,
1196 std::function<void(Function &)> ProcessIRFunction) {
1197 auto Filename = Contents->getBufferIdentifier();
1198 if (Context.shouldDiscardValueNames()) {
1200 DS_Error,
1202 Filename, SourceMgr::DK_Error,
1203 "Can't read MIR with a Context that discards named Values")));
1204 return nullptr;
1205 }
1206 return std::make_unique<MIRParser>(std::make_unique<MIRParserImpl>(
1207 std::move(Contents), Filename, Context, ProcessIRFunction));
1208}
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:362
static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context)
Definition: MIRParser.cpp:190
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:976
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:205
void reportDiagnostic(const SMDiagnostic &Diag)
Definition: MIRParser.cpp:223
bool setupRegisterInfo(const PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF)
Definition: MIRParser.cpp:743
bool parseRegisterInfo(PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF)
Definition: MIRParser.cpp:652
bool initializeFrameInfo(PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF)
Definition: MIRParser.cpp:809
Function * createDummyFunction(StringRef Name, Module &M)
Create an empty function with the given name.
Definition: MIRParser.cpp:297
bool parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS, const T &Object, int FrameIdx)
Definition: MIRParser.cpp:1009
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:522
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:243
bool initializeJumpTableInfo(PerFunctionMIParsingState &PFS, const yaml::MachineJumpTable &YamlJTI)
Definition: MIRParser.cpp:1061
bool initializeConstantPool(PerFunctionMIParsingState &PFS, MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF)
Definition: MIRParser.cpp:1033
MIRParserImpl(std::unique_ptr< MemoryBuffer > Contents, StringRef Filename, LLVMContext &Context, std::function< void(Function &)> ProcessIRFunction)
Definition: MIRParser.cpp:194
std::optional< VarExprLoc > parseVarExprLoc(PerFunctionMIParsingState &PFS, const yaml::StringValue &VarStr, const yaml::StringValue &ExprStr, const yaml::StringValue &LocStr)
Definition: MIRParser.cpp:989
bool parseCalleeSavedRegister(PerFunctionMIParsingState &PFS, std::vector< CalleeSavedInfo > &CSIInfo, const yaml::StringValue &RegisterSource, bool IsRestored, int FrameIdx)
Definition: MIRParser.cpp:959
bool parseMachineMetadataNodes(PerFunctionMIParsingState &PFS, MachineFunction &MF, const yaml::MachineFunction &YMF)
Definition: MIRParser.cpp:1099
bool initializeCallSiteInfo(PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF)
Definition: MIRParser.cpp:460
bool parseMachineFunction(Module &M, MachineModuleInfo &MMI, ModuleAnalysisManager *FAM)
Parse the machine function in the current YAML document.
Definition: MIRParser.cpp:311
bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI, ModuleAnalysisManager *FAM=nullptr)
Definition: MIRParser.cpp:282
MIRParser(std::unique_ptr< MIRParserImpl > Impl)
Definition: MIRParser.cpp:1161
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:1167
bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI)
Parses MachineFunctions in the MIR file and add them to the given MachineModuleInfo MMI.
Definition: MIRParser.cpp:1171
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 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
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:1180
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:1194
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
Identifies call instruction location in machine function.
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::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
std::vector< Entry > Entries
MachineJumpTableInfo::JTEntryKind Kind
A wrapper around std::string which contains a source range that's being set during parsing.