Index: llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h +++ llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h @@ -20,6 +20,34 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/YAMLTraits.h" +#include + +namespace llvm { +namespace yaml { + +struct MachineBasicBlock { + std::string Name; + unsigned Alignment = 0; + bool IsLandingPad = false; + bool AddressTaken = false; + // TODO: Serialize the successors and liveins. + // TODO: Serialize machine instructions. +}; + +template <> struct MappingTraits { + static void mapping(IO &YamlIO, MachineBasicBlock &MBB) { + YamlIO.mapOptional("name", MBB.Name, + std::string()); // Don't print out an empty name. + YamlIO.mapOptional("alignment", MBB.Alignment); + YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad); + YamlIO.mapOptional("addressTaken", MBB.AddressTaken); + } +}; + +} // end namespace yaml +} // end namespace llvm + +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock) namespace llvm { namespace yaml { @@ -29,6 +57,8 @@ unsigned Alignment = 0; bool ExposesReturnsTwice = false; bool HasInlineAsm = false; + + std::vector BasicBlocks; }; template <> struct MappingTraits { @@ -37,6 +67,7 @@ YamlIO.mapOptional("alignment", MF.Alignment); YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice); YamlIO.mapOptional("hasInlineAsm", MF.HasInlineAsm); + YamlIO.mapOptional("body", MF.BasicBlocks); } }; Index: llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp +++ llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp @@ -19,10 +19,12 @@ #include "llvm/AsmParser/Parser.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MIRYamlMapping.h" +#include "llvm/IR/BasicBlock.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" +#include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/LineIterator.h" #include "llvm/Support/SMLoc.h" #include "llvm/Support/SourceMgr.h" @@ -74,6 +76,12 @@ /// Return true if error occurred. bool initializeMachineFunction(MachineFunction &MF); + /// Initialize the machine basic block using it's YAML representation. + /// + /// Return true if an error occurred. + bool initializeMachineBasicBlock(MachineBasicBlock &MBB, + const yaml::MachineBasicBlock &YamlMBB); + private: /// Return a MIR diagnostic converted from an LLVM assembly diagnostic. SMDiagnostic diagFromLLVMAssemblyDiag(const SMDiagnostic &Error, @@ -198,6 +206,28 @@ MF.setAlignment(YamlMF.Alignment); MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice); MF.setHasInlineAsm(YamlMF.HasInlineAsm); + const auto &F = *MF.getFunction(); + for (const auto &YamlMBB : YamlMF.BasicBlocks) { + const BasicBlock *BB = nullptr; + if (!YamlMBB.Name.empty()) { + BB = dyn_cast_or_null( + F.getValueSymbolTable().lookup(YamlMBB.Name)); + // TODO: Report an error if a basic block isn't found. + } + auto *MBB = MF.CreateMachineBasicBlock(BB); + MF.insert(MF.end(), MBB); + if (initializeMachineBasicBlock(*MBB, YamlMBB)) + return true; + } + return false; +} + +bool MIRParserImpl::initializeMachineBasicBlock( + MachineBasicBlock &MBB, const yaml::MachineBasicBlock &YamlMBB) { + MBB.setAlignment(YamlMBB.Alignment); + if (YamlMBB.AddressTaken) + MBB.setHasAddressTaken(); + MBB.setIsLandingPad(YamlMBB.IsLandingPad); return false; } Index: llvm/trunk/lib/CodeGen/MIRPrinter.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MIRPrinter.cpp +++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MIRYamlMapping.h" +#include "llvm/IR/BasicBlock.h" #include "llvm/IR/Module.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" @@ -34,6 +35,8 @@ MIRPrinter(raw_ostream &OS) : OS(OS) {} void print(const MachineFunction &MF); + + void convert(yaml::MachineBasicBlock &YamlMBB, const MachineBasicBlock &MBB); }; } // end anonymous namespace @@ -61,10 +64,27 @@ YamlMF.Alignment = MF.getAlignment(); YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice(); YamlMF.HasInlineAsm = MF.hasInlineAsm(); + for (const auto &MBB : MF) { + yaml::MachineBasicBlock YamlMBB; + convert(YamlMBB, MBB); + YamlMF.BasicBlocks.push_back(YamlMBB); + } yaml::Output Out(OS); Out << YamlMF; } +void MIRPrinter::convert(yaml::MachineBasicBlock &YamlMBB, + const MachineBasicBlock &MBB) { + // TODO: Serialize unnamed BB references. + if (const auto *BB = MBB.getBasicBlock()) + YamlMBB.Name = BB->hasName() ? BB->getName() : ""; + else + YamlMBB.Name = ""; + YamlMBB.Alignment = MBB.getAlignment(); + YamlMBB.AddressTaken = MBB.hasAddressTaken(); + YamlMBB.IsLandingPad = MBB.isLandingPad(); +} + void llvm::printMIR(raw_ostream &OS, const Module &M) { yaml::Output Out(OS); Out << const_cast(M); Index: llvm/trunk/test/CodeGen/MIR/basic-blocks.mir =================================================================== --- llvm/trunk/test/CodeGen/MIR/basic-blocks.mir +++ llvm/trunk/test/CodeGen/MIR/basic-blocks.mir @@ -0,0 +1,43 @@ +# RUN: llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s +# This test ensures that the MIR parser parses machine functions correctly. + +--- | + + define i32 @foo() { + entry: + ret i32 0 + } + + define i32 @bar() { + start: + ret i32 0 + } + +... +--- +# CHECK: name: foo +# CHECK: body: +# CHECK-NEXT: - name: entry +# CHECK-NEXT: alignment: 0 +# CHECK-NEXT: isLandingPad: false +# CHECK-NEXT: addressTaken: false +name: foo +body: + - name: entry +... +--- +# CHECK: name: bar +# CHECK: body: +# CHECK-NEXT: - name: start +# CHECK-NEXT: alignment: 4 +# CHECK-NEXT: isLandingPad: false +# CHECK-NEXT: addressTaken: false +# CHECK-NEXT: - alignment: 0 +# CHECK-NEXT: isLandingPad: false +# CHECK-NEXT: addressTaken: true +name: bar +body: + - name: start + alignment: 4 + - addressTaken: true +...