MIRYamlMapping.h revision 287506
1206089Sfabient//===- MIRYAMLMapping.h - Describes the mapping between MIR and YAML ------===// 2206089Sfabient// 3206089Sfabient// The LLVM Compiler Infrastructure 4206089Sfabient// 5206089Sfabient// This file is distributed under the University of Illinois Open Source 6206089Sfabient// License. See LICENSE.TXT for details. 7206089Sfabient// 8206089Sfabient//===----------------------------------------------------------------------===// 9206089Sfabient// 10206089Sfabient// The MIR serialization library is currently a work in progress. It can't 11206089Sfabient// serialize machine functions at this time. 12231871Sbrueffer// 13231871Sbrueffer// This file implements the mapping between various MIR data structures and 14231871Sbrueffer// their corresponding YAML representation. 15231871Sbrueffer// 16231871Sbrueffer//===----------------------------------------------------------------------===// 17231871Sbrueffer 18231871Sbrueffer#ifndef LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H 19231871Sbrueffer#define LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H 20231871Sbrueffer 21231871Sbrueffer#include "llvm/ADT/StringRef.h" 22231871Sbrueffer#include "llvm/Support/YAMLTraits.h" 23206089Sfabient#include <vector> 24206089Sfabient 25206089Sfabientnamespace llvm { 26206089Sfabientnamespace yaml { 27206622Suqs 28206089Sfabient/// A wrapper around std::string which contains a source range that's being 29206089Sfabient/// set during parsing. 30206089Sfabientstruct StringValue { 31206089Sfabient std::string Value; 32206089Sfabient SMRange SourceRange; 33206089Sfabient 34206089Sfabient StringValue() {} 35206089Sfabient StringValue(std::string Value) : Value(std::move(Value)) {} 36206089Sfabient 37206089Sfabient bool operator==(const StringValue &Other) const { 38206089Sfabient return Value == Other.Value; 39206089Sfabient } 40206089Sfabient}; 41206089Sfabient 42206089Sfabienttemplate <> struct ScalarTraits<StringValue> { 43206089Sfabient static void output(const StringValue &S, void *, llvm::raw_ostream &OS) { 44206089Sfabient OS << S.Value; 45206089Sfabient } 46206089Sfabient 47206089Sfabient static StringRef input(StringRef Scalar, void *Ctx, StringValue &S) { 48206089Sfabient S.Value = Scalar.str(); 49206089Sfabient if (const auto *Node = 50206089Sfabient reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode()) 51206089Sfabient S.SourceRange = Node->getSourceRange(); 52206089Sfabient return ""; 53206089Sfabient } 54206089Sfabient 55206089Sfabient static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); } 56206089Sfabient}; 57206089Sfabient 58206089Sfabientstruct FlowStringValue : StringValue { 59206089Sfabient FlowStringValue() {} 60206089Sfabient FlowStringValue(std::string Value) : StringValue(Value) {} 61206089Sfabient}; 62206089Sfabient 63206089Sfabienttemplate <> struct ScalarTraits<FlowStringValue> { 64206089Sfabient static void output(const FlowStringValue &S, void *, llvm::raw_ostream &OS) { 65206089Sfabient return ScalarTraits<StringValue>::output(S, nullptr, OS); 66206089Sfabient } 67206089Sfabient 68206089Sfabient static StringRef input(StringRef Scalar, void *Ctx, FlowStringValue &S) { 69206089Sfabient return ScalarTraits<StringValue>::input(Scalar, Ctx, S); 70206089Sfabient } 71206089Sfabient 72206089Sfabient static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); } 73206089Sfabient}; 74206089Sfabient 75206089Sfabient} // end namespace yaml 76206089Sfabient} // end namespace llvm 77206089Sfabient 78206089SfabientLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue) 79206089SfabientLLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue) 80206089Sfabient 81206089Sfabientnamespace llvm { 82206089Sfabientnamespace yaml { 83206089Sfabient 84206089Sfabientstruct VirtualRegisterDefinition { 85206089Sfabient unsigned ID; 86206089Sfabient StringValue Class; 87206089Sfabient // TODO: Serialize the virtual register hints. 88206089Sfabient}; 89206089Sfabient 90206089Sfabienttemplate <> struct MappingTraits<VirtualRegisterDefinition> { 91206089Sfabient static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) { 92206089Sfabient YamlIO.mapRequired("id", Reg.ID); 93206089Sfabient YamlIO.mapRequired("class", Reg.Class); 94206089Sfabient } 95206089Sfabient 96206089Sfabient static const bool flow = true; 97206089Sfabient}; 98206089Sfabient 99206089Sfabientstruct MachineBasicBlock { 100206089Sfabient unsigned ID; 101206089Sfabient StringValue Name; 102206089Sfabient unsigned Alignment = 0; 103206089Sfabient bool IsLandingPad = false; 104206089Sfabient bool AddressTaken = false; 105206089Sfabient // TODO: Serialize the successor weights. 106206089Sfabient std::vector<FlowStringValue> Successors; 107206089Sfabient std::vector<FlowStringValue> LiveIns; 108206089Sfabient std::vector<StringValue> Instructions; 109206089Sfabient}; 110206089Sfabient 111206089Sfabienttemplate <> struct MappingTraits<MachineBasicBlock> { 112206089Sfabient static void mapping(IO &YamlIO, MachineBasicBlock &MBB) { 113206089Sfabient YamlIO.mapRequired("id", MBB.ID); 114206089Sfabient YamlIO.mapOptional("name", MBB.Name, 115206089Sfabient StringValue()); // Don't print out an empty name. 116206089Sfabient YamlIO.mapOptional("alignment", MBB.Alignment); 117206089Sfabient YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad); 118206089Sfabient YamlIO.mapOptional("addressTaken", MBB.AddressTaken); 119206089Sfabient YamlIO.mapOptional("successors", MBB.Successors); 120206089Sfabient YamlIO.mapOptional("liveins", MBB.LiveIns); 121206089Sfabient YamlIO.mapOptional("instructions", MBB.Instructions); 122206089Sfabient } 123206089Sfabient}; 124206089Sfabient 125206089Sfabient/// Serializable representation of stack object from the MachineFrameInfo class. 126206089Sfabient/// 127206089Sfabient/// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are 128206089Sfabient/// determined by the object's type and frame information flags. 129206089Sfabient/// Dead stack objects aren't serialized. 130206089Sfabient/// 131206089Sfabient/// TODO: Determine isPreallocated flag by mapping between objects and local 132206089Sfabient/// objects (Serialize local objects). 133206089Sfabientstruct MachineStackObject { 134206089Sfabient enum ObjectType { DefaultType, SpillSlot, VariableSized }; 135206089Sfabient // TODO: Serialize LLVM alloca reference. 136206089Sfabient unsigned ID; 137206089Sfabient ObjectType Type = DefaultType; 138206089Sfabient int64_t Offset = 0; 139206089Sfabient uint64_t Size = 0; 140206089Sfabient unsigned Alignment = 0; 141206089Sfabient}; 142206089Sfabient 143206089Sfabienttemplate <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> { 144206089Sfabient static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type) { 145206089Sfabient IO.enumCase(Type, "default", MachineStackObject::DefaultType); 146206089Sfabient IO.enumCase(Type, "spill-slot", MachineStackObject::SpillSlot); 147206089Sfabient IO.enumCase(Type, "variable-sized", MachineStackObject::VariableSized); 148206089Sfabient } 149206089Sfabient}; 150206089Sfabient 151206089Sfabienttemplate <> struct MappingTraits<MachineStackObject> { 152206089Sfabient static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) { 153206089Sfabient YamlIO.mapRequired("id", Object.ID); 154208914Suqs YamlIO.mapOptional( 155206089Sfabient "type", Object.Type, 156206089Sfabient MachineStackObject::DefaultType); // Don't print the default type. 157206089Sfabient YamlIO.mapOptional("offset", Object.Offset); 158206089Sfabient if (Object.Type != MachineStackObject::VariableSized) 159206089Sfabient YamlIO.mapRequired("size", Object.Size); 160206089Sfabient YamlIO.mapOptional("alignment", Object.Alignment); 161208914Suqs } 162206089Sfabient 163206089Sfabient static const bool flow = true; 164206089Sfabient}; 165206089Sfabient 166206089Sfabient/// Serializable representation of the fixed stack object from the 167206089Sfabient/// MachineFrameInfo class. 168206089Sfabientstruct FixedMachineStackObject { 169206089Sfabient enum ObjectType { DefaultType, SpillSlot }; 170206089Sfabient unsigned ID; 171206089Sfabient ObjectType Type = DefaultType; 172206089Sfabient int64_t Offset = 0; 173206089Sfabient uint64_t Size = 0; 174206089Sfabient unsigned Alignment = 0; 175206089Sfabient bool IsImmutable = false; 176206089Sfabient bool IsAliased = false; 177206089Sfabient}; 178206089Sfabient 179206089Sfabienttemplate <> 180206089Sfabientstruct ScalarEnumerationTraits<FixedMachineStackObject::ObjectType> { 181206089Sfabient static void enumeration(yaml::IO &IO, 182206089Sfabient FixedMachineStackObject::ObjectType &Type) { 183206089Sfabient IO.enumCase(Type, "default", FixedMachineStackObject::DefaultType); 184206089Sfabient IO.enumCase(Type, "spill-slot", FixedMachineStackObject::SpillSlot); 185206089Sfabient } 186206089Sfabient}; 187206089Sfabient 188206089Sfabienttemplate <> struct MappingTraits<FixedMachineStackObject> { 189206089Sfabient static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) { 190206089Sfabient YamlIO.mapRequired("id", Object.ID); 191206089Sfabient YamlIO.mapOptional( 192206089Sfabient "type", Object.Type, 193206089Sfabient FixedMachineStackObject::DefaultType); // Don't print the default type. 194206089Sfabient YamlIO.mapOptional("offset", Object.Offset); 195206089Sfabient YamlIO.mapOptional("size", Object.Size); 196206089Sfabient YamlIO.mapOptional("alignment", Object.Alignment); 197206089Sfabient if (Object.Type != FixedMachineStackObject::SpillSlot) { 198206089Sfabient YamlIO.mapOptional("isImmutable", Object.IsImmutable); 199206089Sfabient YamlIO.mapOptional("isAliased", Object.IsAliased); 200206089Sfabient } 201206089Sfabient } 202206089Sfabient 203206089Sfabient static const bool flow = true; 204206089Sfabient}; 205206089Sfabient 206206089Sfabient} // end namespace yaml 207206089Sfabient} // end namespace llvm 208206089Sfabient 209206089SfabientLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition) 210206089SfabientLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock) 211206089SfabientLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject) 212206089SfabientLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject) 213206089Sfabient 214206089Sfabientnamespace llvm { 215206089Sfabientnamespace yaml { 216206089Sfabient 217206089Sfabient/// Serializable representation of MachineFrameInfo. 218206089Sfabient/// 219206089Sfabient/// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and 220206089Sfabient/// 'RealignOption' as they are determined by the target and LLVM function 221206089Sfabient/// attributes. 222206089Sfabient/// It also doesn't serialize attributes like 'NumFixedObject' and 223206089Sfabient/// 'HasVarSizedObjects' as they are determined by the frame objects themselves. 224206089Sfabientstruct MachineFrameInfo { 225206089Sfabient bool IsFrameAddressTaken = false; 226206089Sfabient bool IsReturnAddressTaken = false; 227206089Sfabient bool HasStackMap = false; 228206089Sfabient bool HasPatchPoint = false; 229206089Sfabient uint64_t StackSize = 0; 230206089Sfabient int OffsetAdjustment = 0; 231206089Sfabient unsigned MaxAlignment = 0; 232206089Sfabient bool AdjustsStack = false; 233206089Sfabient bool HasCalls = false; 234206089Sfabient // TODO: Serialize StackProtectorIdx and FunctionContextIdx 235206089Sfabient unsigned MaxCallFrameSize = 0; 236206089Sfabient // TODO: Serialize callee saved info. 237206089Sfabient // TODO: Serialize local frame objects. 238206089Sfabient bool HasOpaqueSPAdjustment = false; 239206089Sfabient bool HasVAStart = false; 240206089Sfabient bool HasMustTailInVarArgFunc = false; 241206089Sfabient // TODO: Serialize save and restore MBB references. 242206089Sfabient}; 243206089Sfabient 244206089Sfabienttemplate <> struct MappingTraits<MachineFrameInfo> { 245206089Sfabient static void mapping(IO &YamlIO, MachineFrameInfo &MFI) { 246206089Sfabient YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken); 247206089Sfabient YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken); 248206089Sfabient YamlIO.mapOptional("hasStackMap", MFI.HasStackMap); 249206089Sfabient YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint); 250206089Sfabient YamlIO.mapOptional("stackSize", MFI.StackSize); 251206089Sfabient YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment); 252206089Sfabient YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment); 253206089Sfabient YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack); 254206089Sfabient YamlIO.mapOptional("hasCalls", MFI.HasCalls); 255206089Sfabient YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize); 256206089Sfabient YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment); 257206089Sfabient YamlIO.mapOptional("hasVAStart", MFI.HasVAStart); 258206089Sfabient YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc); 259206089Sfabient } 260206089Sfabient}; 261206089Sfabient 262206089Sfabientstruct MachineFunction { 263206089Sfabient StringRef Name; 264206089Sfabient unsigned Alignment = 0; 265206089Sfabient bool ExposesReturnsTwice = false; 266206089Sfabient bool HasInlineAsm = false; 267206089Sfabient // Register information 268206089Sfabient bool IsSSA = false; 269206089Sfabient bool TracksRegLiveness = false; 270206089Sfabient bool TracksSubRegLiveness = false; 271206089Sfabient std::vector<VirtualRegisterDefinition> VirtualRegisters; 272206089Sfabient // TODO: Serialize the various register masks. 273206089Sfabient // TODO: Serialize live in registers. 274206089Sfabient // Frame information 275206089Sfabient MachineFrameInfo FrameInfo; 276206089Sfabient std::vector<FixedMachineStackObject> FixedStackObjects; 277206089Sfabient std::vector<MachineStackObject> StackObjects; 278206089Sfabient 279206089Sfabient std::vector<MachineBasicBlock> BasicBlocks; 280206089Sfabient}; 281206089Sfabient 282206089Sfabienttemplate <> struct MappingTraits<MachineFunction> { 283206089Sfabient static void mapping(IO &YamlIO, MachineFunction &MF) { 284206089Sfabient YamlIO.mapRequired("name", MF.Name); 285206089Sfabient YamlIO.mapOptional("alignment", MF.Alignment); 286206089Sfabient YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice); 287206089Sfabient YamlIO.mapOptional("hasInlineAsm", MF.HasInlineAsm); 288206089Sfabient YamlIO.mapOptional("isSSA", MF.IsSSA); 289206089Sfabient YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness); 290206089Sfabient YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness); 291206089Sfabient YamlIO.mapOptional("registers", MF.VirtualRegisters); 292206089Sfabient YamlIO.mapOptional("frameInfo", MF.FrameInfo); 293206089Sfabient YamlIO.mapOptional("fixedStack", MF.FixedStackObjects); 294206089Sfabient YamlIO.mapOptional("stack", MF.StackObjects); 295206089Sfabient YamlIO.mapOptional("body", MF.BasicBlocks); 296206089Sfabient } 297206089Sfabient}; 298206089Sfabient 299206089Sfabient} // end namespace yaml 300206089Sfabient} // end namespace llvm 301206089Sfabient 302206089Sfabient#endif 303206089Sfabient