[llvm] r241519 - MIR Serialization: Serialize the implicit register flag.

Alex Lorenz arphaman at gmail.com
Mon Jul 6 16:07:26 PDT 2015


Author: arphaman
Date: Mon Jul  6 18:07:26 2015
New Revision: 241519

URL: http://llvm.org/viewvc/llvm-project?rev=241519&view=rev
Log:
MIR Serialization: Serialize the implicit register flag.

This commit serializes the implicit flag for the register machine operands. It
introduces two new keywords into the machine instruction syntax: 'implicit' and
'implicit-def'. The 'implicit' keyword is used for the implicit register
operands, and the 'implicit-def' keyword is used for the register operands that
have both the implicit and the define flags set.

Reviewers: Duncan P. N. Exon Smith

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

Added:
    llvm/trunk/test/CodeGen/MIR/X86/expected-register-after-flags.mir
    llvm/trunk/test/CodeGen/MIR/X86/implicit-register-flag.mir
Modified:
    llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp
    llvm/trunk/lib/CodeGen/MIRParser/MILexer.h
    llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
    llvm/trunk/lib/CodeGen/MIRPrinter.cpp
    llvm/trunk/test/CodeGen/MIR/X86/register-mask-operands.mir

Modified: llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp?rev=241519&r1=241518&r2=241519&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp Mon Jul  6 18:07:26 2015
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "MILexer.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Twine.h"
 #include <cctype>
 
@@ -64,6 +65,14 @@ static bool isIdentifierChar(char C) {
   return isalpha(C) || isdigit(C) || C == '_' || C == '-' || C == '.';
 }
 
