MIRYamlMapping.h revision 287506
1206089Sfabient//===- MIRYAMLMapping.h - Describes the mapping between MIR and YAML ------===//
2206089Sfabient//
3206089Sfabient//                     The LLVM Compiler Infrastructure
4206089Sfabient//
5206089Sfabient// This file is distributed under the University of Illinois Open Source
6206089Sfabient// License. See LICENSE.TXT for details.
7206089Sfabient//
8206089Sfabient//===----------------------------------------------------------------------===//
9206089Sfabient//
10206089Sfabient// The MIR serialization library is currently a work in progress. It can't
11206089Sfabient// serialize machine functions at this time.
12231871Sbrueffer//
13231871Sbrueffer// This file implements the mapping between various MIR data structures and
14231871Sbrueffer// their corresponding YAML representation.
15231871Sbrueffer//
16231871Sbrueffer//===----------------------------------------------------------------------===//
17231871Sbrueffer
18231871Sbrueffer#ifndef LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H
19231871Sbrueffer#define LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H
20231871Sbrueffer
21231871Sbrueffer#include "llvm/ADT/StringRef.h"
22231871Sbrueffer#include "llvm/Support/YAMLTraits.h"
23206089Sfabient#include <vector>
24206089Sfabient
25206089Sfabientnamespace llvm {
26206089Sfabientnamespace yaml {
27206622Suqs
28206089Sfabient/// A wrapper around std::string which contains a source range that's being
29206089Sfabient/// set during parsing.
30206089Sfabientstruct StringValue {
31206089Sfabient  std::string Value;
32206089Sfabient  SMRange SourceRange;
33206089Sfabient
34206089Sfabient  StringValue() {}
35206089Sfabient  StringValue(std::string Value) : Value(std::move(Value)) {}
36206089Sfabient
37206089Sfabient  bool operator==(const StringValue &Other) const {
38206089Sfabient    return Value == Other.Value;
39206089Sfabient  }
40206089Sfabient};
41206089Sfabient
42206089Sfabienttemplate <> struct ScalarTraits<StringValue> {
43206089Sfabient  static void output(const StringValue &S, void *, llvm::raw_ostream &OS) {
44206089Sfabient    OS << S.Value;
45206089Sfabient  }
46206089Sfabient
47206089Sfabient  static StringRef input(StringRef Scalar, void *Ctx, StringValue &S) {
48206089Sfabient    S.Value = Scalar.str();
49206089Sfabient    if (const auto *Node =
50206089Sfabient            reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
51206089Sfabient      S.SourceRange = Node->getSourceRange();
52206089Sfabient    return "";
53206089Sfabient  }
54206089Sfabient
55206089Sfabient  static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
56206089Sfabient};
57206089Sfabient
58206089Sfabientstruct FlowStringValue : StringValue {
59206089Sfabient  FlowStringValue() {}
60206089Sfabient  FlowStringValue(std::string Value) : StringValue(Value) {}
61206089Sfabient};
62206089Sfabient
63206089Sfabienttemplate <> struct ScalarTraits<FlowStringValue> {
64206089Sfabient  static void output(const FlowStringValue &S, void *, llvm::raw_ostream &OS) {
65206089Sfabient    return ScalarTraits<StringValue>::output(S, nullptr, OS);
66206089Sfabient  }
67206089Sfabient
68206089Sfabient  static StringRef input(StringRef Scalar, void *Ctx, FlowStringValue &S) {
69206089Sfabient    return ScalarTraits<StringValue>::input(Scalar, Ctx, S);
70206089Sfabient  }
71206089Sfabient
72206089Sfabient  static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
73206089Sfabient};
74206089Sfabient
75206089Sfabient} // end namespace yaml
76206089Sfabient} // end namespace llvm
77206089Sfabient
78206089SfabientLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue)
79206089SfabientLLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue)
80206089Sfabient
81206089Sfabientnamespace llvm {
82206089Sfabientnamespace yaml {
83206089Sfabient
84206089Sfabientstruct VirtualRegisterDefinition {
85206089Sfabient  unsigned ID;
86206089Sfabient  StringValue Class;
87206089Sfabient  // TODO: Serialize the virtual register hints.
88206089Sfabient};
89206089Sfabient
90206089Sfabienttemplate <> struct MappingTraits<VirtualRegisterDefinition> {
91206089Sfabient  static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) {
92206089Sfabient    YamlIO.mapRequired("id", Reg.ID);
93206089Sfabient    YamlIO.mapRequired("class", Reg.Class);
94206089Sfabient  }
95206089Sfabient
96206089Sfabient  static const bool flow = true;
97206089Sfabient};
98206089Sfabient
99206089Sfabientstruct MachineBasicBlock {
100206089Sfabient  unsigned ID;
101206089Sfabient  StringValue Name;
102206089Sfabient  unsigned Alignment = 0;
103206089Sfabient  bool IsLandingPad = false;
104206089Sfabient  bool AddressTaken = false;
105206089Sfabient  // TODO: Serialize the successor weights.
106206089Sfabient  std::vector<FlowStringValue> Successors;
107206089Sfabient  std::vector<FlowStringValue> LiveIns;
108206089Sfabient  std::vector<StringValue> Instructions;
109206089Sfabient};
110206089Sfabient
111206089Sfabienttemplate <> struct MappingTraits<MachineBasicBlock> {
112206089Sfabient  static void mapping(IO &YamlIO, MachineBasicBlock &MBB) {
113206089Sfabient    YamlIO.mapRequired("id", MBB.ID);
114206089Sfabient    YamlIO.mapOptional("name", MBB.Name,
115206089Sfabient                       StringValue()); // Don't print out an empty name.
116206089Sfabient    YamlIO.mapOptional("alignment", MBB.Alignment);
117206089Sfabient    YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad);
118206089Sfabient    YamlIO.mapOptional("addressTaken", MBB.AddressTaken);
119206089Sfabient    YamlIO.mapOptional("successors", MBB.Successors);
120206089Sfabient    YamlIO.mapOptional("liveins", MBB.LiveIns);
121206089Sfabient    YamlIO.mapOptional("instructions", MBB.Instructions);
122206089Sfabient  }
123206089Sfabient};
124206089Sfabient
125206089Sfabient/// Serializable representation of stack object from the MachineFrameInfo class.
126206089Sfabient///
127206089Sfabient/// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are
128206089Sfabient/// determined by the object's type and frame information flags.
129206089Sfabient/// Dead stack objects aren't serialized.
130206089Sfabient///
131206089Sfabient/// TODO: Determine isPreallocated flag by mapping between objects and local
132206089Sfabient/// objects (Serialize local objects).
133206089Sfabientstruct MachineStackObject {
134206089Sfabient  enum ObjectType { DefaultType, SpillSlot, VariableSized };
135206089Sfabient  // TODO: Serialize LLVM alloca reference.
136206089Sfabient  unsigned ID;
137206089Sfabient  ObjectType Type = DefaultType;
138206089Sfabient  int64_t Offset = 0;
139206089Sfabient  uint64_t Size = 0;
140206089Sfabient  unsigned Alignment = 0;
141206089Sfabient};
142206089Sfabient
143206089Sfabienttemplate <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
144206089Sfabient  static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type) {
145206089Sfabient    IO.enumCase(Type, "default", MachineStackObject::DefaultType);
146206089Sfabient    IO.enumCase(Type, "spill-slot", MachineStackObject::SpillSlot);
147206089Sfabient    IO.enumCase(Type, "variable-sized", MachineStackObject::VariableSized);
148206089Sfabient  }
149206089Sfabient};
150206089Sfabient
151206089Sfabienttemplate <> struct MappingTraits<MachineStackObject> {
152206089Sfabient  static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) {
153206089Sfabient    YamlIO.mapRequired("id", Object.ID);
154208914Suqs    YamlIO.mapOptional(
155206089Sfabient        "type", Object.Type,
156206089Sfabient        MachineStackObject::DefaultType); // Don't print the default type.
157206089Sfabient    YamlIO.mapOptional("offset", Object.Offset);
158206089Sfabient    if (Object.Type != MachineStackObject::VariableSized)
159206089Sfabient      YamlIO.mapRequired("size", Object.Size);
160206089Sfabient    YamlIO.mapOptional("alignment", Object.Alignment);
161208914Suqs  }
162206089Sfabient
163206089Sfabient  static const bool flow = true;
164206089Sfabient};
165206089Sfabient
166206089Sfabient/// Serializable representation of the fixed stack object from the
167206089Sfabient/// MachineFrameInfo class.
168206089Sfabientstruct FixedMachineStackObject {
169206089Sfabient  enum ObjectType { DefaultType, SpillSlot };
170206089Sfabient  unsigned ID;
171206089Sfabient  ObjectType Type = DefaultType;
172206089Sfabient  int64_t Offset = 0;
173206089Sfabient  uint64_t Size = 0;
174206089Sfabient  unsigned Alignment = 0;
175206089Sfabient  bool IsImmutable = false;
176206089Sfabient  bool IsAliased = false;
177206089Sfabient};
178206089Sfabient
179206089Sfabienttemplate <>
180206089Sfabientstruct ScalarEnumerationTraits<FixedMachineStackObject::ObjectType> {
181206089Sfabient  static void enumeration(yaml::IO &IO,
182206089Sfabient                          FixedMachineStackObject::ObjectType &Type) {
183206089Sfabient    IO.enumCase(Type, "default", FixedMachineStackObject::DefaultType);
184206089Sfabient    IO.enumCase(Type, "spill-slot", FixedMachineStackObject::SpillSlot);
185206089Sfabient  }
186206089Sfabient};
187206089Sfabient
188206089Sfabienttemplate <> struct MappingTraits<FixedMachineStackObject> {
189206089Sfabient  static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) {
190206089Sfabient    YamlIO.mapRequired("id", Object.ID);
191206089Sfabient    YamlIO.mapOptional(
192206089Sfabient        "type", Object.Type,
193206089Sfabient        FixedMachineStackObject::DefaultType); // Don't print the default type.
194206089Sfabient    YamlIO.mapOptional("offset", Object.Offset);
195206089Sfabient    YamlIO.mapOptional("size", Object.Size);
196206089Sfabient    YamlIO.mapOptional("alignment", Object.Alignment);
197206089Sfabient    if (Object.Type != FixedMachineStackObject::SpillSlot) {
198206089Sfabient      YamlIO.mapOptional("isImmutable", Object.IsImmutable);
199206089Sfabient      YamlIO.mapOptional("isAliased", Object.IsAliased);
200206089Sfabient    }
201206089Sfabient  }
202206089Sfabient
203206089Sfabient  static const bool flow = true;
204206089Sfabient};
205206089Sfabient
206206089Sfabient} // end namespace yaml
207206089Sfabient} // end namespace llvm
208206089Sfabient
209206089SfabientLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
210206089SfabientLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock)
211206089SfabientLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
212206089SfabientLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject)
213206089Sfabient
214206089Sfabientnamespace llvm {
215206089Sfabientnamespace yaml {
216206089Sfabient
217206089Sfabient/// Serializable representation of MachineFrameInfo.
218206089Sfabient///
219206089Sfabient/// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and
220206089Sfabient/// 'RealignOption' as they are determined by the target and LLVM function
221206089Sfabient/// attributes.
222206089Sfabient/// It also doesn't serialize attributes like 'NumFixedObject' and
223206089Sfabient/// 'HasVarSizedObjects' as they are determined by the frame objects themselves.
224206089Sfabientstruct MachineFrameInfo {
225206089Sfabient  bool IsFrameAddressTaken = false;
226206089Sfabient  bool IsReturnAddressTaken = false;
227206089Sfabient  bool HasStackMap = false;
228206089Sfabient  bool HasPatchPoint = false;
229206089Sfabient  uint64_t StackSize = 0;
230206089Sfabient  int OffsetAdjustment = 0;
231206089Sfabient  unsigned MaxAlignment = 0;
232206089Sfabient  bool AdjustsStack = false;
233206089Sfabient  bool HasCalls = false;
234206089Sfabient  // TODO: Serialize StackProtectorIdx and FunctionContextIdx
235206089Sfabient  unsigned MaxCallFrameSize = 0;
236206089Sfabient  // TODO: Serialize callee saved info.
237206089Sfabient  // TODO: Serialize local frame objects.
238206089Sfabient  bool HasOpaqueSPAdjustment = false;
239206089Sfabient  bool HasVAStart = false;
240206089Sfabient  bool HasMustTailInVarArgFunc = false;
241206089Sfabient  // TODO: Serialize save and restore MBB references.
242206089Sfabient};
243206089Sfabient
244206089Sfabienttemplate <> struct MappingTraits<MachineFrameInfo> {
245206089Sfabient  static void mapping(IO &YamlIO, MachineFrameInfo &MFI) {
246206089Sfabient    YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken);
247206089Sfabient    YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken);
248206089Sfabient    YamlIO.mapOptional("hasStackMap", MFI.HasStackMap);
249206089Sfabient    YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint);
250206089Sfabient    YamlIO.mapOptional("stackSize", MFI.StackSize);
251206089Sfabient    YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment);
252206089Sfabient    YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment);
253206089Sfabient    YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack);
254206089Sfabient    YamlIO.mapOptional("hasCalls", MFI.HasCalls);
255206089Sfabient    YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize);
256206089Sfabient    YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment);
257206089Sfabient    YamlIO.mapOptional("hasVAStart", MFI.HasVAStart);
258206089Sfabient    YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc);
259206089Sfabient  }
260206089Sfabient};
261206089Sfabient
262206089Sfabientstruct MachineFunction {
263206089Sfabient  StringRef Name;
264206089Sfabient  unsigned Alignment = 0;
265206089Sfabient  bool ExposesReturnsTwice = false;
266206089Sfabient  bool HasInlineAsm = false;
267206089Sfabient  // Register information
268206089Sfabient  bool IsSSA = false;
269206089Sfabient  bool TracksRegLiveness = false;
270206089Sfabient  bool TracksSubRegLiveness = false;
271206089Sfabient  std::vector<VirtualRegisterDefinition> VirtualRegisters;
272206089Sfabient  // TODO: Serialize the various register masks.
273206089Sfabient  // TODO: Serialize live in registers.
274206089Sfabient  // Frame information
275206089Sfabient  MachineFrameInfo FrameInfo;
276206089Sfabient  std::vector<FixedMachineStackObject> FixedStackObjects;
277206089Sfabient  std::vector<MachineStackObject> StackObjects;
278206089Sfabient
279206089Sfabient  std::vector<MachineBasicBlock> BasicBlocks;
280206089Sfabient};
281206089Sfabient
282206089Sfabienttemplate <> struct MappingTraits<MachineFunction> {
283206089Sfabient  static void mapping(IO &YamlIO, MachineFunction &MF) {
284206089Sfabient    YamlIO.mapRequired("name", MF.Name);
285206089Sfabient    YamlIO.mapOptional("alignment", MF.Alignment);
286206089Sfabient    YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice);
287206089Sfabient    YamlIO.mapOptional("hasInlineAsm", MF.HasInlineAsm);
288206089Sfabient    YamlIO.mapOptional("isSSA", MF.IsSSA);
289206089Sfabient    YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness);
290206089Sfabient    YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness);
291206089Sfabient    YamlIO.mapOptional("registers", MF.VirtualRegisters);
292206089Sfabient    YamlIO.mapOptional("frameInfo", MF.FrameInfo);
293206089Sfabient    YamlIO.mapOptional("fixedStack", MF.FixedStackObjects);
294206089Sfabient    YamlIO.mapOptional("stack", MF.StackObjects);
295206089Sfabient    YamlIO.mapOptional("body", MF.BasicBlocks);
296206089Sfabient  }
297206089Sfabient};
298206089Sfabient
299206089Sfabient} // end namespace yaml
300206089Sfabient} // end namespace llvm
301206089Sfabient
302206089Sfabient#endif
303206089Sfabient