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 /// A wrapper around unsigned which contains a source range that's being set
78 struct UnsignedValue {
82 UnsignedValue() : Value(0) {}
83 UnsignedValue(unsigned Value) : Value(Value) {}
85 bool operator==(const UnsignedValue &Other) const {
86 return Value == Other.Value;
90 template <> struct ScalarTraits<UnsignedValue> {
91 static void output(const UnsignedValue &Value, void *Ctx, raw_ostream &OS) {
92 return ScalarTraits<unsigned>::output(Value.Value, Ctx, OS);
95 static StringRef input(StringRef Scalar, void *Ctx, UnsignedValue &Value) {
96 if (const auto *Node =
97 reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
98 Value.SourceRange = Node->getSourceRange();
99 return ScalarTraits<unsigned>::input(Scalar, Ctx, Value.Value);
102 static bool mustQuote(StringRef Scalar) {
103 return ScalarTraits<unsigned>::mustQuote(Scalar);
107 template <> struct ScalarEnumerationTraits<MachineJumpTableInfo::JTEntryKind> {
108 static void enumeration(yaml::IO &IO,
109 MachineJumpTableInfo::JTEntryKind &EntryKind) {
110 IO.enumCase(EntryKind, "block-address",
111 MachineJumpTableInfo::EK_BlockAddress);
112 IO.enumCase(EntryKind, "gp-rel64-block-address",
113 MachineJumpTableInfo::EK_GPRel64BlockAddress);
114 IO.enumCase(EntryKind, "gp-rel32-block-address",
115 MachineJumpTableInfo::EK_GPRel32BlockAddress);
116 IO.enumCase(EntryKind, "label-difference32",
117 MachineJumpTableInfo::EK_LabelDifference32);
118 IO.enumCase(EntryKind, "inline", MachineJumpTableInfo::EK_Inline);
119 IO.enumCase(EntryKind, "custom32", MachineJumpTableInfo::EK_Custom32);
123 } // end namespace yaml
124 } // end namespace llvm
126 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue)
127 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue)
128 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::UnsignedValue)
133 struct VirtualRegisterDefinition {
136 StringValue PreferredRegister;
137 // TODO: Serialize the target specific register hints.
140 template <> struct MappingTraits<VirtualRegisterDefinition> {
141 static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) {
142 YamlIO.mapRequired("id", Reg.ID);
143 YamlIO.mapRequired("class", Reg.Class);
144 YamlIO.mapOptional("preferred-register", Reg.PreferredRegister,
145 StringValue()); // Don't print out when it's empty.
148 static const bool flow = true;
151 struct MachineFunctionLiveIn {
152 StringValue Register;
153 StringValue VirtualRegister;
156 template <> struct MappingTraits<MachineFunctionLiveIn> {
157 static void mapping(IO &YamlIO, MachineFunctionLiveIn &LiveIn) {
158 YamlIO.mapRequired("reg", LiveIn.Register);
160 "virtual-reg", LiveIn.VirtualRegister,
161 StringValue()); // Don't print the virtual register when it's empty.
164 static const bool flow = true;
167 struct MachineBasicBlock {
171 unsigned Alignment = 0;
172 bool IsLandingPad = false;
173 bool AddressTaken = false;
174 std::vector<FlowStringValue> Successors;
175 std::vector<UnsignedValue> SuccessorWeights;
176 std::vector<FlowStringValue> LiveIns;
177 std::vector<StringValue> Instructions;
180 template <> struct MappingTraits<MachineBasicBlock> {
181 static void mapping(IO &YamlIO, MachineBasicBlock &MBB) {
182 YamlIO.mapRequired("id", MBB.ID);
183 YamlIO.mapOptional("name", MBB.Name,
184 StringValue()); // Don't print out an empty name.
185 YamlIO.mapOptional("ir-block", MBB.IRBlock,
186 StringValue()); // Don't print out an empty BB reference.
187 YamlIO.mapOptional("alignment", MBB.Alignment);
188 YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad);
189 YamlIO.mapOptional("addressTaken", MBB.AddressTaken);
190 YamlIO.mapOptional("successors", MBB.Successors);
191 YamlIO.mapOptional("weights", MBB.SuccessorWeights);
192 YamlIO.mapOptional("liveins", MBB.LiveIns);
193 YamlIO.mapOptional("instructions", MBB.Instructions);
197 /// Serializable representation of stack object from the MachineFrameInfo class.
199 /// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are
200 /// determined by the object's type and frame information flags.
201 /// Dead stack objects aren't serialized.
203 /// TODO: Determine isPreallocated flag by mapping between objects and local
204 /// objects (Serialize local objects).
205 struct MachineStackObject {
206 enum ObjectType { DefaultType, SpillSlot, VariableSized };
209 // TODO: Serialize unnamed LLVM alloca reference.
210 ObjectType Type = DefaultType;
213 unsigned Alignment = 0;
214 StringValue CalleeSavedRegister;
217 template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
218 static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type) {
219 IO.enumCase(Type, "default", MachineStackObject::DefaultType);
220 IO.enumCase(Type, "spill-slot", MachineStackObject::SpillSlot);
221 IO.enumCase(Type, "variable-sized", MachineStackObject::VariableSized);
225 template <> struct MappingTraits<MachineStackObject> {
226 static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) {
227 YamlIO.mapRequired("id", Object.ID);
228 YamlIO.mapOptional("name", Object.Name,
229 StringValue()); // Don't print out an empty name.
232 MachineStackObject::DefaultType); // Don't print the default type.
233 YamlIO.mapOptional("offset", Object.Offset);
234 if (Object.Type != MachineStackObject::VariableSized)
235 YamlIO.mapRequired("size", Object.Size);
236 YamlIO.mapOptional("alignment", Object.Alignment);
237 YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
238 StringValue()); // Don't print it out when it's empty.
241 static const bool flow = true;
244 /// Serializable representation of the fixed stack object from the
245 /// MachineFrameInfo class.
246 struct FixedMachineStackObject {
247 enum ObjectType { DefaultType, SpillSlot };
249 ObjectType Type = DefaultType;
252 unsigned Alignment = 0;
253 bool IsImmutable = false;
254 bool IsAliased = false;
255 StringValue CalleeSavedRegister;
259 struct ScalarEnumerationTraits<FixedMachineStackObject::ObjectType> {
260 static void enumeration(yaml::IO &IO,
261 FixedMachineStackObject::ObjectType &Type) {
262 IO.enumCase(Type, "default", FixedMachineStackObject::DefaultType);
263 IO.enumCase(Type, "spill-slot", FixedMachineStackObject::SpillSlot);
267 template <> struct MappingTraits<FixedMachineStackObject> {
268 static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) {
269 YamlIO.mapRequired("id", Object.ID);
272 FixedMachineStackObject::DefaultType); // Don't print the default type.
273 YamlIO.mapOptional("offset", Object.Offset);
274 YamlIO.mapOptional("size", Object.Size);
275 YamlIO.mapOptional("alignment", Object.Alignment);
276 if (Object.Type != FixedMachineStackObject::SpillSlot) {
277 YamlIO.mapOptional("isImmutable", Object.IsImmutable);
278 YamlIO.mapOptional("isAliased", Object.IsAliased);
280 YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
281 StringValue()); // Don't print it out when it's empty.
284 static const bool flow = true;
287 struct MachineConstantPoolValue {
290 unsigned Alignment = 0;
293 template <> struct MappingTraits<MachineConstantPoolValue> {
294 static void mapping(IO &YamlIO, MachineConstantPoolValue &Constant) {
295 YamlIO.mapRequired("id", Constant.ID);
296 YamlIO.mapOptional("value", Constant.Value);
297 YamlIO.mapOptional("alignment", Constant.Alignment);
301 struct MachineJumpTable {
304 std::vector<FlowStringValue> Blocks;
307 MachineJumpTableInfo::JTEntryKind Kind = MachineJumpTableInfo::EK_Custom32;
308 std::vector<Entry> Entries;
311 template <> struct MappingTraits<MachineJumpTable::Entry> {
312 static void mapping(IO &YamlIO, MachineJumpTable::Entry &Entry) {
313 YamlIO.mapRequired("id", Entry.ID);
314 YamlIO.mapOptional("blocks", Entry.Blocks);
318 } // end namespace yaml
319 } // end namespace llvm
321 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineFunctionLiveIn)
322 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
323 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock)
324 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
325 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject)
326 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineConstantPoolValue)
327 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineJumpTable::Entry)
332 template <> struct MappingTraits<MachineJumpTable> {
333 static void mapping(IO &YamlIO, MachineJumpTable &JT) {
334 YamlIO.mapRequired("kind", JT.Kind);
335 YamlIO.mapOptional("entries", JT.Entries);
339 /// Serializable representation of MachineFrameInfo.
341 /// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and
342 /// 'RealignOption' as they are determined by the target and LLVM function
344 /// It also doesn't serialize attributes like 'NumFixedObject' and
345 /// 'HasVarSizedObjects' as they are determined by the frame objects themselves.
346 struct MachineFrameInfo {
347 bool IsFrameAddressTaken = false;
348 bool IsReturnAddressTaken = false;
349 bool HasStackMap = false;
350 bool HasPatchPoint = false;
351 uint64_t StackSize = 0;
352 int OffsetAdjustment = 0;
353 unsigned MaxAlignment = 0;
354 bool AdjustsStack = false;
355 bool HasCalls = false;
356 // TODO: Serialize StackProtectorIdx and FunctionContextIdx
357 unsigned MaxCallFrameSize = 0;
358 // TODO: Serialize local frame objects.
359 bool HasOpaqueSPAdjustment = false;
360 bool HasVAStart = false;
361 bool HasMustTailInVarArgFunc = false;
362 StringValue SavePoint;
363 StringValue RestorePoint;
366 template <> struct MappingTraits<MachineFrameInfo> {
367 static void mapping(IO &YamlIO, MachineFrameInfo &MFI) {
368 YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken);
369 YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken);
370 YamlIO.mapOptional("hasStackMap", MFI.HasStackMap);
371 YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint);
372 YamlIO.mapOptional("stackSize", MFI.StackSize);
373 YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment);
374 YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment);
375 YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack);
376 YamlIO.mapOptional("hasCalls", MFI.HasCalls);
377 YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize);
378 YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment);
379 YamlIO.mapOptional("hasVAStart", MFI.HasVAStart);
380 YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc);
381 YamlIO.mapOptional("savePoint", MFI.SavePoint,
382 StringValue()); // Don't print it out when it's empty.
383 YamlIO.mapOptional("restorePoint", MFI.RestorePoint,
384 StringValue()); // Don't print it out when it's empty.
388 struct MachineFunction {
390 unsigned Alignment = 0;
391 bool ExposesReturnsTwice = false;
392 bool HasInlineAsm = false;
393 // Register information
395 bool TracksRegLiveness = false;
396 bool TracksSubRegLiveness = false;
397 std::vector<VirtualRegisterDefinition> VirtualRegisters;
398 std::vector<MachineFunctionLiveIn> LiveIns;
399 // TODO: Serialize the various register masks.
401 MachineFrameInfo FrameInfo;
402 std::vector<FixedMachineStackObject> FixedStackObjects;
403 std::vector<MachineStackObject> StackObjects;
404 std::vector<MachineConstantPoolValue> Constants; /// Constant pool.
405 MachineJumpTable JumpTableInfo;
407 std::vector<MachineBasicBlock> BasicBlocks;
410 template <> struct MappingTraits<MachineFunction> {
411 static void mapping(IO &YamlIO, MachineFunction &MF) {
412 YamlIO.mapRequired("name", MF.Name);
413 YamlIO.mapOptional("alignment", MF.Alignment);
414 YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice);
415 YamlIO.mapOptional("hasInlineAsm", MF.HasInlineAsm);
416 YamlIO.mapOptional("isSSA", MF.IsSSA);
417 YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness);
418 YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness);
419 YamlIO.mapOptional("registers", MF.VirtualRegisters);
420 YamlIO.mapOptional("liveins", MF.LiveIns);
421 YamlIO.mapOptional("frameInfo", MF.FrameInfo);
422 YamlIO.mapOptional("fixedStack", MF.FixedStackObjects);
423 YamlIO.mapOptional("stack", MF.StackObjects);
424 YamlIO.mapOptional("constants", MF.Constants);
425 if (!YamlIO.outputting() || !MF.JumpTableInfo.Entries.empty())
426 YamlIO.mapOptional("jumpTable", MF.JumpTableInfo);
427 YamlIO.mapOptional("body", MF.BasicBlocks);
431 } // end namespace yaml
432 } // end namespace llvm