LLVM 24.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"
21#include "llvm/Support/SMLoc.h"
24#include <algorithm>
25#include <cstdint>
26#include <optional>
27#include <string>
28#include <vector>
29
30namespace llvm {
31namespace yaml {
32
33/// A wrapper around std::string which contains a source range that's being
34/// set during parsing.
36 std::string Value;
38
39 StringValue() = default;
40 StringValue(std::string Value) : Value(std::move(Value)) {}
41 StringValue(const char Val[]) : Value(Val) {}
42
43 bool operator==(const StringValue &Other) const {
44 return Value == Other.Value;
45 }
46};
47
48template <> struct ScalarTraits<StringValue> {
49 static void output(const StringValue &S, void *, raw_ostream &OS) {
50 OS << S.Value;
51 }
52
53 static StringRef input(StringRef Scalar, void *Ctx, StringValue &S) {
54 S.Value = Scalar.str();
55 if (const auto *Node =
56 reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
58 return "";
59 }
60
61 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
62};
63
68
69template <> struct ScalarTraits<FlowStringValue> {
70 static void output(const FlowStringValue &S, void *, raw_ostream &OS) {
71 return ScalarTraits<StringValue>::output(S, nullptr, OS);
72 }
73
76 }
77
78 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
79};
80
83
84 bool operator==(const BlockStringValue &Other) const {
85 return Value == Other.Value;
86 }
87};
88
90 static void output(const BlockStringValue &S, void *Ctx, raw_ostream &OS) {
92 }
93
97};
98
99/// A wrapper around unsigned which contains a source range that's being set
100/// during parsing.
102 unsigned Value = 0;
104
105 UnsignedValue() = default;
107
108 bool operator==(const UnsignedValue &Other) const {
109 return Value == Other.Value;
110 }
111};
112
113template <> struct ScalarTraits<UnsignedValue> {
114 static void output(const UnsignedValue &Value, void *Ctx, raw_ostream &OS) {
116 }
117
119 if (const auto *Node =
120 reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
121 Value.SourceRange = Node->getSourceRange();
123 }
124
128};
129
130template <> struct ScalarEnumerationTraits<MachineJumpTableInfo::JTEntryKind> {
131 static void enumeration(yaml::IO &IO,
133 IO.enumCase(EntryKind, "block-address",
135 IO.enumCase(EntryKind, "gp-rel64-block-address",
137 IO.enumCase(EntryKind, "gp-rel32-block-address",
139 IO.enumCase(EntryKind, "label-difference32",
141 IO.enumCase(EntryKind, "label-difference64",
143 IO.enumCase(EntryKind, "inline", MachineJumpTableInfo::EK_Inline);
144 IO.enumCase(EntryKind, "custom32", MachineJumpTableInfo::EK_Custom32);
145 }
146};
147
157
158template <> struct ScalarTraits<MaybeAlign> {
159 static void output(const MaybeAlign &Alignment, void *,
160 llvm::raw_ostream &out) {
161 out << uint64_t(Alignment ? Alignment->value() : 0U);
162 }
163 static StringRef input(StringRef Scalar, void *, MaybeAlign &Alignment) {
164 unsigned long long n;
165 if (getAsUnsignedInteger(Scalar, 10, n))
166 return "invalid number";
167 if (n > 0 && !isPowerOf2_64(n))
168 return "must be 0 or a power of two";
169 Alignment = MaybeAlign(n);
170 return StringRef();
171 }
173};
174
175template <> struct ScalarTraits<Align> {
176 static void output(const Align &Alignment, void *, llvm::raw_ostream &OS) {
177 OS << Alignment.value();
178 }
179 static StringRef input(StringRef Scalar, void *, Align &Alignment) {
180 unsigned long long N;
181 if (getAsUnsignedInteger(Scalar, 10, N))
182 return "invalid number";
183 if (!isPowerOf2_64(N))
184 return "must be a power of two";
185 Alignment = Align(N);
186 return StringRef();
187 }
189};
190
191} // end namespace yaml
192} // end namespace llvm
193
197
198namespace llvm {
199namespace yaml {
200
205 std::vector<FlowStringValue> RegisterFlags;
206 std::vector<FlowStringValue> AntiHints;
207 // VirtRegMap state.
208 // SplitFrom: id-form virtual register only (e.g. '%0'); physregs and named
209 // vregs are rejected by the parser.
210 // AssignedPhys: physical register only (e.g. '$r5'); virtregs are rejected.
213
214 // TODO: Serialize the target specific register hints.
215
217 return ID == Other.ID && Class == Other.Class &&
218 PreferredRegister == Other.PreferredRegister &&
219 SplitFrom == Other.SplitFrom && AssignedPhys == Other.AssignedPhys;
220 }
221};
222
224 static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) {
225 YamlIO.mapRequired("id", Reg.ID);
226 YamlIO.mapRequired("class", Reg.Class);
227 YamlIO.mapOptional("preferred-register", Reg.PreferredRegister,
228 StringValue()); // Don't print out when it's empty.
229 YamlIO.mapOptional("flags", Reg.RegisterFlags,
230 std::vector<FlowStringValue>());
231 // MIRPrinter sets WriteDefaultValues=true unless -simplify-mir is passed,
232 // so a plain mapOptional with an empty default would still emit the keys
233 // and change every existing test's output.
234 // Skip the call on output when empty to keep them off entirely.
235 if (!YamlIO.outputting() || !Reg.AntiHints.empty()) {
236 YamlIO.mapOptional("anti-hints", Reg.AntiHints,
237 std::vector<FlowStringValue>());
238 }
239 if (!YamlIO.outputting() || !Reg.SplitFrom.Value.empty())
240 YamlIO.mapOptional("split-from", Reg.SplitFrom, StringValue());
241 if (!YamlIO.outputting() || !Reg.AssignedPhys.Value.empty())
242 YamlIO.mapOptional("assigned-phys", Reg.AssignedPhys, StringValue());
243 }
244
245 static const bool flow = true;
246};
247
251
253 return Register == Other.Register &&
254 VirtualRegister == Other.VirtualRegister;
255 }
256};
257
259 static void mapping(IO &YamlIO, MachineFunctionLiveIn &LiveIn) {
260 YamlIO.mapRequired("reg", LiveIn.Register);
261 YamlIO.mapOptional(
262 "virtual-reg", LiveIn.VirtualRegister,
263 StringValue()); // Don't print the virtual register when it's empty.
264 }
265
266 static const bool flow = true;
267};
268
269/// Serializable representation of stack object from the MachineFrameInfo class.
270///
271/// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are
272/// determined by the object's type and frame information flags.
273/// Dead stack objects aren't serialized.
274///
275/// The 'isPreallocated' flag is determined by the local offset.
280 // TODO: Serialize unnamed LLVM alloca reference.
282 int64_t Offset = 0;
284 MaybeAlign Alignment = std::nullopt;
288 std::optional<int64_t> LocalOffset;
292
294 return ID == Other.ID && Name == Other.Name && Type == Other.Type &&
295 Offset == Other.Offset && Size == Other.Size &&
296 Alignment == Other.Alignment &&
297 StackID == Other.StackID &&
298 CalleeSavedRegister == Other.CalleeSavedRegister &&
299 CalleeSavedRestored == Other.CalleeSavedRestored &&
300 LocalOffset == Other.LocalOffset && DebugVar == Other.DebugVar &&
301 DebugExpr == Other.DebugExpr && DebugLoc == Other.DebugLoc;
302 }
303};
304
312
314 static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) {
315 YamlIO.mapRequired("id", Object.ID);
316 YamlIO.mapOptional("name", Object.Name,
317 StringValue()); // Don't print out an empty name.
318 YamlIO.mapOptional(
319 "type", Object.Type,
320 MachineStackObject::DefaultType); // Don't print the default type.
321 YamlIO.mapOptional("offset", Object.Offset, (int64_t)0);
322 if (Object.Type != MachineStackObject::VariableSized)
323 YamlIO.mapRequired("size", Object.Size);
324 YamlIO.mapOptional("alignment", Object.Alignment, std::nullopt);
325 YamlIO.mapOptional("stack-id", Object.StackID, TargetStackID::Default);
326 YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
327 StringValue()); // Don't print it out when it's empty.
328 YamlIO.mapOptional("callee-saved-restored", Object.CalleeSavedRestored,
329 true);
330 YamlIO.mapOptional("local-offset", Object.LocalOffset,
331 std::optional<int64_t>());
332 YamlIO.mapOptional("debug-info-variable", Object.DebugVar,
333 StringValue()); // Don't print it out when it's empty.
334 YamlIO.mapOptional("debug-info-expression", Object.DebugExpr,
335 StringValue()); // Don't print it out when it's empty.
336 YamlIO.mapOptional("debug-info-location", Object.DebugLoc,
337 StringValue()); // Don't print it out when it's empty.
338 }
339
340 static const bool flow = true;
341};
342
343/// Serializable representation of the MCRegister variant of
344/// MachineFunction::VariableDbgInfo.
350 bool operator==(const EntryValueObject &Other) const {
351 return EntryValueRegister == Other.EntryValueRegister &&
352 DebugVar == Other.DebugVar && DebugExpr == Other.DebugExpr &&
353 DebugLoc == Other.DebugLoc;
354 }
355};
356
357template <> struct MappingTraits<EntryValueObject> {
358 static void mapping(yaml::IO &YamlIO, EntryValueObject &Object) {
359 YamlIO.mapRequired("entry-value-register", Object.EntryValueRegister);
360 YamlIO.mapRequired("debug-info-variable", Object.DebugVar);
361 YamlIO.mapRequired("debug-info-expression", Object.DebugExpr);
362 YamlIO.mapRequired("debug-info-location", Object.DebugLoc);
363 }
364 static const bool flow = true;
365};
366
367/// Serializable representation of the fixed stack object from the
368/// MachineFrameInfo class.
373 int64_t Offset = 0;
375 MaybeAlign Alignment = std::nullopt;
377 bool IsImmutable = false;
378 bool IsAliased = false;
384
386 return ID == Other.ID && Type == Other.Type && Offset == Other.Offset &&
387 Size == Other.Size && Alignment == Other.Alignment &&
388 StackID == Other.StackID &&
389 IsImmutable == Other.IsImmutable && IsAliased == Other.IsAliased &&
390 CalleeSavedRegister == Other.CalleeSavedRegister &&
391 CalleeSavedRestored == Other.CalleeSavedRestored &&
392 DebugVar == Other.DebugVar && DebugExpr == Other.DebugExpr
393 && DebugLoc == Other.DebugLoc;
394 }
395};
396
397template <>
405
406template <>
409 IO.enumCase(ID, "default", TargetStackID::Default);
410 IO.enumCase(ID, "sgpr-spill", TargetStackID::SGPRSpill);
411 IO.enumCase(ID, "scalable-vector", TargetStackID::ScalableVector);
412 IO.enumCase(ID, "scalable-predicate-vector",
414 IO.enumCase(ID, "wasm-local", TargetStackID::WasmLocal);
415 IO.enumCase(ID, "avr-align", TargetStackID::AvrAlign);
416 IO.enumCase(ID, "noalloc", TargetStackID::NoAlloc);
417 }
418};
419
421 static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) {
422 YamlIO.mapRequired("id", Object.ID);
423 YamlIO.mapOptional(
424 "type", Object.Type,
425 FixedMachineStackObject::DefaultType); // Don't print the default type.
426 YamlIO.mapOptional("offset", Object.Offset, (int64_t)0);
427 YamlIO.mapOptional("size", Object.Size, (uint64_t)0);
428 YamlIO.mapOptional("alignment", Object.Alignment, std::nullopt);
429 YamlIO.mapOptional("stack-id", Object.StackID, TargetStackID::Default);
430 if (Object.Type != FixedMachineStackObject::SpillSlot) {
431 YamlIO.mapOptional("isImmutable", Object.IsImmutable, false);
432 YamlIO.mapOptional("isAliased", Object.IsAliased, false);
433 }
434 YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
435 StringValue()); // Don't print it out when it's empty.
436 YamlIO.mapOptional("callee-saved-restored", Object.CalleeSavedRestored,
437 true);
438 YamlIO.mapOptional("debug-info-variable", Object.DebugVar,
439 StringValue()); // Don't print it out when it's empty.
440 YamlIO.mapOptional("debug-info-expression", Object.DebugExpr,
441 StringValue()); // Don't print it out when it's empty.
442 YamlIO.mapOptional("debug-info-location", Object.DebugLoc,
443 StringValue()); // Don't print it out when it's empty.
444 }
445
446 static const bool flow = true;
447};
448
449/// A serializaable representation of a reference to a stack object or fixed
450/// stack object.
452 // The frame index as printed. This is always a positive number, even for
453 // fixed objects. To obtain the real index,
454 // MachineFrameInfo::getObjectIndexBegin has to be added.
455 int FI;
458
459 FrameIndex() = default;
461
463};
464
465template <> struct ScalarTraits<FrameIndex> {
466 static void output(const FrameIndex &FI, void *, raw_ostream &OS) {
468 }
469
470 static StringRef input(StringRef Scalar, void *Ctx, FrameIndex &FI) {
471 FI.IsFixed = false;
472 StringRef Num;
473 if (Scalar.starts_with("%stack.")) {
474 Num = Scalar.substr(7);
475 } else if (Scalar.starts_with("%fixed-stack.")) {
476 Num = Scalar.substr(13);
477 FI.IsFixed = true;
478 } else {
479 return "Invalid frame index, needs to start with %stack. or "
480 "%fixed-stack.";
481 }
482 if (Num.consumeInteger(10, FI.FI))
483 return "Invalid frame index, not a valid number";
484
485 if (const auto *Node =
486 reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
488 return StringRef();
489 }
490
492};
493
494/// Identifies call instruction location in machine function.
496 unsigned BlockNum;
497 unsigned Offset;
498
499 bool operator==(const MachineInstrLoc &Other) const {
500 return BlockNum == Other.BlockNum && Offset == Other.Offset;
501 }
502};
503
504/// Serializable representation of CallSiteInfo.
506 // Representation of call argument and register which is used to
507 // transfer it.
508 struct ArgRegPair {
511
512 bool operator==(const ArgRegPair &Other) const {
513 return Reg == Other.Reg && ArgNo == Other.ArgNo;
514 }
515 };
516
518 std::vector<ArgRegPair> ArgForwardingRegs;
519 /// Numeric callee type identifiers for the callgraph section.
520 std::vector<uint64_t> CalleeTypeIds;
521
522 bool operator==(const CallSiteInfo &Other) const {
523 return CallLocation.BlockNum == Other.CallLocation.BlockNum &&
524 CallLocation.Offset == Other.CallLocation.Offset;
525 }
526};
527
528template <> struct MappingTraits<CallSiteInfo::ArgRegPair> {
529 static void mapping(IO &YamlIO, CallSiteInfo::ArgRegPair &ArgReg) {
530 YamlIO.mapRequired("arg", ArgReg.ArgNo);
531 YamlIO.mapRequired("reg", ArgReg.Reg);
532 }
533
534 static const bool flow = true;
535};
536}
537}
538
540
541namespace llvm {
542namespace yaml {
543
544template <> struct MappingTraits<CallSiteInfo> {
545 static void mapping(IO &YamlIO, CallSiteInfo &CSInfo) {
546 YamlIO.mapRequired("bb", CSInfo.CallLocation.BlockNum);
547 YamlIO.mapRequired("offset", CSInfo.CallLocation.Offset);
548 YamlIO.mapOptional("fwdArgRegs", CSInfo.ArgForwardingRegs,
549 std::vector<CallSiteInfo::ArgRegPair>());
550 YamlIO.mapOptional("calleeTypeIds", CSInfo.CalleeTypeIds);
551 }
552
553 static const bool flow = true;
554};
555
556/// Serializable representation of debug value substitutions.
558 unsigned SrcInst;
559 unsigned SrcOp;
560 unsigned DstInst;
561 unsigned DstOp;
562 unsigned Subreg;
563
565 return std::tie(SrcInst, SrcOp, DstInst, DstOp) ==
566 std::tie(Other.SrcInst, Other.SrcOp, Other.DstInst, Other.DstOp);
567 }
568};
569
571 static void mapping(IO &YamlIO, DebugValueSubstitution &Sub) {
572 YamlIO.mapRequired("srcinst", Sub.SrcInst);
573 YamlIO.mapRequired("srcop", Sub.SrcOp);
574 YamlIO.mapRequired("dstinst", Sub.DstInst);
575 YamlIO.mapRequired("dstop", Sub.DstOp);
576 YamlIO.mapRequired("subreg", Sub.Subreg);
577 }
578
579 static const bool flow = true;
580};
581} // namespace yaml
582} // namespace llvm
583
585
586namespace llvm {
587namespace yaml {
591 MaybeAlign Alignment = std::nullopt;
592 bool IsTargetSpecific = false;
593
595 return ID == Other.ID && Value == Other.Value &&
596 Alignment == Other.Alignment &&
597 IsTargetSpecific == Other.IsTargetSpecific;
598 }
599};
600
603 YamlIO.mapRequired("id", Constant.ID);
604 YamlIO.mapOptional("value", Constant.Value, StringValue());
605 YamlIO.mapOptional("alignment", Constant.Alignment, std::nullopt);
606 YamlIO.mapOptional("isTargetSpecific", Constant.IsTargetSpecific, false);
607 }
608};
609
611 struct Entry {
613 std::vector<FlowStringValue> Blocks;
614
615 bool operator==(const Entry &Other) const {
616 return ID == Other.ID && Blocks == Other.Blocks;
617 }
618 };
619
621 std::vector<Entry> Entries;
622
623 bool operator==(const MachineJumpTable &Other) const {
624 return Kind == Other.Kind && Entries == Other.Entries;
625 }
626};
627
628template <> struct MappingTraits<MachineJumpTable::Entry> {
629 static void mapping(IO &YamlIO, MachineJumpTable::Entry &Entry) {
630 YamlIO.mapRequired("id", Entry.ID);
631 YamlIO.mapOptional("blocks", Entry.Blocks, std::vector<FlowStringValue>());
632 }
633};
634
638 unsigned Flags;
639
640 bool operator==(const CalledGlobal &Other) const {
641 return CallSite == Other.CallSite && Callee == Other.Callee &&
642 Flags == Other.Flags;
643 }
644};
645
646template <> struct MappingTraits<CalledGlobal> {
647 static void mapping(IO &YamlIO, CalledGlobal &CG) {
648 YamlIO.mapRequired("bb", CG.CallSite.BlockNum);
649 YamlIO.mapRequired("offset", CG.CallSite.Offset);
650 YamlIO.mapRequired("callee", CG.Callee);
651 YamlIO.mapRequired("flags", CG.Flags);
652 }
653};
654
655} // end namespace yaml
656} // end namespace llvm
657
667
668namespace llvm {
669namespace yaml {
670
671// Struct representing one save/restore point in the 'savePoint' /
672// 'restorePoint' list. One point consists of machine basic block name and list
673// of registers saved/restored in this basic block. In MIR it looks like:
674// savePoint:
675// - point: '%bb.1'
676// registers:
677// - '$rbx'
678// - '$r12'
679// ...
680// restorePoint:
681// - point: '%bb.1'
682// registers:
683// - '$rbx'
684// - '$r12'
685// If no register is saved/restored in the selected BB,
686// field 'registers' is not specified.
689 std::vector<StringValue> Registers;
690
692 return Point == Other.Point && Registers == Other.Registers;
693 }
694};
695
697 static void mapping(IO &YamlIO, SaveRestorePointEntry &Entry) {
698 YamlIO.mapRequired("point", Entry.Point);
699 YamlIO.mapOptional("registers", Entry.Registers,
700 std::vector<StringValue>());
701 }
702};
703
704template <> struct MappingTraits<MachineJumpTable> {
705 static void mapping(IO &YamlIO, MachineJumpTable &JT) {
706 YamlIO.mapRequired("kind", JT.Kind);
707 YamlIO.mapOptional("entries", JT.Entries,
708 std::vector<MachineJumpTable::Entry>());
709 }
710};
711
712} // namespace yaml
713} // namespace llvm
714
716
717namespace llvm {
718namespace yaml {
719
720/// Serializable representation of MachineFrameInfo.
721///
722/// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and
723/// 'RealignOption' as they are determined by the target and LLVM function
724/// attributes.
725/// It also doesn't serialize attributes like 'NumFixedObject' and
726/// 'HasVarSizedObjects' as they are determined by the frame objects themselves.
730 bool HasStackMap = false;
731 bool HasPatchPoint = false;
734 unsigned MaxAlignment = 0;
735 bool AdjustsStack = false;
736 bool HasCalls = false;
740 unsigned MaxCallFrameSize = ~0u; ///< ~0u means: not computed yet.
743 bool HasVAStart = false;
745 bool HasTailCall = false;
747 unsigned LocalFrameSize = 0;
748 std::vector<SaveRestorePointEntry> SavePoints;
749 std::vector<SaveRestorePointEntry> RestorePoints;
750
751 bool operator==(const MachineFrameInfo &Other) const {
752 return IsFrameAddressTaken == Other.IsFrameAddressTaken &&
753 IsReturnAddressTaken == Other.IsReturnAddressTaken &&
754 HasStackMap == Other.HasStackMap &&
755 HasPatchPoint == Other.HasPatchPoint &&
756 StackSize == Other.StackSize &&
757 OffsetAdjustment == Other.OffsetAdjustment &&
758 MaxAlignment == Other.MaxAlignment &&
759 AdjustsStack == Other.AdjustsStack && HasCalls == Other.HasCalls &&
760 FramePointerPolicy == Other.FramePointerPolicy &&
761 StackProtector == Other.StackProtector &&
762 FunctionContext == Other.FunctionContext &&
763 MaxCallFrameSize == Other.MaxCallFrameSize &&
765 Other.CVBytesOfCalleeSavedRegisters &&
766 HasOpaqueSPAdjustment == Other.HasOpaqueSPAdjustment &&
767 HasVAStart == Other.HasVAStart &&
768 HasMustTailInVarArgFunc == Other.HasMustTailInVarArgFunc &&
769 HasTailCall == Other.HasTailCall &&
770 LocalFrameSize == Other.LocalFrameSize &&
771 SavePoints == Other.SavePoints &&
772 RestorePoints == Other.RestorePoints &&
773 IsCalleeSavedInfoValid == Other.IsCalleeSavedInfoValid;
774 }
775};
776
777template <> struct MappingTraits<MachineFrameInfo> {
778 static void mapping(IO &YamlIO, MachineFrameInfo &MFI) {
779 YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken, false);
780 YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken, false);
781 YamlIO.mapOptional("hasStackMap", MFI.HasStackMap, false);
782 YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint, false);
783 YamlIO.mapOptional("stackSize", MFI.StackSize, (uint64_t)0);
784 YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment, (int)0);
785 YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment, (unsigned)0);
786 YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack, false);
787 YamlIO.mapOptional("hasCalls", MFI.HasCalls, false);
788 YamlIO.mapOptional("framePointerPolicy", MFI.FramePointerPolicy);
789 YamlIO.mapOptional("stackProtector", MFI.StackProtector,
790 StringValue()); // Don't print it out when it's empty.
791 YamlIO.mapOptional("functionContext", MFI.FunctionContext,
792 StringValue()); // Don't print it out when it's empty.
793 YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize, (unsigned)~0);
794 YamlIO.mapOptional("cvBytesOfCalleeSavedRegisters",
796 YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment,
797 false);
798 YamlIO.mapOptional("hasVAStart", MFI.HasVAStart, false);
799 YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc,
800 false);
801 YamlIO.mapOptional("hasTailCall", MFI.HasTailCall, false);
802 YamlIO.mapOptional("isCalleeSavedInfoValid", MFI.IsCalleeSavedInfoValid,
803 false);
804 YamlIO.mapOptional("localFrameSize", MFI.LocalFrameSize, (unsigned)0);
805 YamlIO.mapOptional("savePoint", MFI.SavePoints);
806 YamlIO.mapOptional("restorePoint", MFI.RestorePoints);
807 }
808};
809
810/// Targets should override this in a way that mirrors the implementation of
811/// llvm::MachineFunctionInfo.
813 virtual ~MachineFunctionInfo() = default;
814 virtual void mappingImpl(IO &YamlIO) {}
815};
816
817template <> struct MappingTraits<std::unique_ptr<MachineFunctionInfo>> {
818 static void mapping(IO &YamlIO, std::unique_ptr<MachineFunctionInfo> &MFI) {
819 if (MFI)
820 MFI->mappingImpl(YamlIO);
821 }
822};
823
826 MaybeAlign Alignment = std::nullopt;
828 // GISel MachineFunctionProperties.
829 bool Legalized = false;
830 bool RegBankSelected = false;
831 bool Selected = false;
832 bool FailedISel = false;
833 // Register information
834 bool TracksRegLiveness = false;
835 bool HasWinCFI = false;
836
837 // Computed properties that should be overridable
838 std::optional<bool> NoPHIs;
839 std::optional<bool> IsSSA;
840 std::optional<bool> NoVRegs;
841 std::optional<bool> HasFakeUses;
842
843 bool CallsEHReturn = false;
844 bool CallsUnwindInit = false;
845 bool HasEHContTarget = false;
846 bool HasEHScopes = false;
847 bool HasEHFunclets = false;
848 bool IsOutlined = false;
849
850 bool FailsVerification = false;
852 bool UseDebugInstrRef = false;
853 std::vector<VirtualRegisterDefinition> VirtualRegisters;
854 std::vector<MachineFunctionLiveIn> LiveIns;
855 std::optional<std::vector<FlowStringValue>> CalleeSavedRegisters;
856 // TODO: Serialize the various register masks.
857 // Frame information
859 std::vector<FixedMachineStackObject> FixedStackObjects;
860 std::vector<EntryValueObject> EntryValueObjects;
861 std::vector<MachineStackObject> StackObjects;
862 std::vector<MachineConstantPoolValue> Constants; /// Constant pool.
863 std::unique_ptr<MachineFunctionInfo> MachineFuncInfo;
864 std::vector<CallSiteInfo> CallSitesInfo;
865 std::vector<DebugValueSubstitution> DebugValueSubstitutions;
867 std::vector<StringValue> MachineMetadataNodes;
868 std::vector<CalledGlobal> CalledGlobals;
869 std::vector<FlowStringValue> PrefetchTargets;
871};
872
873template <> struct MappingTraits<MachineFunction> {
874 static void mapping(IO &YamlIO, MachineFunction &MF) {
875 YamlIO.mapRequired("name", MF.Name);
876 YamlIO.mapOptional("alignment", MF.Alignment, std::nullopt);
877 YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice, false);
878 YamlIO.mapOptional("legalized", MF.Legalized, false);
879 YamlIO.mapOptional("regBankSelected", MF.RegBankSelected, false);
880 YamlIO.mapOptional("selected", MF.Selected, false);
881 YamlIO.mapOptional("failedISel", MF.FailedISel, false);
882 YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness, false);
883 YamlIO.mapOptional("hasWinCFI", MF.HasWinCFI, false);
884
885 // PHIs must be not be capitalized, since it will clash with the MIR opcode
886 // leading to false-positive FileCheck hits with CHECK-NOT
887 YamlIO.mapOptional("noPhis", MF.NoPHIs, std::optional<bool>());
888 YamlIO.mapOptional("isSSA", MF.IsSSA, std::optional<bool>());
889 YamlIO.mapOptional("noVRegs", MF.NoVRegs, std::optional<bool>());
890 YamlIO.mapOptional("hasFakeUses", MF.HasFakeUses, std::optional<bool>());
891
892 YamlIO.mapOptional("callsEHReturn", MF.CallsEHReturn, false);
893 YamlIO.mapOptional("callsUnwindInit", MF.CallsUnwindInit, false);
894 YamlIO.mapOptional("hasEHContTarget", MF.HasEHContTarget, false);
895 YamlIO.mapOptional("hasEHScopes", MF.HasEHScopes, false);
896 YamlIO.mapOptional("hasEHFunclets", MF.HasEHFunclets, false);
897 YamlIO.mapOptional("isOutlined", MF.IsOutlined, false);
898 YamlIO.mapOptional("debugInstrRef", MF.UseDebugInstrRef, false);
899
900 YamlIO.mapOptional("failsVerification", MF.FailsVerification, false);
901 YamlIO.mapOptional("tracksDebugUserValues", MF.TracksDebugUserValues,
902 false);
903 YamlIO.mapOptional("registers", MF.VirtualRegisters,
904 std::vector<VirtualRegisterDefinition>());
905 YamlIO.mapOptional("liveins", MF.LiveIns,
906 std::vector<MachineFunctionLiveIn>());
907 YamlIO.mapOptional("calleeSavedRegisters", MF.CalleeSavedRegisters,
908 std::optional<std::vector<FlowStringValue>>());
909 YamlIO.mapOptional("frameInfo", MF.FrameInfo, MachineFrameInfo());
910 YamlIO.mapOptional("fixedStack", MF.FixedStackObjects,
911 std::vector<FixedMachineStackObject>());
912 YamlIO.mapOptional("stack", MF.StackObjects,
913 std::vector<MachineStackObject>());
914 YamlIO.mapOptional("entry_values", MF.EntryValueObjects,
915 std::vector<EntryValueObject>());
916 YamlIO.mapOptional("callSites", MF.CallSitesInfo,
917 std::vector<CallSiteInfo>());
918 YamlIO.mapOptional("debugValueSubstitutions", MF.DebugValueSubstitutions,
919 std::vector<DebugValueSubstitution>());
920 YamlIO.mapOptional("constants", MF.Constants,
921 std::vector<MachineConstantPoolValue>());
922 YamlIO.mapOptional("machineFunctionInfo", MF.MachineFuncInfo);
923 if (!YamlIO.outputting() || !MF.JumpTableInfo.Entries.empty())
924 YamlIO.mapOptional("jumpTable", MF.JumpTableInfo, MachineJumpTable());
925 if (!YamlIO.outputting() || !MF.MachineMetadataNodes.empty())
926 YamlIO.mapOptional("machineMetadataNodes", MF.MachineMetadataNodes,
927 std::vector<StringValue>());
928 if (!YamlIO.outputting() || !MF.CalledGlobals.empty())
929 YamlIO.mapOptional("calledGlobals", MF.CalledGlobals,
930 std::vector<CalledGlobal>());
931 if (!YamlIO.outputting() || !MF.PrefetchTargets.empty())
932 YamlIO.mapOptional("prefetch-targets", MF.PrefetchTargets,
933 std::vector<FlowStringValue>());
934
935 YamlIO.mapOptional("body", MF.Body, BlockStringValue());
936 }
937};
938
939} // end namespace yaml
940} // end namespace llvm
941
942#endif // LLVM_CODEGEN_MIRYAMLMAPPING_H
unsigned uint64_t
#define LLVM_ABI
Definition Compiler.h:215
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:47
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
bool consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
Definition StringRef.h:519
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI Value(Type *Ty, unsigned scid)
Definition Value.cpp:54
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:735
void mapOptional(StringRef Key, T &Val)
Definition YAMLTraits.h:800
void mapRequired(StringRef Key, T &Val)
Definition YAMLTraits.h:790
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
QuotingType
Describe which type of quotes should be used when quoting is necessary.
Definition YAMLTraits.h:132
QuotingType needsQuotes(StringRef S, bool ForcePreserveAsString=true)
Definition YAMLTraits.h:590
This is an optimization pass for GlobalISel generic memory operations.
FramePointerKind
Definition CodeGen.h:263
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:285
@ 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:1933
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:878
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
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:180
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.
LLVM_ABI 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.
FramePointerKind FramePointerPolicy
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< FlowStringValue > PrefetchTargets
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:63
std::vector< StringValue > Registers
bool operator==(const SaveRestorePointEntry &Other) const
static void enumeration(yaml::IO &IO, FixedMachineStackObject::ObjectType &Type)
static void enumeration(IO &IO, FramePointerKind &FP)
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:108
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:150
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 > AntiHints
std::vector< FlowStringValue > RegisterFlags