From a5da4f1f8d8751f6e8f1ddd4b787c6026a3b51f9 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Mon, 27 Jul 2015 17:42:45 +0000 Subject: [PATCH] MIR Serialization: Serialize the machine function's liveins. Reviewers: Duncan P. N. Exon Smith git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243288 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MIRYamlMapping.h | 20 +++++++++- lib/CodeGen/MIRParser/MIParser.cpp | 22 +++++++++++ lib/CodeGen/MIRParser/MIParser.h | 6 +++ lib/CodeGen/MIRParser/MIRParser.cpp | 15 ++++++++ lib/CodeGen/MIRPrinter.cpp | 9 +++++ ...ted-named-register-in-functions-livein.mir | 28 ++++++++++++++ ...d-virtual-register-in-functions-livein.mir | 28 ++++++++++++++ test/CodeGen/MIR/X86/function-liveins.mir | 38 +++++++++++++++++++ 8 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/MIR/X86/expected-named-register-in-functions-livein.mir create mode 100644 test/CodeGen/MIR/X86/expected-virtual-register-in-functions-livein.mir create mode 100644 test/CodeGen/MIR/X86/function-liveins.mir diff --git a/include/llvm/CodeGen/MIRYamlMapping.h b/include/llvm/CodeGen/MIRYamlMapping.h index 138882809e2..e14a1fd6327 100644 --- a/include/llvm/CodeGen/MIRYamlMapping.h +++ b/include/llvm/CodeGen/MIRYamlMapping.h @@ -116,6 +116,22 @@ template <> struct MappingTraits { static const bool flow = true; }; +struct MachineFunctionLiveIn { + StringValue Register; + StringValue VirtualRegister; +}; + +template <> struct MappingTraits { + static void mapping(IO &YamlIO, MachineFunctionLiveIn &LiveIn) { + YamlIO.mapRequired("reg", LiveIn.Register); + YamlIO.mapOptional( + "virtual-reg", LiveIn.VirtualRegister, + StringValue()); // Don't print the virtual register when it's empty. + } + + static const bool flow = true; +}; + struct MachineBasicBlock { unsigned ID; StringValue Name; @@ -266,6 +282,7 @@ template <> struct MappingTraits { } // end namespace yaml } // end namespace llvm +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineFunctionLiveIn) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject) @@ -337,8 +354,8 @@ struct MachineFunction { bool TracksRegLiveness = false; bool TracksSubRegLiveness = false; std::vector VirtualRegisters; + std::vector LiveIns; // TODO: Serialize the various register masks. - // TODO: Serialize live in registers. // Frame information MachineFrameInfo FrameInfo; std::vector FixedStackObjects; @@ -359,6 +376,7 @@ template <> struct MappingTraits { YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness); YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness); YamlIO.mapOptional("registers", MF.VirtualRegisters); + YamlIO.mapOptional("liveins", MF.LiveIns); YamlIO.mapOptional("frameInfo", MF.FrameInfo); YamlIO.mapOptional("fixedStack", MF.FixedStackObjects); YamlIO.mapOptional("stack", MF.StackObjects); diff --git a/lib/CodeGen/MIRParser/MIParser.cpp b/lib/CodeGen/MIRParser/MIParser.cpp index 656f2314315..bb25ec39eb0 100644 --- a/lib/CodeGen/MIRParser/MIParser.cpp +++ b/lib/CodeGen/MIRParser/MIParser.cpp @@ -98,6 +98,7 @@ public: bool parse(MachineInstr *&MI); bool parseMBB(MachineBasicBlock *&MBB); bool parseNamedRegister(unsigned &Reg); + bool parseStandaloneVirtualRegister(unsigned &Reg); bool parseRegister(unsigned &Reg); bool parseRegisterFlag(unsigned &Flags); @@ -289,6 +290,18 @@ bool MIParser::parseNamedRegister(unsigned &Reg) { return false; } +bool MIParser::parseStandaloneVirtualRegister(unsigned &Reg) { + lex(); + if (Token.isNot(MIToken::VirtualRegister)) + return error("expected a virtual register"); + if (parseRegister(Reg)) + return 0; + lex(); + if (Token.isNot(MIToken::Eof)) + return error("expected end of string after the register reference"); + return false; +} + static const char *printImplicitRegisterFlag(const MachineOperand &MO) { assert(MO.isImplicit()); return MO.isDef() ? "implicit-def" : "implicit"; @@ -843,3 +856,12 @@ bool llvm::parseNamedRegisterReference(unsigned &Reg, SourceMgr &SM, SMDiagnostic &Error) { return MIParser(SM, MF, Error, Src, PFS, IRSlots).parseNamedRegister(Reg); } + +bool llvm::parseVirtualRegisterReference(unsigned &Reg, SourceMgr &SM, + MachineFunction &MF, StringRef Src, + const PerFunctionMIParsingState &PFS, + const SlotMapping &IRSlots, + SMDiagnostic &Error) { + return MIParser(SM, MF, Error, Src, PFS, IRSlots) + .parseStandaloneVirtualRegister(Reg); +} diff --git a/lib/CodeGen/MIRParser/MIParser.h b/lib/CodeGen/MIRParser/MIParser.h index 888f2f57a31..49530f1a36e 100644 --- a/lib/CodeGen/MIRParser/MIParser.h +++ b/lib/CodeGen/MIRParser/MIParser.h @@ -50,6 +50,12 @@ bool parseNamedRegisterReference(unsigned &Reg, SourceMgr &SM, const SlotMapping &IRSlots, SMDiagnostic &Error); +bool parseVirtualRegisterReference(unsigned &Reg, SourceMgr &SM, + MachineFunction &MF, StringRef Src, + const PerFunctionMIParsingState &PFS, + const SlotMapping &IRSlots, + SMDiagnostic &Error); + } // end namespace llvm #endif diff --git a/lib/CodeGen/MIRParser/MIRParser.cpp b/lib/CodeGen/MIRParser/MIRParser.cpp index 7f226713817..45b401917a3 100644 --- a/lib/CodeGen/MIRParser/MIRParser.cpp +++ b/lib/CodeGen/MIRParser/MIRParser.cpp @@ -402,6 +402,21 @@ bool MIRParserImpl::initializeRegisterInfo(MachineFunction &MF, RegInfo.setSimpleHint(Reg, PreferredReg); } } + + // Parse the liveins. + for (const auto &LiveIn : YamlMF.LiveIns) { + unsigned Reg = 0; + if (parseNamedRegisterReference(Reg, SM, MF, LiveIn.Register.Value, PFS, + IRSlots, Error)) + return error(Error, LiveIn.Register.SourceRange); + unsigned VReg = 0; + if (!LiveIn.VirtualRegister.Value.empty()) { + if (parseVirtualRegisterReference( + VReg, SM, MF, LiveIn.VirtualRegister.Value, PFS, IRSlots, Error)) + return error(Error, LiveIn.VirtualRegister.SourceRange); + } + RegInfo.addLiveIn(Reg, VReg); + } return false; } diff --git a/lib/CodeGen/MIRPrinter.cpp b/lib/CodeGen/MIRPrinter.cpp index 2287dfd4480..5800db55628 100644 --- a/lib/CodeGen/MIRPrinter.cpp +++ b/lib/CodeGen/MIRPrinter.cpp @@ -201,6 +201,15 @@ void MIRPrinter::convert(yaml::MachineFunction &MF, printReg(PreferredReg, VReg.PreferredRegister, TRI); MF.VirtualRegisters.push_back(VReg); } + + // Print the live ins. + for (auto I = RegInfo.livein_begin(), E = RegInfo.livein_end(); I != E; ++I) { + yaml::MachineFunctionLiveIn LiveIn; + printReg(I->first, LiveIn.Register, TRI); + if (I->second) + printReg(I->second, LiveIn.VirtualRegister, TRI); + MF.LiveIns.push_back(LiveIn); + } } void MIRPrinter::convert(yaml::MachineFrameInfo &YamlMFI, diff --git a/test/CodeGen/MIR/X86/expected-named-register-in-functions-livein.mir b/test/CodeGen/MIR/X86/expected-named-register-in-functions-livein.mir new file mode 100644 index 00000000000..b14ff32694a --- /dev/null +++ b/test/CodeGen/MIR/X86/expected-named-register-in-functions-livein.mir @@ -0,0 +1,28 @@ +# RUN: not llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s 2>&1 | FileCheck %s + +--- | + + define i32 @test(i32 %a) { + body: + ret i32 %a + } + +... +--- +name: test +isSSA: true +tracksRegLiveness: true +registers: + - { id: 0, class: gr32 } +liveins: + # CHECK: [[@LINE+1]]:13: expected a named register + - { reg: '%0' } +body: + - id: 0 + name: body + liveins: [ '%edi' ] + instructions: + - '%0 = COPY %edi' + - '%eax = COPY %0' + - 'RETQ %eax' +... diff --git a/test/CodeGen/MIR/X86/expected-virtual-register-in-functions-livein.mir b/test/CodeGen/MIR/X86/expected-virtual-register-in-functions-livein.mir new file mode 100644 index 00000000000..edadf42056b --- /dev/null +++ b/test/CodeGen/MIR/X86/expected-virtual-register-in-functions-livein.mir @@ -0,0 +1,28 @@ +# RUN: not llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s 2>&1 | FileCheck %s + +--- | + + define i32 @test(i32 %a) { + body: + ret i32 %a + } + +... +--- +name: test +isSSA: true +tracksRegLiveness: true +registers: + - { id: 0, class: gr32 } +liveins: + # CHECK: [[@LINE+1]]:34: expected a virtual register + - { reg: '%edi', virtual-reg: '%edi' } +body: + - id: 0 + name: body + liveins: [ '%edi' ] + instructions: + - '%0 = COPY %edi' + - '%eax = COPY %0' + - 'RETQ %eax' +... diff --git a/test/CodeGen/MIR/X86/function-liveins.mir b/test/CodeGen/MIR/X86/function-liveins.mir new file mode 100644 index 00000000000..d3c9d3f72cd --- /dev/null +++ b/test/CodeGen/MIR/X86/function-liveins.mir @@ -0,0 +1,38 @@ +# RUN: llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s | FileCheck %s +# This test ensures that the MIR parser parses machine function's liveins +# correctly. + +--- | + + define i32 @test(i32 %a, i32 %b) { + body: + %c = add i32 %a, %b + ret i32 %c + } + +... +--- +name: test +isSSA: true +tracksRegLiveness: true +registers: + - { id: 0, class: gr32 } + - { id: 1, class: gr32 } + - { id: 2, class: gr32 } +# CHECK: liveins: +# CHECK-NEXT: - { reg: '%edi', virtual-reg: '%0' } +# CHECK-NEXT: - { reg: '%esi', virtual-reg: '%1' } +liveins: + - { reg: '%edi', virtual-reg: '%0' } + - { reg: '%esi', virtual-reg: '%1' } +body: + - id: 0 + name: body + liveins: [ '%edi', '%esi' ] + instructions: + - '%1 = COPY %esi' + - '%0 = COPY %edi' + - '%2 = ADD32rr %0, %1, implicit-def dead %eflags' + - '%eax = COPY %2' + - 'RETQ %eax' +... -- 2.34.1