1 //===- MIRYAMLMapping.h - Describes the mapping between MIR and YAML ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // The MIR serialization library is currently a work in progress. It can't
11 // serialize machine functions at this time.
13 // This file implements the mapping between various MIR data structures and
14 // their corresponding YAML representation.
16 //===----------------------------------------------------------------------===//
18 #ifndef LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H
19 #define LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/CodeGen/MachineJumpTableInfo.h"
23 #include "llvm/Support/YAMLTraits.h"
29 /// A wrapper around std::string which contains a source range that's being
30 /// set during parsing.
36 StringValue(std::string Value) : Value(std::move(Value)) {}
38 bool operator==(const StringValue &Other) const {
39 return Value == Other.Value;
43 template <> struct ScalarTraits<StringValue> {
44 static void output(const StringValue &S, void *, llvm::raw_ostream &OS) {
48 static StringRef input(StringRef Scalar, void *Ctx, StringValue &S) {
49 S.Value = Scalar.str();
50 if (const auto *Node =
51 reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
52 S.SourceRange = Node->getSourceRange();
56 static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
59 struct FlowStringValue : StringValue {
61 FlowStringValue(std::string Value) : StringValue(Value) {}
64 template <> struct ScalarTraits<FlowStringValue> {
65 static void output(const FlowStringValue &S, void *, llvm::raw_ostream &OS) {
66 return ScalarTraits<StringValue>::output(S, nullptr, OS);
69 static StringRef input(StringRef Scalar, void *Ctx, FlowStringValue &S) {
70 return ScalarTraits<StringValue>::input(Scalar, Ctx, S);
73 static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
76 template <> struct ScalarEnumerationTraits<MachineJumpTableInfo::JTEntryKind> {
77 static void enumeration(yaml::IO &IO,
78 MachineJumpTableInfo::JTEntryKind &EntryKind) {
79 IO.enumCase(EntryKind, "block-address",
80 MachineJumpTableInfo::EK_BlockAddress);
81 IO.enumCase(EntryKind, "gp-rel64-block-address",
82 MachineJumpTableInfo::EK_GPRel64BlockAddress);
83 IO.enumCase(EntryKind, "gp-rel32-block-address",
84 MachineJumpTableInfo::EK_GPRel32BlockAddress);
85 IO.enumCase(EntryKind, "label-difference32",
86 MachineJumpTableInfo::EK_LabelDifference32);
87 IO.enumCase(EntryKind, "inline", MachineJumpTableInfo::EK_Inline);
88 IO.enumCase(EntryKind, "custom32", MachineJumpTableInfo::EK_Custom32);
92 } // end namespace yaml
93 } // end namespace llvm
95 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue)
96 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue)
101 struct VirtualRegisterDefinition {
104 StringValue PreferredRegister;
105 // TODO: Serialize the target specific register hints.
108 template <> struct MappingTraits<VirtualRegisterDefinition> {
109 static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) {
110 YamlIO.mapRequired("id", Reg.ID);
111 YamlIO.mapRequired("class", Reg.Class);
112 YamlIO.mapOptional("preferred-register", Reg.PreferredRegister,
113 StringValue()); // Don't print out when it's empty.
116 static const bool flow = true;
119 struct MachineBasicBlock {
122 unsigned Alignment = 0;
123 bool IsLandingPad = false;
124 bool AddressTaken = false;
125 // TODO: Serialize the successor weights.
126 std::vector<FlowStringValue> Successors;
127 std::vector<FlowStringValue> LiveIns;
128 std::vector<StringValue> Instructions;
131 template <> struct MappingTraits<MachineBasicBlock> {
132 static void mapping(IO &YamlIO, MachineBasicBlock &MBB) {
133 YamlIO.mapRequired("id", MBB.ID);
134 YamlIO.mapOptional("name", MBB.Name,
135 StringValue()); // Don't print out an empty name.
136 YamlIO.mapOptional("alignment", MBB.Alignment);
137 YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad);
138 YamlIO.mapOptional("addressTaken", MBB.AddressTaken);
139 YamlIO.mapOptional("successors", MBB.Successors);
140 YamlIO.mapOptional("liveins", MBB.LiveIns);
141 YamlIO.mapOptional("instructions", MBB.Instructions);
145 /// Serializable representation of stack object from the MachineFrameInfo class.
147 /// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are
148 /// determined by the object's type and frame information flags.
149 /// Dead stack objects aren't serialized.
151 /// TODO: Determine isPreallocated flag by mapping between objects and local
152 /// objects (Serialize local objects).
153 struct MachineStackObject {
154 enum ObjectType { DefaultType, SpillSlot, VariableSized };
157 // TODO: Serialize unnamed LLVM alloca reference.
158 ObjectType Type = DefaultType;
161 unsigned Alignment = 0;
164 template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
165 static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type) {
166 IO.enumCase(Type, "default", MachineStackObject::DefaultType);
167 IO.enumCase(Type, "spill-slot", MachineStackObject::SpillSlot);
168 IO.enumCase(Type, "variable-sized", MachineStackObject::VariableSized);
172 template <> struct MappingTraits<MachineStackObject> {
173 static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) {
174 YamlIO.mapRequired("id", Object.ID);
175 YamlIO.mapOptional("name", Object.Name,
176 StringValue()); // Don't print out an empty name.
179 MachineStackObject::DefaultType); // Don't print the default type.
180 YamlIO.mapOptional("offset", Object.Offset);
181 if (Object.Type != MachineStackObject::VariableSized)
182 YamlIO.mapRequired("size", Object.Size);
183 YamlIO.mapOptional("alignment", Object.Alignment);
186 static const bool flow = true;
189 /// Serializable representation of the fixed stack object from the
190 /// MachineFrameInfo class.
191 struct FixedMachineStackObject {
192 enum ObjectType { DefaultType, SpillSlot };
194 ObjectType Type = DefaultType;
197 unsigned Alignment = 0;
198 bool IsImmutable = false;
199 bool IsAliased = false;
203 struct ScalarEnumerationTraits<FixedMachineStackObject::ObjectType> {
204 static void enumeration(yaml::IO &IO,
205 FixedMachineStackObject::ObjectType &Type) {
206 IO.enumCase(Type, "default", FixedMachineStackObject::DefaultType);
207 IO.enumCase(Type, "spill-slot", FixedMachineStackObject::SpillSlot);
211 template <> struct MappingTraits<FixedMachineStackObject> {
212 static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) {
213 YamlIO.mapRequired("id", Object.ID);
216 FixedMachineStackObject::DefaultType); // Don't print the default type.
217 YamlIO.mapOptional("offset", Object.Offset);
218 YamlIO.mapOptional("size", Object.Size);
219 YamlIO.mapOptional("alignment", Object.Alignment);
220 if (Object.Type != FixedMachineStackObject::SpillSlot) {
221 YamlIO.mapOptional("isImmutable", Object.IsImmutable);
222 YamlIO.mapOptional("isAliased", Object.IsAliased);
226 static const bool flow = true;
229 struct MachineConstantPoolValue {
232 unsigned Alignment = 0;
235 template <> struct MappingTraits<MachineConstantPoolValue> {
236 static void mapping(IO &YamlIO, MachineConstantPoolValue &Constant) {
237 YamlIO.mapRequired("id", Constant.ID);
238 YamlIO.mapOptional("value", Constant.Value);
239 YamlIO.mapOptional("alignment", Constant.Alignment);
243 struct MachineJumpTable {
246 std::vector<FlowStringValue> Blocks;
249 MachineJumpTableInfo::JTEntryKind Kind = MachineJumpTableInfo::EK_Custom32;
250 std::vector<Entry> Entries;
253 template <> struct MappingTraits<MachineJumpTable::Entry> {
254 static void mapping(IO &YamlIO, MachineJumpTable::Entry &Entry) {
255 YamlIO.mapRequired("id", Entry.ID);
256 YamlIO.mapOptional("blocks", Entry.Blocks);
260 } // end namespace yaml
261 } // end namespace llvm
263 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
264 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock)
265 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
266 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject)
267 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineConstantPoolValue)
268 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineJumpTable::Entry)
273 template <> struct MappingTraits<MachineJumpTable> {
274 static void mapping(IO &YamlIO, MachineJumpTable &JT) {
275 YamlIO.mapRequired("kind", JT.Kind);
276 YamlIO.mapOptional("entries", JT.Entries);
280 /// Serializable representation of MachineFrameInfo.
282 /// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and
283 /// 'RealignOption' as they are determined by the target and LLVM function
285 /// It also doesn't serialize attributes like 'NumFixedObject' and
286 /// 'HasVarSizedObjects' as they are determined by the frame objects themselves.
287 struct MachineFrameInfo {
288 bool IsFrameAddressTaken = false;
289 bool IsReturnAddressTaken = false;
290 bool HasStackMap = false;
291 bool HasPatchPoint = false;
292 uint64_t StackSize = 0;
293 int OffsetAdjustment = 0;
294 unsigned MaxAlignment = 0;
295 bool AdjustsStack = false;
296 bool HasCalls = false;
297 // TODO: Serialize StackProtectorIdx and FunctionContextIdx
298 unsigned MaxCallFrameSize = 0;
299 // TODO: Serialize callee saved info.
300 // TODO: Serialize local frame objects.
301 bool HasOpaqueSPAdjustment = false;
302 bool HasVAStart = false;
303 bool HasMustTailInVarArgFunc = false;
304 // TODO: Serialize save and restore MBB references.
307 template <> struct MappingTraits<MachineFrameInfo> {
308 static void mapping(IO &YamlIO, MachineFrameInfo &MFI) {
309 YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken);
310 YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken);
311 YamlIO.mapOptional("hasStackMap", MFI.HasStackMap);
312 YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint);
313 YamlIO.mapOptional("stackSize", MFI.StackSize);
314 YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment);
315 YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment);
316 YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack);
317 YamlIO.mapOptional("hasCalls", MFI.HasCalls);
318 YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize);
319 YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment);
320 YamlIO.mapOptional("hasVAStart", MFI.HasVAStart);
321 YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc);
325 struct MachineFunction {
327 unsigned Alignment = 0;
328 bool ExposesReturnsTwice = false;
329 bool HasInlineAsm = false;
330 // Register information
332 bool TracksRegLiveness = false;
333 bool TracksSubRegLiveness = false;
334 std::vector<VirtualRegisterDefinition> VirtualRegisters;
335 // TODO: Serialize the various register masks.
336 // TODO: Serialize live in registers.
338 MachineFrameInfo FrameInfo;
339 std::vector<FixedMachineStackObject> FixedStackObjects;
340 std::vector<MachineStackObject> StackObjects;
341 std::vector<MachineConstantPoolValue> Constants; /// Constant pool.
342 MachineJumpTable JumpTableInfo;
344 std::vector<MachineBasicBlock> BasicBlocks;
347 template <> struct MappingTraits<MachineFunction> {
348 static void mapping(IO &YamlIO, MachineFunction &MF) {
349 YamlIO.mapRequired("name", MF.Name);
350 YamlIO.mapOptional("alignment", MF.Alignment);
351 YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice);
352 YamlIO.mapOptional("hasInlineAsm", MF.HasInlineAsm);
353 YamlIO.mapOptional("isSSA", MF.IsSSA);
354 YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness);
355 YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness);
356 YamlIO.mapOptional("registers", MF.VirtualRegisters);
357 YamlIO.mapOptional("frameInfo", MF.FrameInfo);
358 YamlIO.mapOptional("fixedStack", MF.FixedStackObjects);
359 YamlIO.mapOptional("stack", MF.StackObjects);
360 YamlIO.mapOptional("constants", MF.Constants);
361 if (!YamlIO.outputting() || !MF.JumpTableInfo.Entries.empty())
362 YamlIO.mapOptional("jumpTable", MF.JumpTableInfo);
363 YamlIO.mapOptional("body", MF.BasicBlocks);
367 } // end namespace yaml
368 } // end namespace llvm