From baf422e9ece686d0c1ad95b35e1e8d963802789f Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Wed, 19 Aug 2015 18:55:47 +0000 Subject: [PATCH] MIR Serialization: Serialize defined registers that require 'def' register flag. The defined registers are already serialized - they are represented by placing them before the '=' in a machine instruction. However, certain instructions like INLINEASM can have defined register operands after the '=', so this commit introduces the 'def' register flag for such operands. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245480 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MIRParser/MILexer.cpp | 1 + lib/CodeGen/MIRParser/MILexer.h | 7 +++-- lib/CodeGen/MIRParser/MIParser.cpp | 4 +++ lib/CodeGen/MIRPrinter.cpp | 11 +++++-- test/CodeGen/MIR/X86/inline-asm-registers.mir | 29 +++++++++++++++++++ 5 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 test/CodeGen/MIR/X86/inline-asm-registers.mir diff --git a/lib/CodeGen/MIRParser/MILexer.cpp b/lib/CodeGen/MIRParser/MILexer.cpp index 68c5e8af1a6..034a7d6e980 100644 --- a/lib/CodeGen/MIRParser/MILexer.cpp +++ b/lib/CodeGen/MIRParser/MILexer.cpp @@ -188,6 +188,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) { .Case("_", MIToken::underscore) .Case("implicit", MIToken::kw_implicit) .Case("implicit-def", MIToken::kw_implicit_define) + .Case("def", MIToken::kw_def) .Case("dead", MIToken::kw_dead) .Case("killed", MIToken::kw_killed) .Case("undef", MIToken::kw_undef) diff --git a/lib/CodeGen/MIRParser/MILexer.h b/lib/CodeGen/MIRParser/MILexer.h index fe8fc091b44..f0702fa01af 100644 --- a/lib/CodeGen/MIRParser/MILexer.h +++ b/lib/CodeGen/MIRParser/MILexer.h @@ -49,6 +49,7 @@ struct MIToken { // Keywords kw_implicit, kw_implicit_define, + kw_def, kw_dead, kw_killed, kw_undef, @@ -145,9 +146,9 @@ public: bool isRegisterFlag() const { return Kind == kw_implicit || Kind == kw_implicit_define || - Kind == kw_dead || Kind == kw_killed || Kind == kw_undef || - Kind == kw_internal || Kind == kw_early_clobber || - Kind == kw_debug_use; + Kind == kw_def || Kind == kw_dead || Kind == kw_killed || + Kind == kw_undef || Kind == kw_internal || + Kind == kw_early_clobber || Kind == kw_debug_use; } bool isMemoryOperandFlag() const { diff --git a/lib/CodeGen/MIRParser/MIParser.cpp b/lib/CodeGen/MIRParser/MIParser.cpp index edfca5f88a4..481bc1da981 100644 --- a/lib/CodeGen/MIRParser/MIParser.cpp +++ b/lib/CodeGen/MIRParser/MIParser.cpp @@ -816,6 +816,9 @@ bool MIParser::parseRegisterFlag(unsigned &Flags) { case MIToken::kw_implicit_define: Flags |= RegState::ImplicitDefine; break; + case MIToken::kw_def: + Flags |= RegState::Define; + break; case MIToken::kw_dead: Flags |= RegState::Dead; break; @@ -1297,6 +1300,7 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) { switch (Token.kind()) { case MIToken::kw_implicit: case MIToken::kw_implicit_define: + case MIToken::kw_def: case MIToken::kw_dead: case MIToken::kw_killed: case MIToken::kw_undef: diff --git a/lib/CodeGen/MIRPrinter.cpp b/lib/CodeGen/MIRPrinter.cpp index faeb9055c23..5d3c2999a11 100644 --- a/lib/CodeGen/MIRPrinter.cpp +++ b/lib/CodeGen/MIRPrinter.cpp @@ -116,7 +116,8 @@ public: void printStackObjectReference(int FrameIndex); void printOffset(int64_t Offset); void printTargetFlags(const MachineOperand &Op); - void print(const MachineOperand &Op, const TargetRegisterInfo *TRI); + void print(const MachineOperand &Op, const TargetRegisterInfo *TRI, + bool IsDef = false); void print(const MachineMemOperand &Op); void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI); @@ -516,7 +517,7 @@ void MIPrinter::print(const MachineInstr &MI) { ++I) { if (I) OS << ", "; - print(MI.getOperand(I), TRI); + print(MI.getOperand(I), TRI, /*IsDef=*/true); } if (I) @@ -688,13 +689,17 @@ static const char *getTargetIndexName(const MachineFunction &MF, int Index) { return nullptr; } -void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { +void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI, + bool IsDef) { printTargetFlags(Op); switch (Op.getType()) { case MachineOperand::MO_Register: // FIXME: Serialize the tied register. if (Op.isImplicit()) OS << (Op.isDef() ? "implicit-def " : "implicit "); + else if (!IsDef && Op.isDef()) + // Print the 'def' flag only when the operand is defined after '='. + OS << "def "; if (Op.isInternalRead()) OS << "internal "; if (Op.isDead()) diff --git a/test/CodeGen/MIR/X86/inline-asm-registers.mir b/test/CodeGen/MIR/X86/inline-asm-registers.mir new file mode 100644 index 00000000000..cad1d22030b --- /dev/null +++ b/test/CodeGen/MIR/X86/inline-asm-registers.mir @@ -0,0 +1,29 @@ +# RUN: llc -march=x86-64 -start-after block-placement -stop-after block-placement -o /dev/null %s | FileCheck %s + +--- | + define i64 @test(i64 %x, i64 %y) #0 { + entry: + %x0 = call { i64, i64 } asm "foo", "=r,=r,1,0,~{dirflag},~{fpsr},~{flags}"(i64 %x, i64 %y) #0 + %x1 = extractvalue { i64, i64 } %x0, 0 + ret i64 %x1 + } + + attributes #0 = { nounwind } +... +--- +name: test +hasInlineAsm: true +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } + - { reg: '%rsi' } +body: | + bb.0.entry: + liveins: %rdi, %rsi + + ; CHECK-LABEL: name: test + ; CHECK: INLINEASM $foo, 0, 2818058, def %rsi, 2818058, def dead %rdi, + INLINEASM $foo, 0, 2818058, def %rsi, 2818058, def dead %rdi, 2147549193, killed %rdi, 2147483657, killed %rsi, 12, implicit-def dead early-clobber %eflags + %rax = MOV64rr killed %rsi + RETQ killed %rax +... -- 2.34.1