MIR Serialization: Serialize the list of machine basic blocks with simple attributes.

This commit implements the initial serialization of machine basic blocks in a
machine function. Only the simple, scalar MBB attributes are serialized. The 
reference to LLVM IR's basic block is preserved when that basic block has a name.

Reviewers: Duncan P. N. Exon Smith

Differential Revision: http://reviews.llvm.org/D10465


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240145 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Alex Lorenz 2015-06-19 17:43:07 +00:00
parent ad85d7a042
commit 260366437c
4 changed files with 124 additions and 0 deletions

View File

@ -20,6 +20,34 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/YAMLTraits.h"
#include <vector>
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<MachineBasicBlock> {
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 @@ struct MachineFunction {
unsigned Alignment = 0;
bool ExposesReturnsTwice = false;
bool HasInlineAsm = false;
std::vector<MachineBasicBlock> BasicBlocks;
};
template <> struct MappingTraits<MachineFunction> {
@ -37,6 +67,7 @@ template <> struct MappingTraits<MachineFunction> {
YamlIO.mapOptional("alignment", MF.Alignment);
YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice);
YamlIO.mapOptional("hasInlineAsm", MF.HasInlineAsm);
YamlIO.mapOptional("body", MF.BasicBlocks);
}
};

View File

@ -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 @@ public:
/// 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 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
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<BasicBlock>(
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;
}

View File

@ -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 @@ public:
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 @@ void MIRPrinter::print(const MachineFunction &MF) {
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() : "<unnamed bb>";
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<Module &>(M);

View File

@ -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
...