summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/CodeGen/MIRYamlMapping.h22
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.cpp33
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.h5
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIRParser.cpp11
-rw-r--r--llvm/lib/CodeGen/MIRPrinter.cpp6
-rw-r--r--llvm/test/CodeGen/MIR/expected-eof-after-successor-mbb.mir29
-rw-r--r--llvm/test/CodeGen/MIR/expected-mbb-reference-for-successor-mbb.mir29
-rw-r--r--llvm/test/CodeGen/MIR/successor-basic-blocks.mir58
8 files changed, 189 insertions, 4 deletions
diff --git a/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
index bb8df6307d5..a6ffeb38297 100644
--- a/llvm/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
@@ -55,10 +55,28 @@ template <> struct ScalarTraits<StringValue> {
static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
};
+struct FlowStringValue : StringValue {
+ FlowStringValue() {}
+ FlowStringValue(std::string Value) : StringValue(Value) {}
+};
+
+template <> struct ScalarTraits<FlowStringValue> {
+ static void output(const FlowStringValue &S, void *, llvm::raw_ostream &OS) {
+ return ScalarTraits<StringValue>::output(S, nullptr, OS);
+ }
+
+ static StringRef input(StringRef Scalar, void *Ctx, FlowStringValue &S) {
+ return ScalarTraits<StringValue>::input(Scalar, Ctx, S);
+ }
+
+ static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
+};
+
} // end namespace yaml
} // end namespace llvm
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue)
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue)
namespace llvm {
namespace yaml {
@@ -69,7 +87,8 @@ struct MachineBasicBlock {
unsigned Alignment = 0;
bool IsLandingPad = false;
bool AddressTaken = false;
- // TODO: Serialize the successors and liveins.
+ // TODO: Serialize the successor weights and liveins.
+ std::vector<FlowStringValue> Successors;
std::vector<StringValue> Instructions;
};
@@ -82,6 +101,7 @@ template <> struct MappingTraits<MachineBasicBlock> {
YamlIO.mapOptional("alignment", MBB.Alignment);
YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad);
YamlIO.mapOptional("addressTaken", MBB.AddressTaken);
+ YamlIO.mapOptional("successors", MBB.Successors);
YamlIO.mapOptional("instructions", MBB.Instructions);
}
};
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 43aedffa808..b618e53b8e4 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -64,10 +64,12 @@ public:
bool error(StringRef::iterator Loc, const Twine &Msg);
bool parse(MachineInstr *&MI);
+ bool parseMBB(MachineBasicBlock *&MBB);
bool parseRegister(unsigned &Reg);
bool parseRegisterOperand(MachineOperand &Dest, bool IsDef = false);
bool parseImmediateOperand(MachineOperand &Dest);
+ bool parseMBBReference(MachineBasicBlock *&MBB);
bool parseMBBOperand(MachineOperand &Dest);
bool parseGlobalAddressOperand(MachineOperand &Dest);
bool parseMachineOperand(MachineOperand &Dest);
@@ -186,6 +188,19 @@ bool MIParser::parse(MachineInstr *&MI) {
return false;
}
+bool MIParser::parseMBB(MachineBasicBlock *&MBB) {
+ lex();
+ if (Token.isNot(MIToken::MachineBasicBlock))
+ return error("expected a machine basic block reference");
+ if (parseMBBReference(MBB))
+ return true;
+ lex();
+ if (Token.isNot(MIToken::Eof))
+ return error(
+ "expected end of string after the machine basic block reference");
+ return false;
+}
+
bool MIParser::parseInstruction(unsigned &OpCode) {
if (Token.isNot(MIToken::Identifier))
return error("expected a machine instruction");
@@ -246,7 +261,7 @@ bool MIParser::getUnsigned(unsigned &Result) {
return false;
}
-bool MIParser::parseMBBOperand(MachineOperand &Dest) {
+bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) {
assert(Token.is(MIToken::MachineBasicBlock));
unsigned Number;
if (getUnsigned(Number))
@@ -255,10 +270,17 @@ bool MIParser::parseMBBOperand(MachineOperand &Dest) {
if (MBBInfo == MBBSlots.end())
return error(Twine("use of undefined machine basic block #") +
Twine(Number));
- MachineBasicBlock *MBB = MBBInfo->second;
+ MBB = MBBInfo->second;
if (!Token.stringValue().empty() && Token.stringValue() != MBB->getName())
return error(Twine("the name of machine basic block #") + Twine(Number) +
" isn't '" + Token.stringValue() + "'");
+ return false;
+}
+
+bool MIParser::parseMBBOperand(MachineOperand &Dest) {
+ MachineBasicBlock *MBB;
+ if (parseMBBReference(MBB))
+ return true;
Dest = MachineOperand::CreateMBB(MBB);
lex();
return false;
@@ -392,3 +414,10 @@ bool llvm::parseMachineInstr(
const SlotMapping &IRSlots, SMDiagnostic &Error) {
return MIParser(SM, MF, Error, Src, MBBSlots, IRSlots).parse(MI);
}
+
+bool llvm::parseMBBReference(
+ MachineBasicBlock *&MBB, SourceMgr &SM, MachineFunction &MF, StringRef Src,
+ const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots,
+ const SlotMapping &IRSlots, SMDiagnostic &Error) {
+ return MIParser(SM, MF, Error, Src, MBBSlots, IRSlots).parseMBB(MBB);
+}
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.h b/llvm/lib/CodeGen/MIRParser/MIParser.h
index bae5c2017a2..4d6d4e70021 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.h
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.h
@@ -31,6 +31,11 @@ bool parseMachineInstr(MachineInstr *&MI, SourceMgr &SM, MachineFunction &MF,
const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots,
const SlotMapping &IRSlots, SMDiagnostic &Error);
+bool parseMBBReference(MachineBasicBlock *&MBB, SourceMgr &SM,
+ MachineFunction &MF, StringRef Src,
+ const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots,
+ const SlotMapping &IRSlots, SMDiagnostic &Error);
+
} // end namespace llvm
#endif
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 064b2f15d65..39745830078 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -274,9 +274,18 @@ bool MIRParserImpl::initializeMachineBasicBlock(
if (YamlMBB.AddressTaken)
MBB.setHasAddressTaken();
MBB.setIsLandingPad(YamlMBB.IsLandingPad);
+ SMDiagnostic Error;
+ // Parse the successors.
+ for (const auto &MBBSource : YamlMBB.Successors) {
+ MachineBasicBlock *SuccMBB = nullptr;
+ if (parseMBBReference(SuccMBB, SM, MF, MBBSource.Value, MBBSlots, IRSlots,
+ Error))
+ return error(Error, MBBSource.SourceRange);
+ // TODO: Report an error when adding the same successor more than once.
+ MBB.addSuccessor(SuccMBB);
+ }
// Parse the instructions.
for (const auto &MISource : YamlMBB.Instructions) {
- SMDiagnostic Error;
MachineInstr *MI = nullptr;
if (parseMachineInstr(MI, SM, MF, MISource.Value, MBBSlots, IRSlots, Error))
return error(Error, MISource.SourceRange);
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index 18c976bcd3e..6b6675579cc 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -131,6 +131,12 @@ void MIRPrinter::convert(const Module &M, yaml::MachineBasicBlock &YamlMBB,
YamlMBB.Alignment = MBB.getAlignment();
YamlMBB.AddressTaken = MBB.hasAddressTaken();
YamlMBB.IsLandingPad = MBB.isLandingPad();
+ for (const auto *MBB : MBB.successors()) {
+ std::string Str;
+ raw_string_ostream StrOS(Str);
+ MIPrinter(M, StrOS, RegisterMaskIds).printMBBReference(*MBB);
+ YamlMBB.Successors.push_back(StrOS.str());
+ }
// Print the machine instructions.
YamlMBB.Instructions.reserve(MBB.size());
diff --git a/llvm/test/CodeGen/MIR/expected-eof-after-successor-mbb.mir b/llvm/test/CodeGen/MIR/expected-eof-after-successor-mbb.mir
new file mode 100644
index 00000000000..25ae5119297
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/expected-eof-after-successor-mbb.mir
@@ -0,0 +1,29 @@
+# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+
+--- |
+
+ define i32 @foo(i32 %a) {
+ entry:
+ %0 = icmp sle i32 %a, 10
+ br i1 %0, label %less, label %exit
+
+ less:
+ ret i32 0
+
+ exit:
+ ret i32 %a
+ }
+
+...
+---
+name: foo
+body:
+ - id: 0
+ name: entry
+ # CHECK: [[@LINE+1]]:46: expected end of string after the machine basic block reference
+ successors: [ '%bb.1.less', '%bb.2.exit 2' ]
+ - id: 1
+ name: less
+ - id: 2
+ name: exit
+...
diff --git a/llvm/test/CodeGen/MIR/expected-mbb-reference-for-successor-mbb.mir b/llvm/test/CodeGen/MIR/expected-mbb-reference-for-successor-mbb.mir
new file mode 100644
index 00000000000..ce9192901d7
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/expected-mbb-reference-for-successor-mbb.mir
@@ -0,0 +1,29 @@
+# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+
+--- |
+
+ define i32 @foo(i32 %a) {
+ entry:
+ %0 = icmp sle i32 %a, 10
+ br i1 %0, label %less, label %exit
+
+ less:
+ ret i32 0
+
+ exit:
+ ret i32 %a
+ }
+
+...
+---
+name: foo
+body:
+ - id: 0
+ name: entry
+ # CHECK: [[@LINE+1]]:35: expected a machine basic block reference
+ successors: [ '%bb.1.less', '2' ]
+ - id: 1
+ name: less
+ - id: 2
+ name: exit
+...
diff --git a/llvm/test/CodeGen/MIR/successor-basic-blocks.mir b/llvm/test/CodeGen/MIR/successor-basic-blocks.mir
new file mode 100644
index 00000000000..3fe01e3ad43
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/successor-basic-blocks.mir
@@ -0,0 +1,58 @@
+# RUN: llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s
+# This test ensures that the MIR parser parses basic block successors correctly.
+
+--- |
+
+ define i32 @foo(i32 %a) {
+ entry:
+ %0 = icmp sle i32 %a, 10
+ br i1 %0, label %less, label %exit
+
+ less:
+ ret i32 0
+
+ exit:
+ ret i32 %a
+ }
+
+ define i32 @bar(i32 %a) {
+ entry:
+ %b = icmp sle i32 %a, 10
+ br i1 %b, label %0, label %1
+
+ ; <label>:0
+ ret i32 0
+
+ ; <label>:1
+ ret i32 %a
+ }
+
+...
+---
+name: foo
+body:
+ # CHECK: name: entry
+ # CHECK: successors: [ '%bb.1.less', '%bb.2.exit' ]
+ # CHECK: name: less
+ - id: 0
+ name: entry
+ successors: [ '%bb.1.less', '%bb.2.exit' ]
+ - id: 1
+ name: less
+ - id: 2
+ name: exit
+...
+---
+name: bar
+body:
+ # CHECK: name: bar
+ # CHECK: name: entry
+ # CHECK: successors: [ '%bb.1', '%bb.2' ]
+ # CHECK: id: 1
+ # CHECK: id: 2
+ - id: 0
+ name: entry
+ successors: [ '%bb.1', '%bb.2' ]
+ - id: 1
+ - id: 2
+...
OpenPOWER on IntegriCloud