MIRYamlMapping.h revision 286684
1218885Sdim//===- MIRYAMLMapping.h - Describes the mapping between MIR and YAML ------===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// The MIR serialization library is currently a work in progress. It can't 11218885Sdim// serialize machine functions at this time. 12218885Sdim// 13218885Sdim// This file implements the mapping between various MIR data structures and 14218885Sdim// their corresponding YAML representation. 15221345Sdim// 16218885Sdim//===----------------------------------------------------------------------===// 17218885Sdim 18218885Sdim#ifndef LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H 19218885Sdim#define LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H 20218885Sdim 21218885Sdim#include "llvm/ADT/StringRef.h" 22218885Sdim#include "llvm/Support/YAMLTraits.h" 23218885Sdim#include <vector> 24218885Sdim 25218885Sdimnamespace llvm { 26218885Sdimnamespace yaml { 27218885Sdim 28218885Sdim/// A wrapper around std::string which contains a source range that's being 29218885Sdim/// set during parsing. 30218885Sdimstruct StringValue { 31218885Sdim std::string Value; 32218885Sdim SMRange SourceRange; 33218885Sdim 34218885Sdim StringValue() {} 35218885Sdim StringValue(std::string Value) : Value(std::move(Value)) {} 36218885Sdim 37218885Sdim bool operator==(const StringValue &Other) const { 38218885Sdim return Value == Other.Value; 39218885Sdim } 40218885Sdim}; 41218885Sdim 42218885Sdimtemplate <> struct ScalarTraits<StringValue> { 43218885Sdim static void output(const StringValue &S, void *, llvm::raw_ostream &OS) { 44218885Sdim OS << S.Value; 45218885Sdim } 46218885Sdim 47218885Sdim static StringRef input(StringRef Scalar, void *Ctx, StringValue &S) { 48249423Sdim S.Value = Scalar.str(); 49249423Sdim if (const auto *Node = 50249423Sdim reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode()) 51249423Sdim S.SourceRange = Node->getSourceRange(); 52218885Sdim return ""; 53218885Sdim } 54218885Sdim 55218885Sdim static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); } 56218885Sdim}; 57 58struct FlowStringValue : StringValue { 59 FlowStringValue() {} 60 FlowStringValue(std::string Value) : StringValue(Value) {} 61}; 62 63template <> struct ScalarTraits<FlowStringValue> { 64 static void output(const FlowStringValue &S, void *, llvm::raw_ostream &OS) { 65 return ScalarTraits<StringValue>::output(S, nullptr, OS); 66 } 67 68 static StringRef input(StringRef Scalar, void *Ctx, FlowStringValue &S) { 69 return ScalarTraits<StringValue>::input(Scalar, Ctx, S); 70 } 71 72 static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); } 73}; 74 75} // end namespace yaml 76} // end namespace llvm 77 78LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue) 79LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue) 80 81namespace llvm { 82namespace yaml { 83 84struct VirtualRegisterDefinition { 85 unsigned ID; 86 StringValue Class; 87 // TODO: Serialize the virtual register hints. 88}; 89 90template <> struct MappingTraits<VirtualRegisterDefinition> { 91 static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) { 92 YamlIO.mapRequired("id", Reg.ID); 93 YamlIO.mapRequired("class", Reg.Class); 94 } 95 96 static const bool flow = true; 97}; 98 99struct MachineBasicBlock { 100 unsigned ID; 101 StringValue Name; 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; 109}; 110 111template <> 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); 122 } 123}; 124 125/// Serializable representation of stack object from the MachineFrameInfo class. 126/// 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. 130/// 131/// TODO: Determine isPreallocated flag by mapping between objects and local 132/// objects (Serialize local objects). 133struct MachineStackObject { 134 enum ObjectType { DefaultType, SpillSlot, VariableSized }; 135 // TODO: Serialize LLVM alloca reference. 136 unsigned ID; 137 ObjectType Type = DefaultType; 138 int64_t Offset = 0; 139 uint64_t Size = 0; 140 unsigned Alignment = 0; 141}; 142 143template <> 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); 148 } 149}; 150 151template <> struct MappingTraits<MachineStackObject> { 152 static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) { 153 YamlIO.mapRequired("id", Object.ID); 154 YamlIO.mapOptional( 155 "type", Object.Type, 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); 161 } 162 163 static const bool flow = true; 164}; 165 166/// Serializable representation of the fixed stack object from the 167/// MachineFrameInfo class. 168struct FixedMachineStackObject { 169 enum ObjectType { DefaultType, SpillSlot }; 170 unsigned ID; 171 ObjectType Type = DefaultType; 172 int64_t Offset = 0; 173 uint64_t Size = 0; 174 unsigned Alignment = 0; 175 bool IsImmutable = false; 176 bool IsAliased = false; 177}; 178 179template <> 180struct 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); 185 } 186}; 187 188template <> struct MappingTraits<FixedMachineStackObject> { 189 static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) { 190 YamlIO.mapRequired("id", Object.ID); 191 YamlIO.mapOptional( 192 "type", Object.Type, 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); 200 } 201 } 202 203 static const bool flow = true; 204}; 205 206} // end namespace yaml 207} // end namespace llvm 208 209LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition) 210LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock) 211LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject) 212LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject) 213 214namespace llvm { 215namespace yaml { 216 217/// Serializable representation of MachineFrameInfo. 218/// 219/// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and 220/// 'RealignOption' as they are determined by the target and LLVM function 221/// attributes. 222/// It also doesn't serialize attributes like 'NumFixedObject' and 223/// 'HasVarSizedObjects' as they are determined by the frame objects themselves. 224struct 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. 242}; 243 244template <> 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); 259 } 260}; 261 262struct MachineFunction { 263 StringRef Name; 264 unsigned Alignment = 0; 265 bool ExposesReturnsTwice = false; 266 bool HasInlineAsm = false; 267 // Register information 268 bool IsSSA = false; 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. 274 // Frame information 275 MachineFrameInfo FrameInfo; 276 std::vector<FixedMachineStackObject> FixedStackObjects; 277 std::vector<MachineStackObject> StackObjects; 278 279 std::vector<MachineBasicBlock> BasicBlocks; 280}; 281 282template <> 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); 296 } 297}; 298 299} // end namespace yaml 300} // end namespace llvm 301 302#endif 303