LLVM 22.0.0git
MIRYamlMapping.h
Go to the documentation of this file.
1//===- MIRYamlMapping.h - Describe mapping between MIR and YAML--*- C++ -*-===//
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 mapping between various MIR data structures and
10// their corresponding YAML representation.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CODEGEN_MIRYAMLMAPPING_H
15#define LLVM_CODEGEN_MIRYAMLMAPPING_H
16
17#include "llvm/ADT/StringRef.h"
20#include "llvm/Support/SMLoc.h"
23#include <algorithm>
24#include <cstdint>
25#include <optional>
26#include <string>
27#include <vector>
28
29namespace llvm {
30namespace yaml {
31
32/// A wrapper around std::string which contains a source range that's being
33/// set during parsing.
35 std::string Value;
37
38 StringValue() = default;
39 StringValue(std::string Value) : Value(std::move(Value)) {}
40 StringValue(const char Val[]) : Value(Val) {}
41
42 bool operator==(const StringValue &Other) const {
43 return Value == Other.Value;
44 }
45};
46
47template <> struct ScalarTraits<StringValue> {
48 static void output(const StringValue &S, void *, raw_ostream &OS) {
49 OS << S.Value;
50 }
51
52 static StringRef input(StringRef Scalar, void *Ctx, StringValue &S) {
53 S.Value = Scalar.str();
54 if (const auto *Node =
55 reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
57 return "";
58 }
59
60 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
61};
62
67
68template <> struct ScalarTraits<FlowStringValue> {
69 static void output(const FlowStringValue &S, void *, raw_ostream &OS) {
70 return ScalarTraits<StringValue>::output(S, nullptr, OS);
71 }
72
75 }
76
77 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
78};
79
82
83 bool operator==(const BlockStringValue &Other) const {
84 return Value == Other.Value;
85 }
86};
87
89 static void output(const BlockStringValue &S, void *Ctx, raw_ostream &OS) {
91 }
92
96};
97
98/// A wrapper around unsigned which contains a source range that's being set
99/// during parsing.
101 unsigned Value = 0;
103
104 UnsignedValue() = default;
106
107 bool operator==(const UnsignedValue &Other) const {
108 return Value == Other.Value;
109 }
110};
111
112template <> struct ScalarTraits<UnsignedValue> {
113 static void output(const UnsignedValue &Value, void *Ctx, raw_ostream &OS) {
115 }
116
118 if (const auto *Node =
119 reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
120 Value.SourceRange = Node->getSourceRange();
122 }
123
127};
128
129template <> struct ScalarEnumerationTraits<MachineJumpTableInfo::JTEntryKind> {
130 static void enumeration(yaml::IO &IO,
132 IO.enumCase(EntryKind, "block-address",
134 IO.enumCase(EntryKind, "gp-rel64-block-address",
136 IO.enumCase(EntryKind, "gp-rel32-block-address",
138 IO.enumCase(EntryKind, "label-difference32",
140 IO.enumCase(EntryKind, "label-difference64",
142 IO.enumCase(EntryKind, "inline", MachineJumpTableInfo::EK_Inline);
143 IO.enumCase(EntryKind, "custom32", MachineJumpTableInfo::EK_Custom32);
144 }
145};
146
147template <> struct ScalarTraits<MaybeAlign> {
148 static void output(const MaybeAlign &Alignment, void *,
149 llvm::raw_ostream &out) {
150 out << uint64_t(Alignment ? Alignment->value() : 0U);
151 }
152 static StringRef input(StringRef Scalar, void *, MaybeAlign &Alignment) {
153 unsigned long long n;
154 if (getAsUnsignedInteger(Scalar, 10, n))
155 return "invalid number";
156 if (n > 0 && !isPowerOf2_64(n))
157 return "must be 0 or a power of two";
158 Alignment = MaybeAlign(n);
159 return StringRef();
160 }
162};
163
164template <> struct ScalarTraits<Align> {
165 static void output(const Align &Alignment, void *, llvm::raw_ostream &OS) {
166 OS << Alignment.value();
167 }
168 static StringRef input(StringRef Scalar, void *, Align &Alignment) {
169 unsigned long long N;
170 if (getAsUnsignedInteger(Scalar, 10, N))
171 return "invalid number";
172 if (!isPowerOf2_64(N))
173 return "must be a power of two";
174 Alignment = Align(N);
175 return StringRef();
176 }
178};
179
180} // end namespace yaml
181} // end namespace llvm
182
186
187namespace llvm {
188namespace yaml {
189
194 std::vector<FlowStringValue> RegisterFlags;
195
196 // TODO: Serialize the target specific register hints.
197
199 return ID == Other.ID && Class == Other.Class &&
200 PreferredRegister == Other.PreferredRegister;
201 }
202};
203
205 static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) {
206 YamlIO.mapRequired("id", Reg.ID);
207 YamlIO.mapRequired("class", Reg.Class);
208 YamlIO.mapOptional("preferred-register", Reg.PreferredRegister,
209 StringValue()); // Don't print out when it's empty.
210 YamlIO.mapOptional("flags", Reg.RegisterFlags,
211 std::vector<FlowStringValue>());
212 }
213
214 static const bool flow = true;
215};
216
220
222 return Register == Other.Register &&
223 VirtualRegister == Other.VirtualRegister;
224 }
225};
226
228 static void mapping(IO &YamlIO, MachineFunctionLiveIn &LiveIn) {
229 YamlIO.mapRequired("reg", LiveIn.Register);
230 YamlIO.mapOptional(
231 "virtual-reg", LiveIn.VirtualRegister,
232 StringValue()); // Don't print the virtual register when it's empty.
233 }
234
235 static const bool flow = true;
236};
237
238/// Serializable representation of stack object from the MachineFrameInfo class.
239///
240/// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are
241/// determined by the object's type and frame information flags.
242/// Dead stack objects aren't serialized.
243///
244/// The 'isPreallocated' flag is determined by the local offset.
249 // TODO: Serialize unnamed LLVM alloca reference.
251 int64_t Offset = 0;
253 MaybeAlign Alignment = std::nullopt;
257 std::optional<int64_t> LocalOffset;
261
263 return ID == Other.ID && Name == Other.Name && Type == Other.Type &&
264 Offset == Other.Offset && Size == Other.Size &&
265 Alignment == Other.Alignment &&
266 StackID == Other.StackID &&
267 CalleeSavedRegister == Other.CalleeSavedRegister &&
268 CalleeSavedRestored == Other.CalleeSavedRestored &&
269 LocalOffset == Other.LocalOffset && DebugVar == Other.DebugVar &&
270 DebugExpr == Other.DebugExpr && DebugLoc == Other.DebugLoc;
271 }
272};
273
281
283 static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) {
284 YamlIO.mapRequired("id", Object.ID);
285 YamlIO.mapOptional("name", Object.Name,
286 StringValue()); // Don't print out an empty name.
287 YamlIO.mapOptional(
288 "type", Object.Type,
289 MachineStackObject::DefaultType); // Don't print the default type.
290 YamlIO.mapOptional("offset", Object.Offset, (int64_t)0);
291 if (Object.Type != MachineStackObject::VariableSized)
292 YamlIO.mapRequired("size", Object.Size);
293 YamlIO.mapOptional("alignment", Object.Alignment, std::nullopt);
294 YamlIO.mapOptional("stack-id", Object.StackID, TargetStackID::Default);
295 YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
296 StringValue()); // Don't print it out when it's empty.
297 YamlIO.mapOptional("callee-saved-restored", Object.CalleeSavedRestored,
298 true);
299 YamlIO.mapOptional("local-offset", Object.LocalOffset,
300 std::optional<int64_t>());
301 YamlIO.mapOptional("debug-info-variable", Object.DebugVar,
302 StringValue()); // Don't print it out when it's empty.
303 YamlIO.mapOptional("debug-info-expression", Object.DebugExpr,
304 StringValue()); // Don't print it out when it's empty.
305 YamlIO.mapOptional("debug-info-location", Object.DebugLoc,
306 StringValue()); // Don't print it out when it's empty.
307 }
308
309 static const bool flow = true;
310};
311
312/// Serializable representation of the MCRegister variant of
313/// MachineFunction::VariableDbgInfo.
319 bool operator==(const EntryValueObject &Other) const {
320 return EntryValueRegister == Other.EntryValueRegister &&
321 DebugVar == Other.DebugVar && DebugExpr == Other.DebugExpr &&
322 DebugLoc == Other.DebugLoc;
323 }
324};
325
326template <> struct MappingTraits<EntryValueObject> {
327 static void mapping(yaml::IO &YamlIO, EntryValueObject &Object) {
328 YamlIO.mapRequired("entry-value-register", Object.EntryValueRegister);
329 YamlIO.mapRequired("debug-info-variable", Object.DebugVar);
330 YamlIO.mapRequired("debug-info-expression", Object.DebugExpr);
331 YamlIO.mapRequired("debug-info-location", Object.DebugLoc);
332 }
333 static const bool flow = true;
334};
335
336/// Serializable representation of the fixed stack object from the
337/// MachineFrameInfo class.
342 int64_t Offset = 0;
344 MaybeAlign Alignment = std::nullopt;
346 bool IsImmutable = false;
347 bool IsAliased = false;
353
355 return ID == Other.ID && Type == Other.Type && Offset == Other.Offset &&
356 Size == Other.Size && Alignment == Other.Alignment &&
357 StackID == Other.StackID &&
358 IsImmutable == Other.IsImmutable && IsAliased == Other.IsAliased &&
359 CalleeSavedRegister == Other.CalleeSavedRegister &&
360 CalleeSavedRestored == Other.CalleeSavedRestored &&
361 DebugVar == Other.DebugVar && DebugExpr == Other.DebugExpr
362 && DebugLoc == Other.DebugLoc;
363 }
364};
365
366template <>
374
375template <>
379 IO.enumCase(ID, "sgpr-spill", TargetStackID::SGPRSpill);
380 IO.enumCase(ID, "scalable-vector", TargetStackID::ScalableVector);
381 IO.enumCase(ID, "scalable-predicate-vector",
383 IO.enumCase(ID, "wasm-local", TargetStackID::WasmLocal);
385 }
386};
387
389 static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) {
390 YamlIO.mapRequired("id", Object.ID);
391 YamlIO.mapOptional(
392 "type", Object.Type,
393 FixedMachineStackObject::DefaultType); // Don't print the default type.
394 YamlIO.mapOptional("offset", Object.Offset, (int64_t)0);
395 YamlIO.mapOptional("size", Object.Size, (uint64_t)0);
396 YamlIO.mapOptional("alignment", Object.Alignment, std::nullopt);
397 YamlIO.mapOptional("stack-id", Object.StackID, TargetStackID::Default);
398 if (Object.Type != FixedMachineStackObject::SpillSlot) {
399 YamlIO.mapOptional("isImmutable", Object.IsImmutable, false);
400 YamlIO.mapOptional("isAliased", Object.IsAliased, false);
401 }
402 YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
403 StringValue()); // Don't print it out when it's empty.
404 YamlIO.mapOptional("callee-saved-restored", Object.CalleeSavedRestored,
405 true);
406 YamlIO.mapOptional("debug-info-variable", Object.DebugVar,
407 StringValue()); // Don't print it out when it's empty.
408 YamlIO.mapOptional("debug-info-expression", Object.DebugExpr,
409 StringValue()); // Don't print it out when it's empty.
410 YamlIO.mapOptional("debug-info-location", Object.DebugLoc,
411 StringValue()); // Don't print it out when it's empty.
412 }
413
414 static const bool flow = true;
415};
416
417/// A serializaable representation of a reference to a stack object or fixed
418/// stack object.
420 // The frame index as printed. This is always a positive number, even for
421 // fixed objects. To obtain the real index,
422 // MachineFrameInfo::getObjectIndexBegin has to be added.
423 int FI;
426
427 FrameIndex() = default;
428 FrameIndex(int FI, const llvm::MachineFrameInfo &MFI);
429
431};
432
433template <> struct ScalarTraits<FrameIndex> {
434 static void output(const FrameIndex &FI, void *, raw_ostream &OS) {
436 }
437
438 static StringRef input(StringRef Scalar, void *Ctx, FrameIndex &FI) {
439 FI.IsFixed = false;
440 StringRef Num;
441 if (Scalar.starts_with("%stack.")) {
442 Num = Scalar.substr(7);
443 } else if (Scalar.starts_with("%fixed-stack.")) {
444 Num = Scalar.substr(13);
445 FI.IsFixed = true;
446 } else {
447 return "Invalid frame index, needs to start with %stack. or "
448 "%fixed-stack.";
449 }
450 if (Num.consumeInteger(10, FI.FI))
451 return "Invalid frame index, not a valid number";
452
453 if (const auto *Node =
454 reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
456 return StringRef();
457 }
458
460};
461
462/// Identifies call instruction location in machine function.
464 unsigned BlockNum;
465 unsigned Offset;
466
467 bool operator==(const MachineInstrLoc &Other) const {
468 return BlockNum == Other.BlockNum && Offset == Other.Offset;
469 }
470};
471
472/// Serializable representation of CallSiteInfo.
474 // Representation of call argument and register which is used to
475 // transfer it.
476 struct ArgRegPair {
479
480 bool operator==(const ArgRegPair &Other) const {
481 return Reg == Other.Reg && ArgNo == Other.ArgNo;
482 }
483 };
484
486 std::vector<ArgRegPair> ArgForwardingRegs;
487 /// Numeric callee type identifiers for the callgraph section.
488 std::vector<uint64_t> CalleeTypeIds;
489
490 bool operator==(const CallSiteInfo &Other) const {
491 return CallLocation.BlockNum == Other.CallLocation.BlockNum &&
492 CallLocation.Offset == Other.CallLocation.Offset;
493 }
494};
495
496template <> struct MappingTraits<CallSiteInfo::ArgRegPair> {
497 static void mapping(IO &YamlIO, CallSiteInfo::ArgRegPair &ArgReg) {
498 YamlIO.mapRequired("arg", ArgReg.ArgNo);
499 YamlIO.mapRequired("reg", ArgReg.Reg);
500 }
501
502 static const bool flow = true;
503};
504}
505}
506
508
509namespace llvm {
510namespace yaml {
511
512template <> struct MappingTraits<CallSiteInfo> {
513 static void mapping(IO &YamlIO, CallSiteInfo &CSInfo) {
514 YamlIO.mapRequired("bb", CSInfo.CallLocation.BlockNum);
515 YamlIO.mapRequired("offset", CSInfo.CallLocation.Offset);
516 YamlIO.mapOptional("fwdArgRegs", CSInfo.ArgForwardingRegs,
517 std::vector<CallSiteInfo::ArgRegPair>());
518 YamlIO.mapOptional("calleeTypeIds", CSInfo.CalleeTypeIds);
519 }
520
521 static const bool flow = true;
522};
523
524/// Serializable representation of debug value substitutions.
526 unsigned SrcInst;
527 unsigned SrcOp;
528 unsigned DstInst;
529 unsigned DstOp;
530 unsigned Subreg;
531
533 return std::tie(SrcInst, SrcOp, DstInst, DstOp) ==
534 std::tie(Other.SrcInst, Other.SrcOp, Other.DstInst, Other.DstOp);
535 }
536};
537
539 static void mapping(IO &YamlIO, DebugValueSubstitution &Sub) {
540 YamlIO.mapRequired("srcinst", Sub.SrcInst);
541 YamlIO.mapRequired("srcop", Sub.SrcOp);
542 YamlIO.mapRequired("dstinst", Sub.DstInst);
543 YamlIO.mapRequired("dstop", Sub.DstOp);
544 YamlIO.mapRequired("subreg", Sub.Subreg);
545 }
546
547 static const bool flow = true;
548};
549} // namespace yaml
550} // namespace llvm
551
553
554namespace llvm {
555namespace yaml {
559 MaybeAlign Alignment = std::nullopt;
560 bool IsTargetSpecific = false;
561
563 return ID == Other.ID && Value == Other.Value &&
564 Alignment == Other.Alignment &&
565 IsTargetSpecific == Other.IsTargetSpecific;
566 }
567};
568
571 YamlIO.mapRequired("id", Constant.ID);
572 YamlIO.mapOptional("value", Constant.Value, StringValue());
573 YamlIO.mapOptional("alignment", Constant.Alignment, std::nullopt);
574 YamlIO.mapOptional("isTargetSpecific", Constant.IsTargetSpecific, false);
575 }
576};
577
579 struct Entry {
581 std::vector<FlowStringValue> Blocks;
582
583 bool operator==(const Entry &Other) const {
584 return ID == Other.ID && Blocks == Other.Blocks;
585 }
586 };
587
589 std::vector<Entry> Entries;
590
591 bool operator==(const MachineJumpTable &Other) const {
592 return Kind == Other.Kind && Entries == Other.Entries;
593 }
594};
595
596template <> struct MappingTraits<MachineJumpTable::Entry> {
597 static void mapping(IO &YamlIO, MachineJumpTable::Entry &Entry) {
598 YamlIO.mapRequired("id", Entry.ID);
599 YamlIO.mapOptional("blocks", Entry.Blocks, std::vector<FlowStringValue>());
600 }
601};
602
606 unsigned Flags;
607
608 bool operator==(const CalledGlobal &Other) const {
609 return CallSite == Other.CallSite && Callee == Other.Callee &&
610 Flags == Other.Flags;
611 }
612};
613
614template <> struct MappingTraits<CalledGlobal> {
615 static void mapping(IO &YamlIO, CalledGlobal &CG) {
616 YamlIO.mapRequired("bb", CG.CallSite.BlockNum);
617 YamlIO.mapRequired("offset", CG.CallSite.Offset);
618 YamlIO.mapRequired("callee", CG.Callee);
619 YamlIO.mapRequired("flags", CG.Flags);
620 }
621};
622
623} // end namespace yaml
624} // end namespace llvm
625
635
636namespace llvm {
637namespace yaml {
638
639// Struct representing one save/restore point in the 'savePoint' /
640// 'restorePoint' list. One point consists of machine basic block name and list
641// of registers saved/restored in this basic block. In MIR it looks like:
642// savePoint:
643// - point: '%bb.1'
644// registers:
645// - '$rbx'
646// - '$r12'
647// ...
648// restorePoint:
649// - point: '%bb.1'
650// registers:
651// - '$rbx'
652// - '$r12'
653// If no register is saved/restored in the selected BB,
654// field 'registers' is not specified.
657 std::vector<StringValue> Registers;
658
660 return Point == Other.Point && Registers == Other.Registers;
661 }
662};
663
665 static void mapping(IO &YamlIO, SaveRestorePointEntry &Entry) {
666 YamlIO.mapRequired("point", Entry.Point);
667 YamlIO.mapOptional("registers", Entry.Registers,
668 std::vector<StringValue>());
669 }
670};
671
672template <> struct MappingTraits<MachineJumpTable> {
673 static void mapping(IO &YamlIO, MachineJumpTable &JT) {
674 YamlIO.mapRequired("kind", JT.Kind);
675 YamlIO.mapOptional("entries", JT.Entries,
676 std::vector<MachineJumpTable::Entry>());
677 }
678};
679
680} // namespace yaml
681} // namespace llvm
682
684
685namespace llvm {
686namespace yaml {
687
688/// Serializable representation of MachineFrameInfo.
689///
690/// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and
691/// 'RealignOption' as they are determined by the target and LLVM function
692/// attributes.
693/// It also doesn't serialize attributes like 'NumFixedObject' and
694/// 'HasVarSizedObjects' as they are determined by the frame objects themselves.
698 bool HasStackMap = false;
699 bool HasPatchPoint = false;
702 unsigned MaxAlignment = 0;
703 bool AdjustsStack = false;
704 bool HasCalls = false;
707 unsigned MaxCallFrameSize = ~0u; ///< ~0u means: not computed yet.
710 bool HasVAStart = false;
712 bool HasTailCall = false;
714 unsigned LocalFrameSize = 0;
715 std::vector<SaveRestorePointEntry> SavePoints;
716 std::vector<SaveRestorePointEntry> RestorePoints;
717
718 bool operator==(const MachineFrameInfo &Other) const {
719 return IsFrameAddressTaken == Other.IsFrameAddressTaken &&
720 IsReturnAddressTaken == Other.IsReturnAddressTaken &&
721 HasStackMap == Other.HasStackMap &&
722 HasPatchPoint == Other.HasPatchPoint &&
723 StackSize == Other.StackSize &&
724 OffsetAdjustment == Other.OffsetAdjustment &&
725 MaxAlignment == Other.MaxAlignment &&
726 AdjustsStack == Other.AdjustsStack && HasCalls == Other.HasCalls &&
727 StackProtector == Other.StackProtector &&
728 FunctionContext == Other.FunctionContext &&
729 MaxCallFrameSize == Other.MaxCallFrameSize &&
731 Other.CVBytesOfCalleeSavedRegisters &&
732 HasOpaqueSPAdjustment == Other.HasOpaqueSPAdjustment &&
733 HasVAStart == Other.HasVAStart &&
734 HasMustTailInVarArgFunc == Other.HasMustTailInVarArgFunc &&
735 HasTailCall == Other.HasTailCall &&
736 LocalFrameSize == Other.LocalFrameSize &&
737 SavePoints == Other.SavePoints &&
738 RestorePoints == Other.RestorePoints &&
739 IsCalleeSavedInfoValid == Other.IsCalleeSavedInfoValid;
740 }
741};
742
743template <> struct MappingTraits<MachineFrameInfo> {
744 static void mapping(IO &YamlIO, MachineFrameInfo &MFI) {
745 YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken, false);
746 YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken, false);
747 YamlIO.mapOptional("hasStackMap", MFI.HasStackMap, false);
748 YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint, false);
749 YamlIO.mapOptional("stackSize", MFI.StackSize, (uint64_t)0);
750 YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment, (int)0);
751 YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment, (unsigned)0);
752 YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack, false);
753 YamlIO.mapOptional("hasCalls", MFI.HasCalls, false);
754 YamlIO.mapOptional("stackProtector", MFI.StackProtector,
755 StringValue()); // Don't print it out when it's empty.
756 YamlIO.mapOptional("functionContext", MFI.FunctionContext,
757 StringValue()); // Don't print it out when it's empty.
758 YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize, (unsigned)~0);
759 YamlIO.mapOptional("cvBytesOfCalleeSavedRegisters",
761 YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment,
762 false);
763 YamlIO.mapOptional("hasVAStart", MFI.HasVAStart, false);
764 YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc,
765 false);
766 YamlIO.mapOptional("hasTailCall", MFI.HasTailCall, false);
767 YamlIO.mapOptional("isCalleeSavedInfoValid", MFI.IsCalleeSavedInfoValid,
768 false);
769 YamlIO.mapOptional("localFrameSize", MFI.LocalFrameSize, (unsigned)0);
770 YamlIO.mapOptional("savePoint", MFI.SavePoints);
771 YamlIO.mapOptional("restorePoint", MFI.RestorePoints);
772 }
773};
774
775/// Targets should override this in a way that mirrors the implementation of
776/// llvm::MachineFunctionInfo.
778 virtual ~MachineFunctionInfo() = default;
779 virtual void mappingImpl(IO &YamlIO) {}
780};
781
782template <> struct MappingTraits<std::unique_ptr<MachineFunctionInfo>> {
783 static void mapping(IO &YamlIO, std::unique_ptr<MachineFunctionInfo> &MFI) {
784 if (MFI)
785 MFI->mappingImpl(YamlIO);
786 }
787};
788
791 MaybeAlign Alignment = std::nullopt;
793 // GISel MachineFunctionProperties.
794 bool Legalized = false;
795 bool RegBankSelected = false;
796 bool Selected = false;
797 bool FailedISel = false;
798 // Register information
799 bool TracksRegLiveness = false;
800 bool HasWinCFI = false;
801
802 // Computed properties that should be overridable
803 std::optional<bool> NoPHIs;
804 std::optional<bool> IsSSA;
805 std::optional<bool> NoVRegs;
806 std::optional<bool> HasFakeUses;
807
808 bool CallsEHReturn = false;
809 bool CallsUnwindInit = false;
810 bool HasEHContTarget = false;
811 bool HasEHScopes = false;
812 bool HasEHFunclets = false;
813 bool IsOutlined = false;
814
815 bool FailsVerification = false;
817 bool UseDebugInstrRef = false;
818 std::vector<VirtualRegisterDefinition> VirtualRegisters;
819 std::vector<MachineFunctionLiveIn> LiveIns;
820 std::optional<std::vector<FlowStringValue>> CalleeSavedRegisters;
821 // TODO: Serialize the various register masks.
822 // Frame information
824 std::vector<FixedMachineStackObject> FixedStackObjects;
825 std::vector<EntryValueObject> EntryValueObjects;
826 std::vector<MachineStackObject> StackObjects;
827 std::vector<MachineConstantPoolValue> Constants; /// Constant pool.
828 std::unique_ptr<MachineFunctionInfo> MachineFuncInfo;
829 std::vector<CallSiteInfo> CallSitesInfo;
830 std::vector<DebugValueSubstitution> DebugValueSubstitutions;
832 std::vector<StringValue> MachineMetadataNodes;
833 std::vector<CalledGlobal> CalledGlobals;
835};
836
837template <> struct MappingTraits<MachineFunction> {
838 static void mapping(IO &YamlIO, MachineFunction &MF) {
839 YamlIO.mapRequired("name", MF.Name);
840 YamlIO.mapOptional("alignment", MF.Alignment, std::nullopt);
841 YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice, false);
842 YamlIO.mapOptional("legalized", MF.Legalized, false);
843 YamlIO.mapOptional("regBankSelected", MF.RegBankSelected, false);
844 YamlIO.mapOptional("selected", MF.Selected, false);
845 YamlIO.mapOptional("failedISel", MF.FailedISel, false);
846 YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness, false);
847 YamlIO.mapOptional("hasWinCFI", MF.HasWinCFI, false);
848
849 // PHIs must be not be capitalized, since it will clash with the MIR opcode
850 // leading to false-positive FileCheck hits with CHECK-NOT
851 YamlIO.mapOptional("noPhis", MF.NoPHIs, std::optional<bool>());
852 YamlIO.mapOptional("isSSA", MF.IsSSA, std::optional<bool>());
853 YamlIO.mapOptional("noVRegs", MF.NoVRegs, std::optional<bool>());
854 YamlIO.mapOptional("hasFakeUses", MF.HasFakeUses, std::optional<bool>());
855
856 YamlIO.mapOptional("callsEHReturn", MF.CallsEHReturn, false);
857 YamlIO.mapOptional("callsUnwindInit", MF.CallsUnwindInit, false);
858 YamlIO.mapOptional("hasEHContTarget", MF.HasEHContTarget, false);
859 YamlIO.mapOptional("hasEHScopes", MF.HasEHScopes, false);
860 YamlIO.mapOptional("hasEHFunclets", MF.HasEHFunclets, false);
861 YamlIO.mapOptional("isOutlined", MF.IsOutlined, false);
862 YamlIO.mapOptional("debugInstrRef", MF.UseDebugInstrRef, false);
863
864 YamlIO.mapOptional("failsVerification", MF.FailsVerification, false);
865 YamlIO.mapOptional("tracksDebugUserValues", MF.TracksDebugUserValues,
866 false);
867 YamlIO.mapOptional("registers", MF.VirtualRegisters,
868 std::vector<VirtualRegisterDefinition>());
869 YamlIO.mapOptional("liveins", MF.LiveIns,
870 std::vector<MachineFunctionLiveIn>());
871 YamlIO.mapOptional("calleeSavedRegisters", MF.CalleeSavedRegisters,
872 std::optional<std::vector<FlowStringValue>>());
873 YamlIO.mapOptional("frameInfo", MF.FrameInfo, MachineFrameInfo());
874 YamlIO.mapOptional("fixedStack", MF.FixedStackObjects,
875 std::vector<FixedMachineStackObject>());
876 YamlIO.mapOptional("stack", MF.StackObjects,
877 std::vector<MachineStackObject>());
878 YamlIO.mapOptional("entry_values", MF.EntryValueObjects,
879 std::vector<EntryValueObject>());
880 YamlIO.mapOptional("callSites", MF.CallSitesInfo,
881 std::vector<CallSiteInfo>());
882 YamlIO.mapOptional("debugValueSubstitutions", MF.DebugValueSubstitutions,
883 std::vector<DebugValueSubstitution>());
884 YamlIO.mapOptional("constants", MF.Constants,
885 std::vector<MachineConstantPoolValue>());
886 YamlIO.mapOptional("machineFunctionInfo", MF.MachineFuncInfo);
887 if (!YamlIO.outputting() || !MF.JumpTableInfo.Entries.empty())
888 YamlIO.mapOptional("jumpTable", MF.JumpTableInfo, MachineJumpTable());
889 if (!YamlIO.outputting() || !MF.MachineMetadataNodes.empty())
890 YamlIO.mapOptional("machineMetadataNodes", MF.MachineMetadataNodes,
891 std::vector<StringValue>());
892 if (!YamlIO.outputting() || !MF.CalledGlobals.empty())
893 YamlIO.mapOptional("calledGlobals", MF.CalledGlobals,
894 std::vector<CalledGlobal>());
895 YamlIO.mapOptional("body", MF.Body, BlockStringValue());
896 }
897};
898
899} // end namespace yaml
900} // end namespace llvm
901
902#endif // LLVM_CODEGEN_MIRYAMLMAPPING_H
Register Reg
#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)
Utility for declaring that a std::vector of a particular type should be considered a YAML sequence.
#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type)
Utility for declaring that a std::vector of a particular type should be considered a YAML flow sequen...
This is an important base class in LLVM.
Definition Constant.h:43
Tagged union holding either a T or a Error.
Definition Error.h:485
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
JTEntryKind
JTEntryKind - This enum indicates how each entry of the jump table is represented and emitted.
@ EK_GPRel32BlockAddress
EK_GPRel32BlockAddress - Each entry is an address of block, encoded with a relocation as gp-relative,...
@ EK_Inline
EK_Inline - Jump table entries are emitted inline at their point of use.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
@ EK_Custom32
EK_Custom32 - Each entry is a 32-bit value that is custom lowered by the TargetLowering::LowerCustomJ...
@ EK_LabelDifference64
EK_LabelDifference64 - Each entry is the address of the block minus the address of the jump table.
@ EK_BlockAddress
EK_BlockAddress - Each entry is a plain address of block, e.g.: .word LBB123.
@ EK_GPRel64BlockAddress
EK_GPRel64BlockAddress - Each entry is an address of block, encoded with a relocation as gp-relative,...
static LLVM_ABI void printStackObjectReference(raw_ostream &OS, unsigned FrameIndex, bool IsFixed, StringRef Name)
Print a stack object reference.
Represents a range in source code.
Definition SMLoc.h:48
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
bool consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
Definition StringRef.h:501
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI Value(Type *Ty, unsigned scid)
Definition Value.cpp:53
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
virtual bool outputting() const =0
void enumCase(T &Val, StringRef Str, const T ConstVal)
Definition YAMLTraits.h:734
void mapOptional(StringRef Key, T &Val)
Definition YAMLTraits.h:799
void mapRequired(StringRef Key, T &Val)
Definition YAMLTraits.h:789
The Input class is used to parse a yaml document into in-memory structs and vectors.
Abstract base class for all Nodes.
Definition YAMLParser.h:121
SMRange getSourceRange() const
Definition YAMLParser.h:167
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
QuotingType
Describe which type of quotes should be used when quoting is necessary.
Definition YAMLTraits.h:131
QuotingType needsQuotes(StringRef S, bool ForcePreserveAsString=true)
Definition YAMLTraits.h:589
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:293
@ Other
Any other memory.
Definition ModRef.h:68
@ Sub
Subtraction of integers.
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:1847
LLVM_ABI bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:106
static void output(const BlockStringValue &S, void *Ctx, raw_ostream &OS)
static StringRef input(StringRef Scalar, void *Ctx, BlockStringValue &S)
This class should be specialized by type that requires custom conversion to/from a YAML literal block...
Definition YAMLTraits.h:179
bool operator==(const BlockStringValue &Other) const
bool operator==(const ArgRegPair &Other) const
Serializable representation of CallSiteInfo.
std::vector< uint64_t > CalleeTypeIds
Numeric callee type identifiers for the callgraph section.
std::vector< ArgRegPair > ArgForwardingRegs
MachineInstrLoc CallLocation
bool operator==(const CallSiteInfo &Other) const
bool operator==(const CalledGlobal &Other) const
Serializable representation of debug value substitutions.
bool operator==(const DebugValueSubstitution &Other) const
Serializable representation of the MCRegister variant of MachineFunction::VariableDbgInfo.
bool operator==(const EntryValueObject &Other) const
Serializable representation of the fixed stack object from the MachineFrameInfo class.
bool operator==(const FixedMachineStackObject &Other) const
FlowStringValue(std::string Value)
A serializaable representation of a reference to a stack object or fixed stack object.
Expected< int > getFI(const llvm::MachineFrameInfo &MFI) const
bool operator==(const MachineConstantPoolValue &Other) const
Serializable representation of MachineFrameInfo.
bool operator==(const MachineFrameInfo &Other) const
std::vector< SaveRestorePointEntry > RestorePoints
unsigned MaxCallFrameSize
~0u means: not computed yet.
std::vector< SaveRestorePointEntry > SavePoints
Targets should override this in a way that mirrors the implementation of llvm::MachineFunctionInfo.
virtual void mappingImpl(IO &YamlIO)
virtual ~MachineFunctionInfo()=default
bool operator==(const MachineFunctionLiveIn &Other) const
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.
Identifies call instruction location in machine function.
bool operator==(const MachineInstrLoc &Other) const
bool operator==(const Entry &Other) const
std::vector< FlowStringValue > Blocks
bool operator==(const MachineJumpTable &Other) const
std::vector< Entry > Entries
MachineJumpTableInfo::JTEntryKind Kind
Serializable representation of stack object from the MachineFrameInfo class.
bool operator==(const MachineStackObject &Other) const
std::optional< int64_t > LocalOffset
static void mapping(IO &YamlIO, CallSiteInfo &CSInfo)
static void mapping(IO &YamlIO, CallSiteInfo::ArgRegPair &ArgReg)
static void mapping(IO &YamlIO, CalledGlobal &CG)
static void mapping(IO &YamlIO, DebugValueSubstitution &Sub)
static void mapping(yaml::IO &YamlIO, EntryValueObject &Object)
static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object)
static void mapping(IO &YamlIO, MachineConstantPoolValue &Constant)
static void mapping(IO &YamlIO, MachineFrameInfo &MFI)
static void mapping(IO &YamlIO, MachineFunctionLiveIn &LiveIn)
static void mapping(IO &YamlIO, MachineFunction &MF)
static void mapping(IO &YamlIO, MachineJumpTable &JT)
static void mapping(IO &YamlIO, MachineJumpTable::Entry &Entry)
static void mapping(yaml::IO &YamlIO, MachineStackObject &Object)
static void mapping(IO &YamlIO, SaveRestorePointEntry &Entry)
static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg)
static void mapping(IO &YamlIO, std::unique_ptr< MachineFunctionInfo > &MFI)
This class should be specialized by any type that needs to be converted to/from a YAML mapping.
Definition YAMLTraits.h:62
std::vector< StringValue > Registers
bool operator==(const SaveRestorePointEntry &Other) const
static void enumeration(yaml::IO &IO, FixedMachineStackObject::ObjectType &Type)
static void enumeration(yaml::IO &IO, MachineJumpTableInfo::JTEntryKind &EntryKind)
static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type)
static void enumeration(yaml::IO &IO, TargetStackID::Value &ID)
This class should be specialized by any integral type that converts to/from a YAML scalar where there...
Definition YAMLTraits.h:107
static StringRef input(StringRef Scalar, void *, Align &Alignment)
static QuotingType mustQuote(StringRef)
static void output(const Align &Alignment, void *, llvm::raw_ostream &OS)
static QuotingType mustQuote(StringRef S)
static void output(const FlowStringValue &S, void *, raw_ostream &OS)
static StringRef input(StringRef Scalar, void *Ctx, FlowStringValue &S)
static void output(const FrameIndex &FI, void *, raw_ostream &OS)
static StringRef input(StringRef Scalar, void *Ctx, FrameIndex &FI)
static QuotingType mustQuote(StringRef S)
static StringRef input(StringRef Scalar, void *, MaybeAlign &Alignment)
static void output(const MaybeAlign &Alignment, void *, llvm::raw_ostream &out)
static QuotingType mustQuote(StringRef)
static StringRef input(StringRef Scalar, void *Ctx, StringValue &S)
static QuotingType mustQuote(StringRef S)
static void output(const StringValue &S, void *, raw_ostream &OS)
static StringRef input(StringRef Scalar, void *Ctx, UnsignedValue &Value)
static QuotingType mustQuote(StringRef Scalar)
static void output(const UnsignedValue &Value, void *Ctx, raw_ostream &OS)
This class should be specialized by type that requires custom conversion to/from a yaml scalar.
Definition YAMLTraits.h:149
A wrapper around std::string which contains a source range that's being set during parsing.
StringValue(const char Val[])
StringValue(std::string Value)
bool operator==(const StringValue &Other) const
A wrapper around unsigned which contains a source range that's being set during parsing.
bool operator==(const UnsignedValue &Other) const
UnsignedValue(unsigned Value)
bool operator==(const VirtualRegisterDefinition &Other) const
std::vector< FlowStringValue > RegisterFlags