[llvm] r262890 - [MIR] Teach the parser how to parse complex types of generic machine instructions.

Quentin Colombet via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 7 16:57:31 PST 2016


Author: qcolombet
Date: Mon Mar  7 18:57:31 2016
New Revision: 262890

URL: http://llvm.org/viewvc/llvm-project?rev=262890&view=rev
Log:
[MIR] Teach the parser how to parse complex types of generic machine instructions.
By complex types, I mean aggregate or vector types.

Modified:
    llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp
    llvm/trunk/lib/CodeGen/MIRParser/MILexer.h
    llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
    llvm/trunk/test/CodeGen/MIR/X86/generic-virtual-registers.mir

Modified: llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp?rev=262890&r1=262889&r2=262890&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp Mon Mar  7 18:57:31 2016
@@ -497,6 +497,10 @@ static MIToken::TokenKind symbolToken(ch
     return MIToken::plus;
   case '-':
     return MIToken::minus;
+  case '<':
+    return MIToken::lt;
+  case '>':
+    return MIToken::gt;
   default:
     return MIToken::Error;
   }

Modified: llvm/trunk/lib/CodeGen/MIRParser/MILexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MILexer.h?rev=262890&r1=262889&r2=262890&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MILexer.h (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.h Mon Mar  7 18:57:31 2016
@@ -45,6 +45,8 @@ struct MIToken {
     rbrace,
     plus,
     minus,
+    lt,
+    gt,
 
     // Keywords
     kw_implicit,

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp?rev=262890&r1=262889&r2=262890&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp Mon Mar  7 18:57:31 2016
@@ -88,7 +88,9 @@ public:
            StringRef Source, const PerFunctionMIParsingState &PFS,
            const SlotMapping &IRSlots);
 
-  void lex();
+  /// \p SkipChar gives the number of characters to skip before looking
+  /// for the next token.
+  void lex(unsigned SkipChar = 0);
 
   /// Report an error at the current location with the given message.
   ///
@@ -127,8 +129,10 @@ public:
   bool parseIRConstant(StringRef::iterator Loc, StringRef Source,
                        const Constant *&C);
   bool parseIRConstant(StringRef::iterator Loc, const Constant *&C);
-  bool parseIRType(StringRef::iterator Loc, StringRef Source, Type *&Ty);
-  bool parseIRType(StringRef::iterator Loc, Type *&Ty);
+  bool parseIRType(StringRef::iterator Loc, StringRef Source, unsigned &Read,
+                   Type *&Ty);
+  // \p MustBeSized defines whether or not \p Ty must be sized.
+  bool parseIRType(StringRef::iterator Loc, Type *&Ty, bool MustBeSized = true);
   bool parseTypedImmediateOperand(MachineOperand &Dest);
   bool parseFPImmediateOperand(MachineOperand &Dest);
   bool parseMBBReference(MachineBasicBlock *&MBB);
@@ -254,9 +258,9 @@ MIParser::MIParser(SourceMgr &SM, Machin
     : SM(SM), MF(MF), Error(Error), Source(Source), CurrentSource(Source),
       PFS(PFS), IRSlots(IRSlots) {}
 
-void MIParser::lex() {
+void MIParser::lex(unsigned SkipChar) {
   CurrentSource = lexMIToken(
-      CurrentSource, Token,
+      CurrentSource.data() + SkipChar, Token,
       [this](StringRef::iterator Loc, const Twine &Msg) { error(Loc, Msg); });
 }
 
@@ -597,10 +601,6 @@ bool MIParser::parse(MachineInstr *&MI)
     auto Loc = Token.location();
     if (parseIRType(Loc, Ty))
       return true;
-    // The type must be sized, otherwise there is not much the backend
-    // can do with it.
-    if (!Ty->isSized())
-      return error("expected a fully defined type for generic instruction");
   }
 
   // Parse the remaining machine operands.
@@ -1019,19 +1019,34 @@ bool MIParser::parseIRConstant(StringRef
 }
 
 bool MIParser::parseIRType(StringRef::iterator Loc, StringRef StringValue,
-                           Type *&Ty) {
+                           unsigned &Read, Type *&Ty) {
   auto Source = StringValue.str(); // The source has to be null terminated.
   SMDiagnostic Err;
-  Ty = parseType(Source.c_str(), Err, *MF.getFunction()->getParent(), &IRSlots);
+  Ty = parseTypeAtBeginning(Source.c_str(), Read, Err,
+                            *MF.getFunction()->getParent(), &IRSlots);
   if (!Ty)
     return error(Loc + Err.getColumnNo(), Err.getMessage());
   return false;
 }
 
-bool MIParser::parseIRType(StringRef::iterator Loc, Type *&Ty) {
-  if (parseIRType(Loc, StringRef(Loc, Token.range().end() - Loc), Ty))
-    return true;
-  lex();
+bool MIParser::parseIRType(StringRef::iterator Loc, Type *&Ty,
+                           bool MustBeSized) {
+  // At this point we enter in the IR world, i.e., to get the correct type,
+  // we need to hand off the whole string, not just the current token.
+  // E.g., <4 x i64> would give '<' as a token and there is not much
+  // the IR parser can do with that.
+  unsigned Read = 0;
+  if (parseIRType(Loc, StringRef(Loc), Read, Ty))
+    return true;
+  // The type must be sized, otherwise there is not much the backend
+  // can do with it.
+  if (MustBeSized && !Ty->isSized())
+    return error("expected a sized type");
+  // The next token is Read characters from the Loc.
+  // However, the current location is not Loc, but Loc + the length of Token.
+  // Therefore, subtract the length of Token (range().end() - Loc) to the
+  // number of characters to skip before the next token.
+  lex(Read - (Token.range().end() - Loc));
   return false;
 }
 

Modified: llvm/trunk/test/CodeGen/MIR/X86/generic-virtual-registers.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/generic-virtual-registers.mir?rev=262890&r1=262889&r2=262890&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/generic-virtual-registers.mir (original)
+++ llvm/trunk/test/CodeGen/MIR/X86/generic-virtual-registers.mir Mon Mar  7 18:57:31 2016
@@ -3,16 +3,43 @@
 # This test ensures that the MIR parser parses generic virtual
 # register definitions correctly.
 
+--- |
+  ; ModuleID = 'generic-virtual-registers-type-error.mir'
+  target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+  %type_alias = type <2 x i32>
+  %structure_alias = type { i32, i16 }
+  define void @bar() {
+  entry:
+    ret void
+  }
+
+...
+
 ---
 name:            bar
 isSSA:           true
 # CHECK:      registers:
 # CHECK-NEXT:   - { id: 0, class: gr32 }
+# CHECK-NEXT:   - { id: 1, class: gr64 }
 registers:
   - { id: 0, class: gr32 }
+  - { id: 1, class: gr64 }
+  - { id: 2, class: gr64 }
+  - { id: 3, class: gr64 }
+  - { id: 4, class: gr64 }
 body: |
   bb.0.entry:
     liveins: %edi
     ; CHECK:      %0(32) = G_ADD i32 %edi
     %0(32) = G_ADD i32 %edi, %edi
+    ; CHECK:      %1(64) = G_ADD <2 x i32> %edi
+    %1(64) = G_ADD <2 x i32> %edi, %edi
+    ; CHECK:      %2(64) = G_ADD <2 x i32> %edi
+    %2(64) = G_ADD %type_alias %edi, %edi
+    ; G_ADD is actually not a valid operand for structure type,
+    ; but that is the only one we have for now for testing.
+    ; CHECK:      %3(64) = G_ADD { i32, i32 } %edi
+    %3(64) = G_ADD {i32, i32} %edi, %edi
+    ; CHECK:      %4(48) = G_ADD %structure_alias %edi
+    %4(48) = G_ADD %structure_alias %edi, %edi
 ...




More information about the llvm-commits mailing list