+static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
+  return StringSwitch<MIToken::TokenKind>(Identifier)
+      .Case("_", MIToken::underscore)
+      .Case("implicit", MIToken::kw_implicit)
+      .Case("implicit-def", MIToken::kw_implicit_define)
+      .Default(MIToken::Identifier);
+}
+
 static Cursor maybeLexIdentifier(Cursor C, MIToken &Token) {
   if (!isalpha(C.peek()) && C.peek() != '_')
     return None;
@@ -71,8 +80,7 @@ static Cursor maybeLexIdentifier(Cursor
   while (isIdentifierChar(C.peek()))
     C.advance();
   auto Identifier = Range.upto(C);
-  Token = MIToken(Identifier == "_" ? MIToken::underscore : MIToken::Identifier,
-                  Identifier);
+  Token = MIToken(getIdentifierKind(Identifier), Identifier);
   return C;
 }
 

Modified: llvm/trunk/lib/CodeGen/MIRParser/MILexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MILexer.h?rev=241519&r1=241518&r2=241519&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MILexer.h (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.h Mon Jul  6 18:07:26 2015
@@ -36,6 +36,10 @@ struct MIToken {
     equal,
     underscore,
 
+    // Keywords
+    kw_implicit,
+    kw_implicit_define,
+
     // Identifier tokens
     Identifier,
     NamedRegister,
@@ -69,6 +73,10 @@ public:
     return Kind == NamedRegister || Kind == underscore;
   }
 
+  bool isRegisterFlag() const {
+    return Kind == kw_implicit || Kind == kw_implicit_define;
+  }
+
   bool is(TokenKind K) const { return Kind == K; }
 
   bool isNot(TokenKind K) const { return Kind != K; }

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp?rev=241519&r1=241518&r2=241519&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp Mon Jul  6 18:07:26 2015
@@ -18,6 +18,7 @@
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/SourceMgr.h"
@@ -67,6 +68,7 @@ public:
   bool parseMBB(MachineBasicBlock *&MBB);
 
   bool parseRegister(unsigned &Reg);
+  bool parseRegisterFlag(unsigned &Flags);
   bool parseRegisterOperand(MachineOperand &Dest, bool IsDef = false);
   bool parseImmediateOperand(MachineOperand &Dest);
   bool parseMBBReference(MachineBasicBlock *&MBB);
@@ -138,7 +140,7 @@ bool MIParser::parse(MachineInstr *&MI)
   // TODO: Allow parsing of multiple operands before '='
   MachineOperand MO = MachineOperand::CreateImm(0);
   SmallVector<MachineOperand, 8> Operands;
-  if (Token.isRegister()) {
+  if (Token.isRegister() || Token.isRegisterFlag()) {
     if (parseRegisterOperand(MO, /*IsDef=*/true))
       return true;
     Operands.push_back(MO);
@@ -167,21 +169,8 @@ bool MIParser::parse(MachineInstr *&MI)
 
   const auto &MCID = MF.getSubtarget().getInstrInfo()->get(OpCode);
 
-  // Verify machine operands.
-  if (!MCID.isVariadic()) {
-    for (size_t I = 0, E = Operands.size(); I < E; ++I) {
-      if (I < MCID.getNumOperands())
-        continue;
-      // Mark this register as implicit to prevent an assertion when it's added
-      // to an instruction. This is a temporary workaround until the implicit
-      // register flag can be parsed.
-      if (Operands[I].isReg())
-        Operands[I].setImplicit();
-    }
-  }
-
-  // TODO: Determine the implicit behaviour when implicit register flags are
-  // parsed.
+  // TODO: Check for extraneous machine operands.
+  // TODO: Check that this instruction has the implicit register operands.
   MI = MF.CreateMachineInstr(MCID, DebugLoc(), /*NoImplicit=*/true);
   for (const auto &Operand : Operands)
     MI->addOperand(MF, Operand);
@@ -229,14 +218,38 @@ bool MIParser::parseRegister(unsigned &R
   return false;
 }
 
+bool MIParser::parseRegisterFlag(unsigned &Flags) {
+  switch (Token.kind()) {
+  case MIToken::kw_implicit:
+    Flags |= RegState::Implicit;
+    break;
+  case MIToken::kw_implicit_define:
+    Flags |= RegState::ImplicitDefine;
+    break;
+  // TODO: report an error when we specify the same flag more than once.
+  // TODO: parse the other register flags.
+  default:
+    llvm_unreachable("The current token should be a register flag");
+  }
+  lex();
+  return false;
+}
+
 bool MIParser::parseRegisterOperand(MachineOperand &Dest, bool IsDef) {
   unsigned Reg;
-  // TODO: Parse register flags.
+  unsigned Flags = IsDef ? RegState::Define : 0;
+  while (Token.isRegisterFlag()) {
+    if (parseRegisterFlag(Flags))
+      return true;
+  }
+  if (!Token.isRegister())
+    return error("expected a register after register flags");
   if (parseRegister(Reg))
     return true;
   lex();
   // TODO: Parse subregister.
-  Dest = MachineOperand::CreateReg(Reg, IsDef);
+  Dest = MachineOperand::CreateReg(Reg, Flags & RegState::Define,
+                                   Flags & RegState::Implicit);
   return false;
 }
 
@@ -318,6 +331,8 @@ bool MIParser::parseGlobalAddressOperand
 
 bool MIParser::parseMachineOperand(MachineOperand &Dest) {
   switch (Token.kind()) {
+  case MIToken::kw_implicit:
+  case MIToken::kw_implicit_define:
   case MIToken::underscore:
   case MIToken::NamedRegister:
     return parseRegisterOperand(Dest);

Modified: llvm/trunk/lib/CodeGen/MIRPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRPrinter.cpp?rev=241519&r1=241518&r2=241519&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp Mon Jul  6 18:07:26 2015
@@ -211,7 +211,9 @@ void MIPrinter::printMBBReference(const
 void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
   switch (Op.getType()) {
   case MachineOperand::MO_Register:
-    // TODO: Print register flags.
+    // TODO: Print the other register flags.
+    if (Op.isImplicit())
+      OS << (Op.isDef() ? "implicit-def " : "implicit ");
     printReg(Op.getReg(), OS, TRI);
     // TODO: Print sub register.
     break;

Added: llvm/trunk/test/CodeGen/MIR/X86/expected-register-after-flags.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/expected-register-after-flags.mir?rev=241519&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/expected-register-after-flags.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/expected-register-after-flags.mir Mon Jul  6 18:07:26 2015
@@ -0,0 +1,22 @@
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+# This test ensures that an error is reported when a register operand doesn't
+# follow register flags.
+
+--- |
+
+  define i32 @foo() {
+  entry:
+    ret i32 0
+  }
+
+...
+---
+name:            foo
+body:
+ - id:           0
+   name:         entry
+   instructions:
+     # CHECK: [[@LINE+1]]:37: expected a register after register flags
+     - '%eax = MOV32r0 implicit-def 2'
+     - 'RETQ %eax'
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/implicit-register-flag.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/implicit-register-flag.mir?rev=241519&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/implicit-register-flag.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/implicit-register-flag.mir Mon Jul  6 18:07:26 2015
@@ -0,0 +1,41 @@
+# RUN: llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s
+# This test ensures that the MIR parser parses the 'implicit' and 'implicit-def'
+# register flags 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
+  }
+
+...
+---
+name:            foo
+body:
+  - id:          0
+    name:        entry
+    instructions:
+      # CHECK:      - 'CMP32ri8 %edi, 10, implicit-def %eflags'
+      # CHECK-NEXT: - 'JG_1 %bb.2.exit, implicit %eflags'
+      - 'CMP32ri8 %edi, 10, implicit-def %eflags'
+      - 'JG_1 %bb.2.exit, implicit %eflags'
+  - id:          1
+    name:        less
+    instructions:
+      # CHECK: - '%eax = MOV32r0 implicit-def %eflags'
+      - '%eax = MOV32r0 implicit-def %eflags'
+      - 'RETQ %eax'
+  - id:          2
+    name:        exit
+    instructions:
+      - '%eax = COPY %edi'
+      - 'RETQ %eax'
+...

Modified: llvm/trunk/test/CodeGen/MIR/X86/register-mask-operands.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/register-mask-operands.mir?rev=241519&r1=241518&r2=241519&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/register-mask-operands.mir (original)
+++ llvm/trunk/test/CodeGen/MIR/X86/register-mask-operands.mir Mon Jul  6 18:07:26 2015
@@ -35,9 +35,9 @@ body:
     name:        entry
     instructions:
       # CHECK:      - 'PUSH64r %rax
-      # CHECK-NEXT: - 'CALL64pcrel32 @compute, csr_64, %rsp, %edi, %rsp, %eax'
+      # CHECK-NEXT: - 'CALL64pcrel32 @compute, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax'
       - 'PUSH64r %rax'
-      - 'CALL64pcrel32 @compute, csr_64, %rsp, %edi, %rsp, %eax'
+      - 'CALL64pcrel32 @compute, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax'
       - '%rdx = POP64r'
       - 'RETQ %eax'
 ...





More information about the llvm-commits mailing list