diff options
-rw-r--r-- | llvm/include/llvm/CodeGen/MIRYamlMapping.h | 22 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.cpp | 33 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.h | 5 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRPrinter.cpp | 6 | ||||
-rw-r--r-- | llvm/test/CodeGen/MIR/expected-eof-after-successor-mbb.mir | 29 | ||||
-rw-r--r-- | llvm/test/CodeGen/MIR/expected-mbb-reference-for-successor-mbb.mir | 29 | ||||
-rw-r--r-- | llvm/test/CodeGen/MIR/successor-basic-blocks.mir | 58 |
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 +... |