MIRYamlMapping.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. //===- MIRYAMLMapping.h - Describes the mapping between MIR and YAML ------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // The MIR serialization library is currently a work in progress. It can't
  11. // serialize machine functions at this time.
  12. //
  13. // This file implements the mapping between various MIR data structures and
  14. // their corresponding YAML representation.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H
  18. #define LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H
  19. #include "llvm/ADT/StringRef.h"
  20. #include "llvm/Support/YAMLTraits.h"
  21. #include <vector>
  22. namespace llvm {
  23. namespace yaml {
  24. /// A wrapper around std::string which contains a source range that's being
  25. /// set during parsing.
  26. struct StringValue {
  27. std::string Value;
  28. SMRange SourceRange;
  29. StringValue() {}
  30. StringValue(std::string Value) : Value(std::move(Value)) {}
  31. bool operator==(const StringValue &Other) const {
  32. return Value == Other.Value;
  33. }
  34. };
  35. template <> struct ScalarTraits<StringValue> {
  36. static void output(const StringValue &S, void *, llvm::raw_ostream &OS) {
  37. OS << S.Value;
  38. }
  39. static StringRef input(StringRef Scalar, void *Ctx, StringValue &S) {
  40. S.Value = Scalar.str();
  41. if (const auto *Node =
  42. reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode())
  43. S.SourceRange = Node->getSourceRange();
  44. return "";
  45. }
  46. static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
  47. };
  48. struct FlowStringValue : StringValue {
  49. FlowStringValue() {}
  50. FlowStringValue(std::string Value) : StringValue(Value) {}
  51. };
  52. template <> struct ScalarTraits<FlowStringValue> {
  53. static void output(const FlowStringValue &S, void *, llvm::raw_ostream &OS) {
  54. return ScalarTraits<StringValue>::output(S, nullptr, OS);
  55. }
  56. static StringRef input(StringRef Scalar, void *Ctx, FlowStringValue &S) {
  57. return ScalarTraits<StringValue>::input(Scalar, Ctx, S);
  58. }
  59. static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
  60. };
  61. } // end namespace yaml
  62. } // end namespace llvm
  63. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue)
  64. LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue)
  65. namespace llvm {
  66. namespace yaml {
  67. struct VirtualRegisterDefinition {
  68. unsigned ID;
  69. StringValue Class;
  70. // TODO: Serialize the virtual register hints.
  71. };
  72. template <> struct MappingTraits<VirtualRegisterDefinition> {
  73. static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) {
  74. YamlIO.mapRequired("id", Reg.ID);
  75. YamlIO.mapRequired("class", Reg.Class);
  76. }
  77. static const bool flow = true;
  78. };
  79. struct MachineBasicBlock {
  80. unsigned ID;
  81. StringValue Name;
  82. unsigned Alignment = 0;
  83. bool IsLandingPad = false;
  84. bool AddressTaken = false;
  85. // TODO: Serialize the successor weights.
  86. std::vector<FlowStringValue> Successors;
  87. std::vector<FlowStringValue> LiveIns;
  88. std::vector<StringValue> Instructions;
  89. };
  90. template <> struct MappingTraits<MachineBasicBlock> {
  91. static void mapping(IO &YamlIO, MachineBasicBlock &MBB) {
  92. YamlIO.mapRequired("id", MBB.ID);
  93. YamlIO.mapOptional("name", MBB.Name,
  94. StringValue()); // Don't print out an empty name.
  95. YamlIO.mapOptional("alignment", MBB.Alignment);
  96. YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad);
  97. YamlIO.mapOptional("addressTaken", MBB.AddressTaken);
  98. YamlIO.mapOptional("successors", MBB.Successors);
  99. YamlIO.mapOptional("liveins", MBB.LiveIns);
  100. YamlIO.mapOptional("instructions", MBB.Instructions);
  101. }
  102. };
  103. /// Serializable representation of stack object from the MachineFrameInfo class.
  104. ///
  105. /// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are
  106. /// determined by the object's type and frame information flags.
  107. /// Dead stack objects aren't serialized.
  108. ///
  109. /// TODO: Determine isPreallocated flag by mapping between objects and local
  110. /// objects (Serialize local objects).
  111. struct MachineStackObject {
  112. enum ObjectType { DefaultType, SpillSlot, VariableSized };
  113. // TODO: Serialize LLVM alloca reference.
  114. unsigned ID;
  115. ObjectType Type = DefaultType;
  116. int64_t Offset = 0;
  117. uint64_t Size = 0;
  118. unsigned Alignment = 0;
  119. };
  120. template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
  121. static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type) {
  122. IO.enumCase(Type, "default", MachineStackObject::DefaultType);
  123. IO.enumCase(Type, "spill-slot", MachineStackObject::SpillSlot);
  124. IO.enumCase(Type, "variable-sized", MachineStackObject::VariableSized);
  125. }
  126. };
  127. template <> struct MappingTraits<MachineStackObject> {
  128. static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) {
  129. YamlIO.mapRequired("id", Object.ID);
  130. YamlIO.mapOptional(
  131. "type", Object.Type,
  132. MachineStackObject::DefaultType); // Don't print the default type.
  133. YamlIO.mapOptional("offset", Object.Offset);
  134. if (Object.Type != MachineStackObject::VariableSized)
  135. YamlIO.mapRequired("size", Object.Size);
  136. YamlIO.mapOptional("alignment", Object.Alignment);
  137. }
  138. static const bool flow = true;
  139. };
  140. /// Serializable representation of the fixed stack object from the
  141. /// MachineFrameInfo class.
  142. struct FixedMachineStackObject {
  143. enum ObjectType { DefaultType, SpillSlot };
  144. unsigned ID;
  145. ObjectType Type = DefaultType;
  146. int64_t Offset = 0;
  147. uint64_t Size = 0;
  148. unsigned Alignment = 0;
  149. bool IsImmutable = false;
  150. bool IsAliased = false;
  151. };
  152. template <>
  153. struct ScalarEnumerationTraits<FixedMachineStackObject::ObjectType> {
  154. static void enumeration(yaml::IO &IO,
  155. FixedMachineStackObject::ObjectType &Type) {
  156. IO.enumCase(Type, "default", FixedMachineStackObject::DefaultType);
  157. IO.enumCase(Type, "spill-slot", FixedMachineStackObject::SpillSlot);
  158. }
  159. };
  160. template <> struct MappingTraits<FixedMachineStackObject> {
  161. static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) {
  162. YamlIO.mapRequired("id", Object.ID);
  163. YamlIO.mapOptional(
  164. "type", Object.Type,
  165. FixedMachineStackObject::DefaultType); // Don't print the default type.
  166. YamlIO.mapOptional("offset", Object.Offset);
  167. YamlIO.mapOptional("size", Object.Size);
  168. YamlIO.mapOptional("alignment", Object.Alignment);
  169. if (Object.Type != FixedMachineStackObject::SpillSlot) {
  170. YamlIO.mapOptional("isImmutable", Object.IsImmutable);
  171. YamlIO.mapOptional("isAliased", Object.IsAliased);
  172. }
  173. }
  174. static const bool flow = true;
  175. };
  176. } // end namespace yaml
  177. } // end namespace llvm
  178. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
  179. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock)
  180. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
  181. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject)
  182. namespace llvm {
  183. namespace yaml {
  184. /// Serializable representation of MachineFrameInfo.
  185. ///
  186. /// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and
  187. /// 'RealignOption' as they are determined by the target and LLVM function
  188. /// attributes.
  189. /// It also doesn't serialize attributes like 'NumFixedObject' and
  190. /// 'HasVarSizedObjects' as they are determined by the frame objects themselves.
  191. struct MachineFrameInfo {
  192. bool IsFrameAddressTaken = false;
  193. bool IsReturnAddressTaken = false;
  194. bool HasStackMap = false;
  195. bool HasPatchPoint = false;
  196. uint64_t StackSize = 0;
  197. int OffsetAdjustment = 0;
  198. unsigned MaxAlignment = 0;
  199. bool AdjustsStack = false;
  200. bool HasCalls = false;
  201. // TODO: Serialize StackProtectorIdx and FunctionContextIdx
  202. unsigned MaxCallFrameSize = 0;
  203. // TODO: Serialize callee saved info.
  204. // TODO: Serialize local frame objects.
  205. bool HasOpaqueSPAdjustment = false;
  206. bool HasVAStart = false;
  207. bool HasMustTailInVarArgFunc = false;
  208. // TODO: Serialize save and restore MBB references.
  209. };
  210. template <> struct MappingTraits<MachineFrameInfo> {
  211. static void mapping(IO &YamlIO, MachineFrameInfo &MFI) {
  212. YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken);
  213. YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken);
  214. YamlIO.mapOptional("hasStackMap", MFI.HasStackMap);
  215. YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint);
  216. YamlIO.mapOptional("stackSize", MFI.StackSize);
  217. YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment);
  218. YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment);
  219. YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack);
  220. YamlIO.mapOptional("hasCalls", MFI.HasCalls);
  221. YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize);
  222. YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment);
  223. YamlIO.mapOptional("hasVAStart", MFI.HasVAStart);
  224. YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc);
  225. }
  226. };
  227. struct MachineFunction {
  228. StringRef Name;
  229. unsigned Alignment = 0;
  230. bool ExposesReturnsTwice = false;
  231. bool HasInlineAsm = false;
  232. // Register information
  233. bool IsSSA = false;
  234. bool TracksRegLiveness = false;
  235. bool TracksSubRegLiveness = false;
  236. std::vector<VirtualRegisterDefinition> VirtualRegisters;
  237. // TODO: Serialize the various register masks.
  238. // TODO: Serialize live in registers.
  239. // Frame information
  240. MachineFrameInfo FrameInfo;
  241. std::vector<FixedMachineStackObject> FixedStackObjects;
  242. std::vector<MachineStackObject> StackObjects;
  243. std::vector<MachineBasicBlock> BasicBlocks;
  244. };
  245. template <> struct MappingTraits<MachineFunction> {
  246. static void mapping(IO &YamlIO, MachineFunction &MF) {
  247. YamlIO.mapRequired("name", MF.Name);
  248. YamlIO.mapOptional("alignment", MF.Alignment);
  249. YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice);
  250. YamlIO.mapOptional("hasInlineAsm", MF.HasInlineAsm);
  251. YamlIO.mapOptional("isSSA", MF.IsSSA);
  252. YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness);
  253. YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness);
  254. YamlIO.mapOptional("registers", MF.VirtualRegisters);
  255. YamlIO.mapOptional("frameInfo", MF.FrameInfo);
  256. YamlIO.mapOptional("fixedStack", MF.FixedStackObjects);
  257. YamlIO.mapOptional("stack", MF.StackObjects);
  258. YamlIO.mapOptional("body", MF.BasicBlocks);
  259. }
  260. };
  261. } // end namespace yaml
  262. } // end namespace llvm
  263. #endif