]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r307894, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / CodeGen / MIRYamlMapping.h
1 //===- MIRYAMLMapping.h - Describes the mapping between MIR and YAML ------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the mapping between various MIR data structures and
11 // their corresponding YAML representation.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H
16 #define LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H
17
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/CodeGen/MachineJumpTableInfo.h"
20 #include "llvm/Support/YAMLTraits.h"
21 #include <vector>
22
23 namespace llvm {
24 namespace yaml {
25
26 /// A wrapper around std::string which contains a source range that's being
27 /// set during parsing.
28 struct StringValue {
29   std::string Value;
30   SMRange SourceRange;
31
32   StringValue() {}
33   StringValue(std::string Value) : Value(std::move(Value)) {}
34
35   bool operator==(const StringValue &Other) const {
36     return Value == Other.Value;
37   }
38 };
39
40 template <> struct ScalarTraits<StringValue> {
41   static void output(const StringValue &S, void *, llvm::raw_ostream &OS) {
42     OS << S.Value;
43   }
44
45   static StringRef input(StringRef Scalar, void *Ctx, StringValue &S) {
46     S.Value = Scalar.str();
47     if (const auto *Node =
48             reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
49       S.SourceRange = Node->getSourceRange();
50     return "";
51   }
52
53   static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
54 };
55
56 struct FlowStringValue : StringValue {
57   FlowStringValue() {}
58   FlowStringValue(std::string Value) : StringValue(std::move(Value)) {}
59 };
60
61 template <> struct ScalarTraits<FlowStringValue> {
62   static void output(const FlowStringValue &S, void *, llvm::raw_ostream &OS) {
63     return ScalarTraits<StringValue>::output(S, nullptr, OS);
64   }
65
66   static StringRef input(StringRef Scalar, void *Ctx, FlowStringValue &S) {
67     return ScalarTraits<StringValue>::input(Scalar, Ctx, S);
68   }
69
70   static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
71 };
72
73 struct BlockStringValue {
74   StringValue Value;
75   bool operator==(const BlockStringValue &Other) const {
76     return Value == Other.Value;
77   }
78 };
79
80 template <> struct BlockScalarTraits<BlockStringValue> {
81   static void output(const BlockStringValue &S, void *Ctx, raw_ostream &OS) {
82     return ScalarTraits<StringValue>::output(S.Value, Ctx, OS);
83   }
84
85   static StringRef input(StringRef Scalar, void *Ctx, BlockStringValue &S) {
86     return ScalarTraits<StringValue>::input(Scalar, Ctx, S.Value);
87   }
88 };
89
90 /// A wrapper around unsigned which contains a source range that's being set
91 /// during parsing.
92 struct UnsignedValue {
93   unsigned Value;
94   SMRange SourceRange;
95
96   UnsignedValue() : Value(0) {}
97   UnsignedValue(unsigned Value) : Value(Value) {}
98
99   bool operator==(const UnsignedValue &Other) const {
100     return Value == Other.Value;
101   }
102 };
103
104 template <> struct ScalarTraits<UnsignedValue> {
105   static void output(const UnsignedValue &Value, void *Ctx, raw_ostream &OS) {
106     return ScalarTraits<unsigned>::output(Value.Value, Ctx, OS);
107   }
108
109   static StringRef input(StringRef Scalar, void *Ctx, UnsignedValue &Value) {
110     if (const auto *Node =
111             reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
112       Value.SourceRange = Node->getSourceRange();
113     return ScalarTraits<unsigned>::input(Scalar, Ctx, Value.Value);
114   }
115
116   static bool mustQuote(StringRef Scalar) {
117     return ScalarTraits<unsigned>::mustQuote(Scalar);
118   }
119 };
120
121 template <> struct ScalarEnumerationTraits<MachineJumpTableInfo::JTEntryKind> {
122   static void enumeration(yaml::IO &IO,
123                           MachineJumpTableInfo::JTEntryKind &EntryKind) {
124     IO.enumCase(EntryKind, "block-address",
125                 MachineJumpTableInfo::EK_BlockAddress);
126     IO.enumCase(EntryKind, "gp-rel64-block-address",
127                 MachineJumpTableInfo::EK_GPRel64BlockAddress);
128     IO.enumCase(EntryKind, "gp-rel32-block-address",
129                 MachineJumpTableInfo::EK_GPRel32BlockAddress);
130     IO.enumCase(EntryKind, "label-difference32",
131                 MachineJumpTableInfo::EK_LabelDifference32);
132     IO.enumCase(EntryKind, "inline", MachineJumpTableInfo::EK_Inline);
133     IO.enumCase(EntryKind, "custom32", MachineJumpTableInfo::EK_Custom32);
134   }
135 };
136
137 } // end namespace yaml
138 } // end namespace llvm
139
140 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue)
141 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue)
142 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::UnsignedValue)
143
144 namespace llvm {
145 namespace yaml {
146
147 struct VirtualRegisterDefinition {
148   UnsignedValue ID;
149   StringValue Class;
150   StringValue PreferredRegister;
151   // TODO: Serialize the target specific register hints.
152   bool operator==(const VirtualRegisterDefinition &Other) const {
153     return ID == Other.ID && Class == Other.Class &&
154            PreferredRegister == Other.PreferredRegister;
155   }
156 };
157
158 template <> struct MappingTraits<VirtualRegisterDefinition> {
159   static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) {
160     YamlIO.mapRequired("id", Reg.ID);
161     YamlIO.mapRequired("class", Reg.Class);
162     YamlIO.mapOptional("preferred-register", Reg.PreferredRegister,
163                        StringValue()); // Don't print out when it's empty.
164   }
165
166   static const bool flow = true;
167 };
168
169 struct MachineFunctionLiveIn {
170   StringValue Register;
171   StringValue VirtualRegister;
172   bool operator==(const MachineFunctionLiveIn &Other) const {
173     return Register == Other.Register &&
174            VirtualRegister == Other.VirtualRegister;
175   }
176 };
177
178 template <> struct MappingTraits<MachineFunctionLiveIn> {
179   static void mapping(IO &YamlIO, MachineFunctionLiveIn &LiveIn) {
180     YamlIO.mapRequired("reg", LiveIn.Register);
181     YamlIO.mapOptional(
182         "virtual-reg", LiveIn.VirtualRegister,
183         StringValue()); // Don't print the virtual register when it's empty.
184   }
185
186   static const bool flow = true;
187 };
188
189 /// Serializable representation of stack object from the MachineFrameInfo class.
190 ///
191 /// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are
192 /// determined by the object's type and frame information flags.
193 /// Dead stack objects aren't serialized.
194 ///
195 /// The 'isPreallocated' flag is determined by the local offset.
196 struct MachineStackObject {
197   enum ObjectType { DefaultType, SpillSlot, VariableSized };
198   UnsignedValue ID;
199   StringValue Name;
200   // TODO: Serialize unnamed LLVM alloca reference.
201   ObjectType Type = DefaultType;
202   int64_t Offset = 0;
203   uint64_t Size = 0;
204   unsigned Alignment = 0;
205   StringValue CalleeSavedRegister;
206   Optional<int64_t> LocalOffset;
207   StringValue DebugVar;
208   StringValue DebugExpr;
209   StringValue DebugLoc;
210   bool operator==(const MachineStackObject &Other) const {
211     return ID == Other.ID && Name == Other.Name && Type == Other.Type &&
212            Offset == Other.Offset && Size == Other.Size &&
213            Alignment == Other.Alignment &&
214            CalleeSavedRegister == Other.CalleeSavedRegister &&
215            LocalOffset == Other.LocalOffset && DebugVar == Other.DebugVar &&
216            DebugExpr == Other.DebugExpr && DebugLoc == Other.DebugLoc;
217   }
218 };
219
220 template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
221   static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type) {
222     IO.enumCase(Type, "default", MachineStackObject::DefaultType);
223     IO.enumCase(Type, "spill-slot", MachineStackObject::SpillSlot);
224     IO.enumCase(Type, "variable-sized", MachineStackObject::VariableSized);
225   }
226 };
227
228 template <> struct MappingTraits<MachineStackObject> {
229   static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) {
230     YamlIO.mapRequired("id", Object.ID);
231     YamlIO.mapOptional("name", Object.Name,
232                        StringValue()); // Don't print out an empty name.
233     YamlIO.mapOptional(
234         "type", Object.Type,
235         MachineStackObject::DefaultType); // Don't print the default type.
236     YamlIO.mapOptional("offset", Object.Offset, (int64_t)0);
237     if (Object.Type != MachineStackObject::VariableSized)
238       YamlIO.mapRequired("size", Object.Size);
239     YamlIO.mapOptional("alignment", Object.Alignment, (unsigned)0);
240     YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
241                        StringValue()); // Don't print it out when it's empty.
242     YamlIO.mapOptional("local-offset", Object.LocalOffset, Optional<int64_t>());
243     YamlIO.mapOptional("di-variable", Object.DebugVar,
244                        StringValue()); // Don't print it out when it's empty.
245     YamlIO.mapOptional("di-expression", Object.DebugExpr,
246                        StringValue()); // Don't print it out when it's empty.
247     YamlIO.mapOptional("di-location", Object.DebugLoc,
248                        StringValue()); // Don't print it out when it's empty.
249   }
250
251   static const bool flow = true;
252 };
253
254 /// Serializable representation of the fixed stack object from the
255 /// MachineFrameInfo class.
256 struct FixedMachineStackObject {
257   enum ObjectType { DefaultType, SpillSlot };
258   UnsignedValue ID;
259   ObjectType Type = DefaultType;
260   int64_t Offset = 0;
261   uint64_t Size = 0;
262   unsigned Alignment = 0;
263   bool IsImmutable = false;
264   bool IsAliased = false;
265   StringValue CalleeSavedRegister;
266   bool operator==(const FixedMachineStackObject &Other) const {
267     return ID == Other.ID && Type == Other.Type && Offset == Other.Offset &&
268            Size == Other.Size && Alignment == Other.Alignment &&
269            IsImmutable == Other.IsImmutable && IsAliased == Other.IsAliased &&
270            CalleeSavedRegister == Other.CalleeSavedRegister;
271   }
272 };
273
274 template <>
275 struct ScalarEnumerationTraits<FixedMachineStackObject::ObjectType> {
276   static void enumeration(yaml::IO &IO,
277                           FixedMachineStackObject::ObjectType &Type) {
278     IO.enumCase(Type, "default", FixedMachineStackObject::DefaultType);
279     IO.enumCase(Type, "spill-slot", FixedMachineStackObject::SpillSlot);
280   }
281 };
282
283 template <> struct MappingTraits<FixedMachineStackObject> {
284   static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) {
285     YamlIO.mapRequired("id", Object.ID);
286     YamlIO.mapOptional(
287         "type", Object.Type,
288         FixedMachineStackObject::DefaultType); // Don't print the default type.
289     YamlIO.mapOptional("offset", Object.Offset, (int64_t)0);
290     YamlIO.mapOptional("size", Object.Size, (uint64_t)0);
291     YamlIO.mapOptional("alignment", Object.Alignment, (unsigned)0);
292     if (Object.Type != FixedMachineStackObject::SpillSlot) {
293       YamlIO.mapOptional("isImmutable", Object.IsImmutable, false);
294       YamlIO.mapOptional("isAliased", Object.IsAliased, false);
295     }
296     YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
297                        StringValue()); // Don't print it out when it's empty.
298   }
299
300   static const bool flow = true;
301 };
302
303 struct MachineConstantPoolValue {
304   UnsignedValue ID;
305   StringValue Value;
306   unsigned Alignment = 0;
307   bool operator==(const MachineConstantPoolValue &Other) const {
308     return ID == Other.ID && Value == Other.Value &&
309            Alignment == Other.Alignment;
310   }
311 };
312
313 template <> struct MappingTraits<MachineConstantPoolValue> {
314   static void mapping(IO &YamlIO, MachineConstantPoolValue &Constant) {
315     YamlIO.mapRequired("id", Constant.ID);
316     YamlIO.mapOptional("value", Constant.Value, StringValue());
317     YamlIO.mapOptional("alignment", Constant.Alignment, (unsigned)0);
318   }
319 };
320
321 struct MachineJumpTable {
322   struct Entry {
323     UnsignedValue ID;
324     std::vector<FlowStringValue> Blocks;
325     bool operator==(const Entry &Other) const {
326       return ID == Other.ID && Blocks == Other.Blocks;
327     }
328   };
329
330   MachineJumpTableInfo::JTEntryKind Kind = MachineJumpTableInfo::EK_Custom32;
331   std::vector<Entry> Entries;
332   bool operator==(const MachineJumpTable &Other) const {
333     return Kind == Other.Kind && Entries == Other.Entries;
334   }
335 };
336
337 template <> struct MappingTraits<MachineJumpTable::Entry> {
338   static void mapping(IO &YamlIO, MachineJumpTable::Entry &Entry) {
339     YamlIO.mapRequired("id", Entry.ID);
340     YamlIO.mapOptional("blocks", Entry.Blocks, std::vector<FlowStringValue>());
341   }
342 };
343
344 } // end namespace yaml
345 } // end namespace llvm
346
347 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineFunctionLiveIn)
348 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
349 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
350 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject)
351 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineConstantPoolValue)
352 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineJumpTable::Entry)
353
354 namespace llvm {
355 namespace yaml {
356
357 template <> struct MappingTraits<MachineJumpTable> {
358   static void mapping(IO &YamlIO, MachineJumpTable &JT) {
359     YamlIO.mapRequired("kind", JT.Kind);
360     YamlIO.mapOptional("entries", JT.Entries,
361                        std::vector<MachineJumpTable::Entry>());
362   }
363 };
364
365 /// Serializable representation of MachineFrameInfo.
366 ///
367 /// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and
368 /// 'RealignOption' as they are determined by the target and LLVM function
369 /// attributes.
370 /// It also doesn't serialize attributes like 'NumFixedObject' and
371 /// 'HasVarSizedObjects' as they are determined by the frame objects themselves.
372 struct MachineFrameInfo {
373   bool IsFrameAddressTaken = false;
374   bool IsReturnAddressTaken = false;
375   bool HasStackMap = false;
376   bool HasPatchPoint = false;
377   uint64_t StackSize = 0;
378   int OffsetAdjustment = 0;
379   unsigned MaxAlignment = 0;
380   bool AdjustsStack = false;
381   bool HasCalls = false;
382   StringValue StackProtector;
383   // TODO: Serialize FunctionContextIdx
384   unsigned MaxCallFrameSize = ~0u; ///< ~0u means: not computed yet.
385   bool HasOpaqueSPAdjustment = false;
386   bool HasVAStart = false;
387   bool HasMustTailInVarArgFunc = false;
388   StringValue SavePoint;
389   StringValue RestorePoint;
390   bool operator==(const MachineFrameInfo &Other) const {
391     return IsFrameAddressTaken == Other.IsFrameAddressTaken &&
392            IsReturnAddressTaken == Other.IsReturnAddressTaken &&
393            HasStackMap == Other.HasStackMap &&
394            HasPatchPoint == Other.HasPatchPoint &&
395            StackSize == Other.StackSize &&
396            OffsetAdjustment == Other.OffsetAdjustment &&
397            MaxAlignment == Other.MaxAlignment &&
398            AdjustsStack == Other.AdjustsStack && HasCalls == Other.HasCalls &&
399            StackProtector == Other.StackProtector &&
400            MaxCallFrameSize == Other.MaxCallFrameSize &&
401            HasOpaqueSPAdjustment == Other.HasOpaqueSPAdjustment &&
402            HasVAStart == Other.HasVAStart &&
403            HasMustTailInVarArgFunc == Other.HasMustTailInVarArgFunc &&
404            SavePoint == Other.SavePoint && RestorePoint == Other.RestorePoint;
405   }
406 };
407
408 template <> struct MappingTraits<MachineFrameInfo> {
409   static void mapping(IO &YamlIO, MachineFrameInfo &MFI) {
410     YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken, false);
411     YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken, false);
412     YamlIO.mapOptional("hasStackMap", MFI.HasStackMap, false);
413     YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint, false);
414     YamlIO.mapOptional("stackSize", MFI.StackSize, (uint64_t)0);
415     YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment, (int)0);
416     YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment, (unsigned)0);
417     YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack, false);
418     YamlIO.mapOptional("hasCalls", MFI.HasCalls, false);
419     YamlIO.mapOptional("stackProtector", MFI.StackProtector,
420                        StringValue()); // Don't print it out when it's empty.
421     YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize, (unsigned)~0);
422     YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment,
423                        false);
424     YamlIO.mapOptional("hasVAStart", MFI.HasVAStart, false);
425     YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc,
426                        false);
427     YamlIO.mapOptional("savePoint", MFI.SavePoint,
428                        StringValue()); // Don't print it out when it's empty.
429     YamlIO.mapOptional("restorePoint", MFI.RestorePoint,
430                        StringValue()); // Don't print it out when it's empty.
431   }
432 };
433
434 struct MachineFunction {
435   StringRef Name;
436   unsigned Alignment = 0;
437   bool ExposesReturnsTwice = false;
438   // GISel MachineFunctionProperties.
439   bool Legalized = false;
440   bool RegBankSelected = false;
441   bool Selected = false;
442   // Register information
443   bool TracksRegLiveness = false;
444   std::vector<VirtualRegisterDefinition> VirtualRegisters;
445   std::vector<MachineFunctionLiveIn> LiveIns;
446   Optional<std::vector<FlowStringValue>> CalleeSavedRegisters;
447   // TODO: Serialize the various register masks.
448   // Frame information
449   MachineFrameInfo FrameInfo;
450   std::vector<FixedMachineStackObject> FixedStackObjects;
451   std::vector<MachineStackObject> StackObjects;
452   std::vector<MachineConstantPoolValue> Constants; /// Constant pool.
453   MachineJumpTable JumpTableInfo;
454   BlockStringValue Body;
455 };
456
457 template <> struct MappingTraits<MachineFunction> {
458   static void mapping(IO &YamlIO, MachineFunction &MF) {
459     YamlIO.mapRequired("name", MF.Name);
460     YamlIO.mapOptional("alignment", MF.Alignment, (unsigned)0);
461     YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice, false);
462     YamlIO.mapOptional("legalized", MF.Legalized, false);
463     YamlIO.mapOptional("regBankSelected", MF.RegBankSelected, false);
464     YamlIO.mapOptional("selected", MF.Selected, false);
465     YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness, false);
466     YamlIO.mapOptional("registers", MF.VirtualRegisters,
467                        std::vector<VirtualRegisterDefinition>());
468     YamlIO.mapOptional("liveins", MF.LiveIns,
469                        std::vector<MachineFunctionLiveIn>());
470     YamlIO.mapOptional("calleeSavedRegisters", MF.CalleeSavedRegisters,
471                        Optional<std::vector<FlowStringValue>>());
472     YamlIO.mapOptional("frameInfo", MF.FrameInfo, MachineFrameInfo());
473     YamlIO.mapOptional("fixedStack", MF.FixedStackObjects,
474                        std::vector<FixedMachineStackObject>());
475     YamlIO.mapOptional("stack", MF.StackObjects,
476                        std::vector<MachineStackObject>());
477     YamlIO.mapOptional("constants", MF.Constants,
478                        std::vector<MachineConstantPoolValue>());
479     if (!YamlIO.outputting() || !MF.JumpTableInfo.Entries.empty())
480       YamlIO.mapOptional("jumpTable", MF.JumpTableInfo, MachineJumpTable());
481     YamlIO.mapOptional("body", MF.Body, BlockStringValue());
482   }
483 };
484
485 } // end namespace yaml
486 } // end namespace llvm
487
488 #endif