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