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/Support/YAMLTraits.h"
28 /// A wrapper around std::string which contains a source range that's being
29 /// set during parsing.
35 StringValue(std::string Value) : Value(std::move(Value)) {}
37 bool operator==(const StringValue &Other) const {
38 return Value == Other.Value;
42 template <> struct ScalarTraits<StringValue> {
43 static void output(const StringValue &S, void *, llvm::raw_ostream &OS) {
47 static StringRef input(StringRef Scalar, void *Ctx, StringValue &S) {
48 S.Value = Scalar.str();
49 if (const auto *Node =
50 reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
51 S.SourceRange = Node->getSourceRange();
55 static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
58 struct FlowStringValue : StringValue {
60 FlowStringValue(std::string Value) : StringValue(Value) {}
63 template <> struct ScalarTraits<FlowStringValue> {
64 static void output(const FlowStringValue &S, void *, llvm::raw_ostream &OS) {
65 return ScalarTraits<StringValue>::output(S, nullptr, OS);
68 static StringRef input(StringRef Scalar, void *Ctx, FlowStringValue &S) {
69 return ScalarTraits<StringValue>::input(Scalar, Ctx, S);
72 static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
75 } // end namespace yaml
76 } // end namespace llvm
78 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue)
79 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue)
84 struct VirtualRegisterDefinition {
87 // TODO: Serialize the virtual register hints.
90 template <> struct MappingTraits<VirtualRegisterDefinition> {
91 static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) {
92 YamlIO.mapRequired("id", Reg.ID);
93 YamlIO.mapRequired("class", Reg.Class);
96 static const bool flow = true;
99 struct MachineBasicBlock {
102 unsigned Alignment = 0;
103 bool IsLandingPad = false;
104 bool AddressTaken = false;
105 // TODO: Serialize the successor weights.
106 std::vector<FlowStringValue> Successors;
107 std::vector<FlowStringValue> LiveIns;
108 std::vector<StringValue> Instructions;
111 template <> struct MappingTraits<MachineBasicBlock> {
112 static void mapping(IO &YamlIO, MachineBasicBlock &MBB) {
113 YamlIO.mapRequired("id", MBB.ID);
114 YamlIO.mapOptional("name", MBB.Name,
115 StringValue()); // Don't print out an empty name.
116 YamlIO.mapOptional("alignment", MBB.Alignment);
117 YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad);
118 YamlIO.mapOptional("addressTaken", MBB.AddressTaken);
119 YamlIO.mapOptional("successors", MBB.Successors);
120 YamlIO.mapOptional("liveins", MBB.LiveIns);
121 YamlIO.mapOptional("instructions", MBB.Instructions);
125 /// Serializable representation of stack object from the MachineFrameInfo class.
127 /// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are
128 /// determined by the object's type and frame information flags.
129 /// Dead stack objects aren't serialized.
131 /// TODO: Determine isPreallocated flag by mapping between objects and local
132 /// objects (Serialize local objects).
133 struct MachineStackObject {
134 enum ObjectType { DefaultType, SpillSlot, VariableSized };
135 // TODO: Serialize LLVM alloca reference.
137 ObjectType Type = DefaultType;
140 unsigned Alignment = 0;
143 template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
144 static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type) {
145 IO.enumCase(Type, "default", MachineStackObject::DefaultType);
146 IO.enumCase(Type, "spill-slot", MachineStackObject::SpillSlot);
147 IO.enumCase(Type, "variable-sized", MachineStackObject::VariableSized);
151 template <> struct MappingTraits<MachineStackObject> {
152 static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) {
153 YamlIO.mapRequired("id", Object.ID);
156 MachineStackObject::DefaultType); // Don't print the default type.
157 YamlIO.mapOptional("offset", Object.Offset);
158 if (Object.Type != MachineStackObject::VariableSized)
159 YamlIO.mapRequired("size", Object.Size);
160 YamlIO.mapOptional("alignment", Object.Alignment);
163 static const bool flow = true;
166 /// Serializable representation of the fixed stack object from the
167 /// MachineFrameInfo class.
168 struct FixedMachineStackObject {
169 enum ObjectType { DefaultType, SpillSlot };
171 ObjectType Type = DefaultType;
174 unsigned Alignment = 0;
175 bool IsImmutable = false;
176 bool IsAliased = false;
180 struct ScalarEnumerationTraits<FixedMachineStackObject::ObjectType> {
181 static void enumeration(yaml::IO &IO,
182 FixedMachineStackObject::ObjectType &Type) {
183 IO.enumCase(Type, "default", FixedMachineStackObject::DefaultType);
184 IO.enumCase(Type, "spill-slot", FixedMachineStackObject::SpillSlot);
188 template <> struct MappingTraits<FixedMachineStackObject> {
189 static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) {
190 YamlIO.mapRequired("id", Object.ID);
193 FixedMachineStackObject::DefaultType); // Don't print the default type.
194 YamlIO.mapOptional("offset", Object.Offset);
195 YamlIO.mapOptional("size", Object.Size);
196 YamlIO.mapOptional("alignment", Object.Alignment);
197 if (Object.Type != FixedMachineStackObject::SpillSlot) {
198 YamlIO.mapOptional("isImmutable", Object.IsImmutable);
199 YamlIO.mapOptional("isAliased", Object.IsAliased);
203 static const bool flow = true;
206 } // end namespace yaml
207 } // end namespace llvm
209 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
210 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock)
211 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
212 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject)
217 /// Serializable representation of MachineFrameInfo.
219 /// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and
220 /// 'RealignOption' as they are determined by the target and LLVM function
222 /// It also doesn't serialize attributes like 'NumFixedObject' and
223 /// 'HasVarSizedObjects' as they are determined by the frame objects themselves.
224 struct MachineFrameInfo {
225 bool IsFrameAddressTaken = false;
226 bool IsReturnAddressTaken = false;
227 bool HasStackMap = false;
228 bool HasPatchPoint = false;
229 uint64_t StackSize = 0;
230 int OffsetAdjustment = 0;
231 unsigned MaxAlignment = 0;
232 bool AdjustsStack = false;
233 bool HasCalls = false;
234 // TODO: Serialize StackProtectorIdx and FunctionContextIdx
235 unsigned MaxCallFrameSize = 0;
236 // TODO: Serialize callee saved info.
237 // TODO: Serialize local frame objects.
238 bool HasOpaqueSPAdjustment = false;
239 bool HasVAStart = false;
240 bool HasMustTailInVarArgFunc = false;
241 // TODO: Serialize save and restore MBB references.
244 template <> struct MappingTraits<MachineFrameInfo> {
245 static void mapping(IO &YamlIO, MachineFrameInfo &MFI) {
246 YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken);
247 YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken);
248 YamlIO.mapOptional("hasStackMap", MFI.HasStackMap);
249 YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint);
250 YamlIO.mapOptional("stackSize", MFI.StackSize);
251 YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment);
252 YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment);
253 YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack);
254 YamlIO.mapOptional("hasCalls", MFI.HasCalls);
255 YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize);
256 YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment);
257 YamlIO.mapOptional("hasVAStart", MFI.HasVAStart);
258 YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc);
262 struct MachineFunction {
264 unsigned Alignment = 0;
265 bool ExposesReturnsTwice = false;
266 bool HasInlineAsm = false;
267 // Register information
269 bool TracksRegLiveness = false;
270 bool TracksSubRegLiveness = false;
271 std::vector<VirtualRegisterDefinition> VirtualRegisters;
272 // TODO: Serialize the various register masks.
273 // TODO: Serialize live in registers.
275 MachineFrameInfo FrameInfo;
276 std::vector<FixedMachineStackObject> FixedStackObjects;
277 std::vector<MachineStackObject> StackObjects;
279 std::vector<MachineBasicBlock> BasicBlocks;
282 template <> struct MappingTraits<MachineFunction> {
283 static void mapping(IO &YamlIO, MachineFunction &MF) {
284 YamlIO.mapRequired("name", MF.Name);
285 YamlIO.mapOptional("alignment", MF.Alignment);
286 YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice);
287 YamlIO.mapOptional("hasInlineAsm", MF.HasInlineAsm);
288 YamlIO.mapOptional("isSSA", MF.IsSSA);
289 YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness);
290 YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness);
291 YamlIO.mapOptional("registers", MF.VirtualRegisters);
292 YamlIO.mapOptional("frameInfo", MF.FrameInfo);
293 YamlIO.mapOptional("fixedStack", MF.FixedStackObjects);
294 YamlIO.mapOptional("stack", MF.StackObjects);
295 YamlIO.mapOptional("body", MF.BasicBlocks);
299 } // end namespace yaml
300 } // end namespace llvm