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 // This file implements the mapping between various MIR data structures and
11 // their corresponding YAML representation.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H
16 #define LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/CodeGen/MachineJumpTableInfo.h"
20 #include "llvm/Support/YAMLTraits.h"
26 /// A wrapper around std::string which contains a source range that's being
27 /// set during parsing.
33 StringValue(std::string Value) : Value(std::move(Value)) {}
35 bool operator==(const StringValue &Other) const {
36 return Value == Other.Value;
40 template <> struct ScalarTraits<StringValue> {
41 static void output(const StringValue &S, void *, llvm::raw_ostream &OS) {
45 static StringRef input(StringRef Scalar, void *Ctx, StringValue &S) {
46 S.Value = Scalar.str();
47 if (const auto *Node =
48 reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
49 S.SourceRange = Node->getSourceRange();
53 static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
56 struct FlowStringValue : StringValue {
58 FlowStringValue(std::string Value) : StringValue(Value) {}
61 template <> struct ScalarTraits<FlowStringValue> {
62 static void output(const FlowStringValue &S, void *, llvm::raw_ostream &OS) {
63 return ScalarTraits<StringValue>::output(S, nullptr, OS);
66 static StringRef input(StringRef Scalar, void *Ctx, FlowStringValue &S) {
67 return ScalarTraits<StringValue>::input(Scalar, Ctx, S);
70 static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
73 struct BlockStringValue {
77 template <> struct BlockScalarTraits<BlockStringValue> {
78 static void output(const BlockStringValue &S, void *Ctx, raw_ostream &OS) {
79 return ScalarTraits<StringValue>::output(S.Value, Ctx, OS);
82 static StringRef input(StringRef Scalar, void *Ctx, BlockStringValue &S) {
83 return ScalarTraits<StringValue>::input(Scalar, Ctx, S.Value);
87 /// A wrapper around unsigned which contains a source range that's being set
89 struct UnsignedValue {
93 UnsignedValue() : Value(0) {}
94 UnsignedValue(unsigned Value) : Value(Value) {}
96 bool operator==(const UnsignedValue &Other) const {
97 return Value == Other.Value;
101 template <> struct ScalarTraits<UnsignedValue> {
102 static void output(const UnsignedValue &Value, void *Ctx, raw_ostream &OS) {
103 return ScalarTraits<unsigned>::output(Value.Value, Ctx, OS);
106 static StringRef input(StringRef Scalar, void *Ctx, UnsignedValue &Value) {
107 if (const auto *Node =
108 reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
109 Value.SourceRange = Node->getSourceRange();
110 return ScalarTraits<unsigned>::input(Scalar, Ctx, Value.Value);
113 static bool mustQuote(StringRef Scalar) {
114 return ScalarTraits<unsigned>::mustQuote(Scalar);
118 template <> struct ScalarEnumerationTraits<MachineJumpTableInfo::JTEntryKind> {
119 static void enumeration(yaml::IO &IO,
120 MachineJumpTableInfo::JTEntryKind &EntryKind) {
121 IO.enumCase(EntryKind, "block-address",
122 MachineJumpTableInfo::EK_BlockAddress);
123 IO.enumCase(EntryKind, "gp-rel64-block-address",
124 MachineJumpTableInfo::EK_GPRel64BlockAddress);
125 IO.enumCase(EntryKind, "gp-rel32-block-address",
126 MachineJumpTableInfo::EK_GPRel32BlockAddress);
127 IO.enumCase(EntryKind, "label-difference32",
128 MachineJumpTableInfo::EK_LabelDifference32);
129 IO.enumCase(EntryKind, "inline", MachineJumpTableInfo::EK_Inline);
130 IO.enumCase(EntryKind, "custom32", MachineJumpTableInfo::EK_Custom32);
134 } // end namespace yaml
135 } // end namespace llvm
137 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue)
138 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue)
139 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::UnsignedValue)
144 struct VirtualRegisterDefinition {
147 StringValue PreferredRegister;
148 // TODO: Serialize the target specific register hints.
151 template <> struct MappingTraits<VirtualRegisterDefinition> {
152 static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) {
153 YamlIO.mapRequired("id", Reg.ID);
154 YamlIO.mapRequired("class", Reg.Class);
155 YamlIO.mapOptional("preferred-register", Reg.PreferredRegister,
156 StringValue()); // Don't print out when it's empty.
159 static const bool flow = true;
162 struct MachineFunctionLiveIn {
163 StringValue Register;
164 StringValue VirtualRegister;
167 template <> struct MappingTraits<MachineFunctionLiveIn> {
168 static void mapping(IO &YamlIO, MachineFunctionLiveIn &LiveIn) {
169 YamlIO.mapRequired("reg", LiveIn.Register);
171 "virtual-reg", LiveIn.VirtualRegister,
172 StringValue()); // Don't print the virtual register when it's empty.
175 static const bool flow = true;
178 /// Serializable representation of stack object from the MachineFrameInfo class.
180 /// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are
181 /// determined by the object's type and frame information flags.
182 /// Dead stack objects aren't serialized.
184 /// The 'isPreallocated' flag is determined by the local offset.
185 struct MachineStackObject {
186 enum ObjectType { DefaultType, SpillSlot, VariableSized };
189 // TODO: Serialize unnamed LLVM alloca reference.
190 ObjectType Type = DefaultType;
193 unsigned Alignment = 0;
194 StringValue CalleeSavedRegister;
195 Optional<int64_t> LocalOffset;
196 StringValue DebugVar;
197 StringValue DebugExpr;
198 StringValue DebugLoc;
201 template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
202 static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type) {
203 IO.enumCase(Type, "default", MachineStackObject::DefaultType);
204 IO.enumCase(Type, "spill-slot", MachineStackObject::SpillSlot);
205 IO.enumCase(Type, "variable-sized", MachineStackObject::VariableSized);
209 template <> struct MappingTraits<MachineStackObject> {
210 static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) {
211 YamlIO.mapRequired("id", Object.ID);
212 YamlIO.mapOptional("name", Object.Name,
213 StringValue()); // Don't print out an empty name.
216 MachineStackObject::DefaultType); // Don't print the default type.
217 YamlIO.mapOptional("offset", Object.Offset);
218 if (Object.Type != MachineStackObject::VariableSized)
219 YamlIO.mapRequired("size", Object.Size);
220 YamlIO.mapOptional("alignment", Object.Alignment);
221 YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
222 StringValue()); // Don't print it out when it's empty.
223 YamlIO.mapOptional("local-offset", Object.LocalOffset);
224 YamlIO.mapOptional("di-variable", Object.DebugVar,
225 StringValue()); // Don't print it out when it's empty.
226 YamlIO.mapOptional("di-expression", Object.DebugExpr,
227 StringValue()); // Don't print it out when it's empty.
228 YamlIO.mapOptional("di-location", Object.DebugLoc,
229 StringValue()); // Don't print it out when it's empty.
232 static const bool flow = true;
235 /// Serializable representation of the fixed stack object from the
236 /// MachineFrameInfo class.
237 struct FixedMachineStackObject {
238 enum ObjectType { DefaultType, SpillSlot };
240 ObjectType Type = DefaultType;
243 unsigned Alignment = 0;
244 bool IsImmutable = false;
245 bool IsAliased = false;
246 StringValue CalleeSavedRegister;
250 struct ScalarEnumerationTraits<FixedMachineStackObject::ObjectType> {
251 static void enumeration(yaml::IO &IO,
252 FixedMachineStackObject::ObjectType &Type) {
253 IO.enumCase(Type, "default", FixedMachineStackObject::DefaultType);
254 IO.enumCase(Type, "spill-slot", FixedMachineStackObject::SpillSlot);
258 template <> struct MappingTraits<FixedMachineStackObject> {
259 static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) {
260 YamlIO.mapRequired("id", Object.ID);
263 FixedMachineStackObject::DefaultType); // Don't print the default type.
264 YamlIO.mapOptional("offset", Object.Offset);
265 YamlIO.mapOptional("size", Object.Size);
266 YamlIO.mapOptional("alignment", Object.Alignment);
267 if (Object.Type != FixedMachineStackObject::SpillSlot) {
268 YamlIO.mapOptional("isImmutable", Object.IsImmutable);
269 YamlIO.mapOptional("isAliased", Object.IsAliased);
271 YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
272 StringValue()); // Don't print it out when it's empty.
275 static const bool flow = true;
278 struct MachineConstantPoolValue {
281 unsigned Alignment = 0;
284 template <> struct MappingTraits<MachineConstantPoolValue> {
285 static void mapping(IO &YamlIO, MachineConstantPoolValue &Constant) {
286 YamlIO.mapRequired("id", Constant.ID);
287 YamlIO.mapOptional("value", Constant.Value);
288 YamlIO.mapOptional("alignment", Constant.Alignment);
292 struct MachineJumpTable {
295 std::vector<FlowStringValue> Blocks;
298 MachineJumpTableInfo::JTEntryKind Kind = MachineJumpTableInfo::EK_Custom32;
299 std::vector<Entry> Entries;
302 template <> struct MappingTraits<MachineJumpTable::Entry> {
303 static void mapping(IO &YamlIO, MachineJumpTable::Entry &Entry) {
304 YamlIO.mapRequired("id", Entry.ID);
305 YamlIO.mapOptional("blocks", Entry.Blocks);
309 } // end namespace yaml
310 } // end namespace llvm
312 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineFunctionLiveIn)
313 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
314 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
315 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject)
316 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineConstantPoolValue)
317 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineJumpTable::Entry)
322 template <> struct MappingTraits<MachineJumpTable> {
323 static void mapping(IO &YamlIO, MachineJumpTable &JT) {
324 YamlIO.mapRequired("kind", JT.Kind);
325 YamlIO.mapOptional("entries", JT.Entries);
329 /// Serializable representation of MachineFrameInfo.
331 /// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and
332 /// 'RealignOption' as they are determined by the target and LLVM function
334 /// It also doesn't serialize attributes like 'NumFixedObject' and
335 /// 'HasVarSizedObjects' as they are determined by the frame objects themselves.
336 struct MachineFrameInfo {
337 bool IsFrameAddressTaken = false;
338 bool IsReturnAddressTaken = false;
339 bool HasStackMap = false;
340 bool HasPatchPoint = false;
341 uint64_t StackSize = 0;
342 int OffsetAdjustment = 0;
343 unsigned MaxAlignment = 0;
344 bool AdjustsStack = false;
345 bool HasCalls = false;
346 StringValue StackProtector;
347 // TODO: Serialize FunctionContextIdx
348 unsigned MaxCallFrameSize = 0;
349 bool HasOpaqueSPAdjustment = false;
350 bool HasVAStart = false;
351 bool HasMustTailInVarArgFunc = false;
352 StringValue SavePoint;
353 StringValue RestorePoint;
356 template <> struct MappingTraits<MachineFrameInfo> {
357 static void mapping(IO &YamlIO, MachineFrameInfo &MFI) {
358 YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken);
359 YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken);
360 YamlIO.mapOptional("hasStackMap", MFI.HasStackMap);
361 YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint);
362 YamlIO.mapOptional("stackSize", MFI.StackSize);
363 YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment);
364 YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment);
365 YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack);
366 YamlIO.mapOptional("hasCalls", MFI.HasCalls);
367 YamlIO.mapOptional("stackProtector", MFI.StackProtector,
368 StringValue()); // Don't print it out when it's empty.
369 YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize);
370 YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment);
371 YamlIO.mapOptional("hasVAStart", MFI.HasVAStart);
372 YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc);
373 YamlIO.mapOptional("savePoint", MFI.SavePoint,
374 StringValue()); // Don't print it out when it's empty.
375 YamlIO.mapOptional("restorePoint", MFI.RestorePoint,
376 StringValue()); // Don't print it out when it's empty.
380 struct MachineFunction {
382 unsigned Alignment = 0;
383 bool ExposesReturnsTwice = false;
384 // GISel MachineFunctionProperties.
385 bool Legalized = false;
386 bool RegBankSelected = false;
387 bool Selected = false;
388 // Register information
389 bool TracksRegLiveness = false;
390 std::vector<VirtualRegisterDefinition> VirtualRegisters;
391 std::vector<MachineFunctionLiveIn> LiveIns;
392 Optional<std::vector<FlowStringValue>> CalleeSavedRegisters;
393 // TODO: Serialize the various register masks.
395 MachineFrameInfo FrameInfo;
396 std::vector<FixedMachineStackObject> FixedStackObjects;
397 std::vector<MachineStackObject> StackObjects;
398 std::vector<MachineConstantPoolValue> Constants; /// Constant pool.
399 MachineJumpTable JumpTableInfo;
400 BlockStringValue Body;
403 template <> struct MappingTraits<MachineFunction> {
404 static void mapping(IO &YamlIO, MachineFunction &MF) {
405 YamlIO.mapRequired("name", MF.Name);
406 YamlIO.mapOptional("alignment", MF.Alignment);
407 YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice);
408 YamlIO.mapOptional("legalized", MF.Legalized);
409 YamlIO.mapOptional("regBankSelected", MF.RegBankSelected);
410 YamlIO.mapOptional("selected", MF.Selected);
411 YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness);
412 YamlIO.mapOptional("registers", MF.VirtualRegisters);
413 YamlIO.mapOptional("liveins", MF.LiveIns);
414 YamlIO.mapOptional("calleeSavedRegisters", MF.CalleeSavedRegisters);
415 YamlIO.mapOptional("frameInfo", MF.FrameInfo);
416 YamlIO.mapOptional("fixedStack", MF.FixedStackObjects);
417 YamlIO.mapOptional("stack", MF.StackObjects);
418 YamlIO.mapOptional("constants", MF.Constants);
419 if (!YamlIO.outputting() || !MF.JumpTableInfo.Entries.empty())
420 YamlIO.mapOptional("jumpTable", MF.JumpTableInfo);
421 YamlIO.mapOptional("body", MF.Body);
425 } // end namespace yaml
426 } // end namespace llvm