]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/CodeGen/MIRYamlMapping.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / CodeGen / MIRYamlMapping.h
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/Optional.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/CodeGen/MachineJumpTableInfo.h"
20 #include "llvm/CodeGen/TargetFrameLowering.h"
21 #include "llvm/Support/SMLoc.h"
22 #include "llvm/Support/YAMLTraits.h"
23 #include "llvm/Support/raw_ostream.h"
24 #include <algorithm>
25 #include <cstdint>
26 #include <string>
27 #include <vector>
28
29 namespace llvm {
30 namespace yaml {
31
32 /// A wrapper around std::string which contains a source range that's being
33 /// set during parsing.
34 struct StringValue {
35   std::string Value;
36   SMRange SourceRange;
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
47 template <> 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())
56       S.SourceRange = Node->getSourceRange();
57     return "";
58   }
59
60   static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
61 };
62
63 struct FlowStringValue : StringValue {
64   FlowStringValue() = default;
65   FlowStringValue(std::string Value) : StringValue(std::move(Value)) {}
66 };
67
68 template <> struct ScalarTraits<FlowStringValue> {
69   static void output(const FlowStringValue &S, void *, raw_ostream &OS) {
70     return ScalarTraits<StringValue>::output(S, nullptr, OS);
71   }
72
73   static StringRef input(StringRef Scalar, void *Ctx, FlowStringValue &S) {
74     return ScalarTraits<StringValue>::input(Scalar, Ctx, S);
75   }
76
77   static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
78 };
79
80 struct BlockStringValue {
81   StringValue Value;
82
83   bool operator==(const BlockStringValue &Other) const {
84     return Value == Other.Value;
85   }
86 };
87
88 template <> struct BlockScalarTraits<BlockStringValue> {
89   static void output(const BlockStringValue &S, void *Ctx, raw_ostream &OS) {
90     return ScalarTraits<StringValue>::output(S.Value, Ctx, OS);
91   }
92
93   static StringRef input(StringRef Scalar, void *Ctx, BlockStringValue &S) {
94     return ScalarTraits<StringValue>::input(Scalar, Ctx, S.Value);
95   }
96 };
97
98 /// A wrapper around unsigned which contains a source range that's being set
99 /// during parsing.
100 struct UnsignedValue {
101   unsigned Value = 0;
102   SMRange SourceRange;
103
104   UnsignedValue() = default;
105   UnsignedValue(unsigned Value) : Value(Value) {}
106
107   bool operator==(const UnsignedValue &Other) const {
108     return Value == Other.Value;
109   }
110 };
111
112 template <> struct ScalarTraits<UnsignedValue> {
113   static void output(const UnsignedValue &Value, void *Ctx, raw_ostream &OS) {
114     return ScalarTraits<unsigned>::output(Value.Value, Ctx, OS);
115   }
116
117   static StringRef input(StringRef Scalar, void *Ctx, UnsignedValue &Value) {
118     if (const auto *Node =
119             reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
120       Value.SourceRange = Node->getSourceRange();
121     return ScalarTraits<unsigned>::input(Scalar, Ctx, Value.Value);
122   }
123
124   static QuotingType mustQuote(StringRef Scalar) {
125     return ScalarTraits<unsigned>::mustQuote(Scalar);
126   }
127 };
128
129 template <> struct ScalarEnumerationTraits<MachineJumpTableInfo::JTEntryKind> {
130   static void enumeration(yaml::IO &IO,
131                           MachineJumpTableInfo::JTEntryKind &EntryKind) {
132     IO.enumCase(EntryKind, "block-address",
133                 MachineJumpTableInfo::EK_BlockAddress);
134     IO.enumCase(EntryKind, "gp-rel64-block-address",
135                 MachineJumpTableInfo::EK_GPRel64BlockAddress);
136     IO.enumCase(EntryKind, "gp-rel32-block-address",
137                 MachineJumpTableInfo::EK_GPRel32BlockAddress);
138     IO.enumCase(EntryKind, "label-difference32",
139                 MachineJumpTableInfo::EK_LabelDifference32);
140     IO.enumCase(EntryKind, "inline", MachineJumpTableInfo::EK_Inline);
141     IO.enumCase(EntryKind, "custom32", MachineJumpTableInfo::EK_Custom32);
142   }
143 };
144
145 } // end namespace yaml
146 } // end namespace llvm
147
148 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue)
149 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue)
150 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::UnsignedValue)
151
152 namespace llvm {
153 namespace yaml {
154
155 struct VirtualRegisterDefinition {
156   UnsignedValue ID;
157   StringValue Class;
158   StringValue PreferredRegister;
159
160   // TODO: Serialize the target specific register hints.
161
162   bool operator==(const VirtualRegisterDefinition &Other) const {
163     return ID == Other.ID && Class == Other.Class &&
164            PreferredRegister == Other.PreferredRegister;
165   }
166 };
167
168 template <> struct MappingTraits<VirtualRegisterDefinition> {
169   static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) {
170     YamlIO.mapRequired("id", Reg.ID);
171     YamlIO.mapRequired("class", Reg.Class);
172     YamlIO.mapOptional("preferred-register", Reg.PreferredRegister,
173                        StringValue()); // Don't print out when it's empty.
174   }
175
176   static const bool flow = true;
177 };
178
179 struct MachineFunctionLiveIn {
180   StringValue Register;
181   StringValue VirtualRegister;
182
183   bool operator==(const MachineFunctionLiveIn &Other) const {
184     return Register == Other.Register &&
185            VirtualRegister == Other.VirtualRegister;
186   }
187 };
188
189 template <> struct MappingTraits<MachineFunctionLiveIn> {
190   static void mapping(IO &YamlIO, MachineFunctionLiveIn &LiveIn) {
191     YamlIO.mapRequired("reg", LiveIn.Register);
192     YamlIO.mapOptional(
193         "virtual-reg", LiveIn.VirtualRegister,
194         StringValue()); // Don't print the virtual register when it's empty.
195   }
196
197   static const bool flow = true;
198 };
199
200 /// Serializable representation of stack object from the MachineFrameInfo class.
201 ///
202 /// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are
203 /// determined by the object's type and frame information flags.
204 /// Dead stack objects aren't serialized.
205 ///
206 /// The 'isPreallocated' flag is determined by the local offset.
207 struct MachineStackObject {
208   enum ObjectType { DefaultType, SpillSlot, VariableSized };
209   UnsignedValue ID;
210   StringValue Name;
211   // TODO: Serialize unnamed LLVM alloca reference.
212   ObjectType Type = DefaultType;
213   int64_t Offset = 0;
214   uint64_t Size = 0;
215   unsigned Alignment = 0;
216   TargetStackID::Value StackID;
217   StringValue CalleeSavedRegister;
218   bool CalleeSavedRestored = true;
219   Optional<int64_t> LocalOffset;
220   StringValue DebugVar;
221   StringValue DebugExpr;
222   StringValue DebugLoc;
223
224   bool operator==(const MachineStackObject &Other) const {
225     return ID == Other.ID && Name == Other.Name && Type == Other.Type &&
226            Offset == Other.Offset && Size == Other.Size &&
227            Alignment == Other.Alignment &&
228            StackID == Other.StackID &&
229            CalleeSavedRegister == Other.CalleeSavedRegister &&
230            CalleeSavedRestored == Other.CalleeSavedRestored &&
231            LocalOffset == Other.LocalOffset && DebugVar == Other.DebugVar &&
232            DebugExpr == Other.DebugExpr && DebugLoc == Other.DebugLoc;
233   }
234 };
235
236 template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
237   static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type) {
238     IO.enumCase(Type, "default", MachineStackObject::DefaultType);
239     IO.enumCase(Type, "spill-slot", MachineStackObject::SpillSlot);
240     IO.enumCase(Type, "variable-sized", MachineStackObject::VariableSized);
241   }
242 };
243
244 template <> struct MappingTraits<MachineStackObject> {
245   static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) {
246     YamlIO.mapRequired("id", Object.ID);
247     YamlIO.mapOptional("name", Object.Name,
248                        StringValue()); // Don't print out an empty name.
249     YamlIO.mapOptional(
250         "type", Object.Type,
251         MachineStackObject::DefaultType); // Don't print the default type.
252     YamlIO.mapOptional("offset", Object.Offset, (int64_t)0);
253     if (Object.Type != MachineStackObject::VariableSized)
254       YamlIO.mapRequired("size", Object.Size);
255     YamlIO.mapOptional("alignment", Object.Alignment, (unsigned)0);
256     YamlIO.mapOptional("stack-id", Object.StackID, TargetStackID::Default);
257     YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
258                        StringValue()); // Don't print it out when it's empty.
259     YamlIO.mapOptional("callee-saved-restored", Object.CalleeSavedRestored,
260                        true);
261     YamlIO.mapOptional("local-offset", Object.LocalOffset, Optional<int64_t>());
262     YamlIO.mapOptional("debug-info-variable", Object.DebugVar,
263                        StringValue()); // Don't print it out when it's empty.
264     YamlIO.mapOptional("debug-info-expression", Object.DebugExpr,
265                        StringValue()); // Don't print it out when it's empty.
266     YamlIO.mapOptional("debug-info-location", Object.DebugLoc,
267                        StringValue()); // Don't print it out when it's empty.
268   }
269
270   static const bool flow = true;
271 };
272
273 /// Serializable representation of the fixed stack object from the
274 /// MachineFrameInfo class.
275 struct FixedMachineStackObject {
276   enum ObjectType { DefaultType, SpillSlot };
277   UnsignedValue ID;
278   ObjectType Type = DefaultType;
279   int64_t Offset = 0;
280   uint64_t Size = 0;
281   unsigned Alignment = 0;
282   TargetStackID::Value StackID;
283   bool IsImmutable = false;
284   bool IsAliased = false;
285   StringValue CalleeSavedRegister;
286   bool CalleeSavedRestored = true;
287   StringValue DebugVar;
288   StringValue DebugExpr;
289   StringValue DebugLoc;
290
291   bool operator==(const FixedMachineStackObject &Other) const {
292     return ID == Other.ID && Type == Other.Type && Offset == Other.Offset &&
293            Size == Other.Size && Alignment == Other.Alignment &&
294            StackID == Other.StackID &&
295            IsImmutable == Other.IsImmutable && IsAliased == Other.IsAliased &&
296            CalleeSavedRegister == Other.CalleeSavedRegister &&
297            CalleeSavedRestored == Other.CalleeSavedRestored &&
298            DebugVar == Other.DebugVar && DebugExpr == Other.DebugExpr
299            && DebugLoc == Other.DebugLoc;
300   }
301 };
302
303 template <>
304 struct ScalarEnumerationTraits<FixedMachineStackObject::ObjectType> {
305   static void enumeration(yaml::IO &IO,
306                           FixedMachineStackObject::ObjectType &Type) {
307     IO.enumCase(Type, "default", FixedMachineStackObject::DefaultType);
308     IO.enumCase(Type, "spill-slot", FixedMachineStackObject::SpillSlot);
309   }
310 };
311
312 template <>
313 struct ScalarEnumerationTraits<TargetStackID::Value> {
314   static void enumeration(yaml::IO &IO, TargetStackID::Value &ID) {
315     IO.enumCase(ID, "default", TargetStackID::Default);
316     IO.enumCase(ID, "sgpr-spill", TargetStackID::SGPRSpill);
317     IO.enumCase(ID, "sve-vec", TargetStackID::SVEVector);
318     IO.enumCase(ID, "noalloc", TargetStackID::NoAlloc);
319   }
320 };
321
322 template <> struct MappingTraits<FixedMachineStackObject> {
323   static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) {
324     YamlIO.mapRequired("id", Object.ID);
325     YamlIO.mapOptional(
326         "type", Object.Type,
327         FixedMachineStackObject::DefaultType); // Don't print the default type.
328     YamlIO.mapOptional("offset", Object.Offset, (int64_t)0);
329     YamlIO.mapOptional("size", Object.Size, (uint64_t)0);
330     YamlIO.mapOptional("alignment", Object.Alignment, (unsigned)0);
331     YamlIO.mapOptional("stack-id", Object.StackID, TargetStackID::Default);
332     if (Object.Type != FixedMachineStackObject::SpillSlot) {
333       YamlIO.mapOptional("isImmutable", Object.IsImmutable, false);
334       YamlIO.mapOptional("isAliased", Object.IsAliased, false);
335     }
336     YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
337                        StringValue()); // Don't print it out when it's empty.
338     YamlIO.mapOptional("callee-saved-restored", Object.CalleeSavedRestored,
339                      true);
340     YamlIO.mapOptional("debug-info-variable", Object.DebugVar,
341                        StringValue()); // Don't print it out when it's empty.
342     YamlIO.mapOptional("debug-info-expression", Object.DebugExpr,
343                        StringValue()); // Don't print it out when it's empty.
344     YamlIO.mapOptional("debug-info-location", Object.DebugLoc,
345                        StringValue()); // Don't print it out when it's empty.
346   }
347
348   static const bool flow = true;
349 };
350
351
352 /// Serializable representation of CallSiteInfo.
353 struct CallSiteInfo {
354   // Representation of call argument and register which is used to
355   // transfer it.
356   struct ArgRegPair {
357     StringValue Reg;
358     uint16_t ArgNo;
359
360     bool operator==(const ArgRegPair &Other) const {
361       return Reg == Other.Reg && ArgNo == Other.ArgNo;
362     }
363   };
364
365   /// Identifies call instruction location in machine function.
366   struct MachineInstrLoc {
367     unsigned BlockNum;
368     unsigned Offset;
369
370     bool operator==(const MachineInstrLoc &Other) const {
371       return BlockNum == Other.BlockNum && Offset == Other.Offset;
372     }
373   };
374
375   MachineInstrLoc CallLocation;
376   std::vector<ArgRegPair> ArgForwardingRegs;
377
378   bool operator==(const CallSiteInfo &Other) const {
379     return CallLocation.BlockNum == Other.CallLocation.BlockNum &&
380            CallLocation.Offset == Other.CallLocation.Offset;
381   }
382 };
383
384 template <> struct MappingTraits<CallSiteInfo::ArgRegPair> {
385   static void mapping(IO &YamlIO, CallSiteInfo::ArgRegPair &ArgReg) {
386     YamlIO.mapRequired("arg", ArgReg.ArgNo);
387     YamlIO.mapRequired("reg", ArgReg.Reg);
388   }
389
390   static const bool flow = true;
391 };
392 }
393 }
394
395 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::CallSiteInfo::ArgRegPair)
396
397 namespace llvm {
398 namespace yaml {
399
400 template <> struct MappingTraits<CallSiteInfo> {
401   static void mapping(IO &YamlIO, CallSiteInfo &CSInfo) {
402     YamlIO.mapRequired("bb", CSInfo.CallLocation.BlockNum);
403     YamlIO.mapRequired("offset", CSInfo.CallLocation.Offset);
404     YamlIO.mapOptional("fwdArgRegs", CSInfo.ArgForwardingRegs,
405                        std::vector<CallSiteInfo::ArgRegPair>());
406   }
407
408   static const bool flow = true;
409 };
410
411 struct MachineConstantPoolValue {
412   UnsignedValue ID;
413   StringValue Value;
414   unsigned Alignment = 0;
415   bool IsTargetSpecific = false;
416
417   bool operator==(const MachineConstantPoolValue &Other) const {
418     return ID == Other.ID && Value == Other.Value &&
419            Alignment == Other.Alignment &&
420            IsTargetSpecific == Other.IsTargetSpecific;
421   }
422 };
423
424 template <> struct MappingTraits<MachineConstantPoolValue> {
425   static void mapping(IO &YamlIO, MachineConstantPoolValue &Constant) {
426     YamlIO.mapRequired("id", Constant.ID);
427     YamlIO.mapOptional("value", Constant.Value, StringValue());
428     YamlIO.mapOptional("alignment", Constant.Alignment, (unsigned)0);
429     YamlIO.mapOptional("isTargetSpecific", Constant.IsTargetSpecific, false);
430   }
431 };
432
433 struct MachineJumpTable {
434   struct Entry {
435     UnsignedValue ID;
436     std::vector<FlowStringValue> Blocks;
437
438     bool operator==(const Entry &Other) const {
439       return ID == Other.ID && Blocks == Other.Blocks;
440     }
441   };
442
443   MachineJumpTableInfo::JTEntryKind Kind = MachineJumpTableInfo::EK_Custom32;
444   std::vector<Entry> Entries;
445
446   bool operator==(const MachineJumpTable &Other) const {
447     return Kind == Other.Kind && Entries == Other.Entries;
448   }
449 };
450
451 template <> struct MappingTraits<MachineJumpTable::Entry> {
452   static void mapping(IO &YamlIO, MachineJumpTable::Entry &Entry) {
453     YamlIO.mapRequired("id", Entry.ID);
454     YamlIO.mapOptional("blocks", Entry.Blocks, std::vector<FlowStringValue>());
455   }
456 };
457
458 } // end namespace yaml
459 } // end namespace llvm
460
461 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineFunctionLiveIn)
462 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
463 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
464 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject)
465 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::CallSiteInfo)
466 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineConstantPoolValue)
467 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineJumpTable::Entry)
468
469 namespace llvm {
470 namespace yaml {
471
472 template <> struct MappingTraits<MachineJumpTable> {
473   static void mapping(IO &YamlIO, MachineJumpTable &JT) {
474     YamlIO.mapRequired("kind", JT.Kind);
475     YamlIO.mapOptional("entries", JT.Entries,
476                        std::vector<MachineJumpTable::Entry>());
477   }
478 };
479
480 /// Serializable representation of MachineFrameInfo.
481 ///
482 /// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and
483 /// 'RealignOption' as they are determined by the target and LLVM function
484 /// attributes.
485 /// It also doesn't serialize attributes like 'NumFixedObject' and
486 /// 'HasVarSizedObjects' as they are determined by the frame objects themselves.
487 struct MachineFrameInfo {
488   bool IsFrameAddressTaken = false;
489   bool IsReturnAddressTaken = false;
490   bool HasStackMap = false;
491   bool HasPatchPoint = false;
492   uint64_t StackSize = 0;
493   int OffsetAdjustment = 0;
494   unsigned MaxAlignment = 0;
495   bool AdjustsStack = false;
496   bool HasCalls = false;
497   StringValue StackProtector;
498   // TODO: Serialize FunctionContextIdx
499   unsigned MaxCallFrameSize = ~0u; ///< ~0u means: not computed yet.
500   unsigned CVBytesOfCalleeSavedRegisters = 0;
501   bool HasOpaqueSPAdjustment = false;
502   bool HasVAStart = false;
503   bool HasMustTailInVarArgFunc = false;
504   unsigned LocalFrameSize = 0;
505   StringValue SavePoint;
506   StringValue RestorePoint;
507
508   bool operator==(const MachineFrameInfo &Other) const {
509     return IsFrameAddressTaken == Other.IsFrameAddressTaken &&
510            IsReturnAddressTaken == Other.IsReturnAddressTaken &&
511            HasStackMap == Other.HasStackMap &&
512            HasPatchPoint == Other.HasPatchPoint &&
513            StackSize == Other.StackSize &&
514            OffsetAdjustment == Other.OffsetAdjustment &&
515            MaxAlignment == Other.MaxAlignment &&
516            AdjustsStack == Other.AdjustsStack && HasCalls == Other.HasCalls &&
517            StackProtector == Other.StackProtector &&
518            MaxCallFrameSize == Other.MaxCallFrameSize &&
519            CVBytesOfCalleeSavedRegisters ==
520                Other.CVBytesOfCalleeSavedRegisters &&
521            HasOpaqueSPAdjustment == Other.HasOpaqueSPAdjustment &&
522            HasVAStart == Other.HasVAStart &&
523            HasMustTailInVarArgFunc == Other.HasMustTailInVarArgFunc &&
524            LocalFrameSize == Other.LocalFrameSize &&
525            SavePoint == Other.SavePoint && RestorePoint == Other.RestorePoint;
526   }
527 };
528
529 template <> struct MappingTraits<MachineFrameInfo> {
530   static void mapping(IO &YamlIO, MachineFrameInfo &MFI) {
531     YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken, false);
532     YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken, false);
533     YamlIO.mapOptional("hasStackMap", MFI.HasStackMap, false);
534     YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint, false);
535     YamlIO.mapOptional("stackSize", MFI.StackSize, (uint64_t)0);
536     YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment, (int)0);
537     YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment, (unsigned)0);
538     YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack, false);
539     YamlIO.mapOptional("hasCalls", MFI.HasCalls, false);
540     YamlIO.mapOptional("stackProtector", MFI.StackProtector,
541                        StringValue()); // Don't print it out when it's empty.
542     YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize, (unsigned)~0);
543     YamlIO.mapOptional("cvBytesOfCalleeSavedRegisters",
544                        MFI.CVBytesOfCalleeSavedRegisters, 0U);
545     YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment,
546                        false);
547     YamlIO.mapOptional("hasVAStart", MFI.HasVAStart, false);
548     YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc,
549                        false);
550     YamlIO.mapOptional("localFrameSize", MFI.LocalFrameSize, (unsigned)0);
551     YamlIO.mapOptional("savePoint", MFI.SavePoint,
552                        StringValue()); // Don't print it out when it's empty.
553     YamlIO.mapOptional("restorePoint", MFI.RestorePoint,
554                        StringValue()); // Don't print it out when it's empty.
555   }
556 };
557
558 /// Targets should override this in a way that mirrors the implementation of
559 /// llvm::MachineFunctionInfo.
560 struct MachineFunctionInfo {
561   virtual ~MachineFunctionInfo() {}
562   virtual void mappingImpl(IO &YamlIO) {}
563 };
564
565 template <> struct MappingTraits<std::unique_ptr<MachineFunctionInfo>> {
566   static void mapping(IO &YamlIO, std::unique_ptr<MachineFunctionInfo> &MFI) {
567     if (MFI)
568       MFI->mappingImpl(YamlIO);
569   }
570 };
571
572 struct MachineFunction {
573   StringRef Name;
574   unsigned Alignment = 0;
575   bool ExposesReturnsTwice = false;
576   // GISel MachineFunctionProperties.
577   bool Legalized = false;
578   bool RegBankSelected = false;
579   bool Selected = false;
580   bool FailedISel = false;
581   // Register information
582   bool TracksRegLiveness = false;
583   bool HasWinCFI = false;
584   std::vector<VirtualRegisterDefinition> VirtualRegisters;
585   std::vector<MachineFunctionLiveIn> LiveIns;
586   Optional<std::vector<FlowStringValue>> CalleeSavedRegisters;
587   // TODO: Serialize the various register masks.
588   // Frame information
589   MachineFrameInfo FrameInfo;
590   std::vector<FixedMachineStackObject> FixedStackObjects;
591   std::vector<MachineStackObject> StackObjects;
592   std::vector<MachineConstantPoolValue> Constants; /// Constant pool.
593   std::unique_ptr<MachineFunctionInfo> MachineFuncInfo;
594   std::vector<CallSiteInfo> CallSitesInfo;
595   MachineJumpTable JumpTableInfo;
596   BlockStringValue Body;
597 };
598
599 template <> struct MappingTraits<MachineFunction> {
600   static void mapping(IO &YamlIO, MachineFunction &MF) {
601     YamlIO.mapRequired("name", MF.Name);
602     YamlIO.mapOptional("alignment", MF.Alignment, (unsigned)0);
603     YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice, false);
604     YamlIO.mapOptional("legalized", MF.Legalized, false);
605     YamlIO.mapOptional("regBankSelected", MF.RegBankSelected, false);
606     YamlIO.mapOptional("selected", MF.Selected, false);
607     YamlIO.mapOptional("failedISel", MF.FailedISel, false);
608     YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness, false);
609     YamlIO.mapOptional("hasWinCFI", MF.HasWinCFI, false);
610     YamlIO.mapOptional("registers", MF.VirtualRegisters,
611                        std::vector<VirtualRegisterDefinition>());
612     YamlIO.mapOptional("liveins", MF.LiveIns,
613                        std::vector<MachineFunctionLiveIn>());
614     YamlIO.mapOptional("calleeSavedRegisters", MF.CalleeSavedRegisters,
615                        Optional<std::vector<FlowStringValue>>());
616     YamlIO.mapOptional("frameInfo", MF.FrameInfo, MachineFrameInfo());
617     YamlIO.mapOptional("fixedStack", MF.FixedStackObjects,
618                        std::vector<FixedMachineStackObject>());
619     YamlIO.mapOptional("stack", MF.StackObjects,
620                        std::vector<MachineStackObject>());
621     YamlIO.mapOptional("callSites", MF.CallSitesInfo,
622                        std::vector<CallSiteInfo>());
623     YamlIO.mapOptional("constants", MF.Constants,
624                        std::vector<MachineConstantPoolValue>());
625     YamlIO.mapOptional("machineFunctionInfo", MF.MachineFuncInfo);
626     if (!YamlIO.outputting() || !MF.JumpTableInfo.Entries.empty())
627       YamlIO.mapOptional("jumpTable", MF.JumpTableInfo, MachineJumpTable());
628     YamlIO.mapOptional("body", MF.Body, BlockStringValue());
629   }
630 };
631
632 } // end namespace yaml
633 } // end namespace llvm
634
635 #endif // LLVM_CODEGEN_MIRYAMLMAPPING_H