partition operand processing between aliases and instructions.
authorChris Lattner <sabre@nondot.org>
Thu, 4 Nov 2010 02:11:18 +0000 (02:11 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 4 Nov 2010 02:11:18 +0000 (02:11 +0000)
Right now the code is partitioned but the behavior is the same.
This should be improved in the near future.   This removes some
uses of TheOperandList.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118232 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/AsmMatcherEmitter.cpp

index 2ffdd13ab8743d58cb38b473a5b9071ea165f565..75bcc046f69a800da116e20473a97d36f065b8f6 100644 (file)
@@ -75,6 +75,7 @@
 #include "Record.h"
 #include "StringMatcher.h"
 #include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/STLExtras.h"
@@ -312,6 +313,9 @@ struct MatchableInfo {
   /// matchable came from.
   Record *const TheDef;
   
+  /// DefRec - This is the definition that it came from.
+  PointerUnion<const CodeGenInstruction*, const CodeGenInstAlias*> DefRec;
+  
   // FIXME: REMOVE.
   const CGIOperandList &TheOperandList;
 
@@ -343,12 +347,13 @@ struct MatchableInfo {
   std::string ConversionFnKind;
   
   MatchableInfo(const CodeGenInstruction &CGI)
-    : TheDef(CGI.TheDef), TheOperandList(CGI.Operands), AsmString(CGI.AsmString) {
+    : TheDef(CGI.TheDef), DefRec(&CGI),
+      TheOperandList(CGI.Operands), AsmString(CGI.AsmString) {
     InstrName = TheDef->getName();
   }
 
   MatchableInfo(const CodeGenInstAlias *Alias)
-    : TheDef(Alias->TheDef), TheOperandList(Alias->Operands),
+    : TheDef(Alias->TheDef), DefRec(Alias), TheOperandList(Alias->Operands),
       AsmString(Alias->AsmString) {
         
     // FIXME: Huge hack.
@@ -510,9 +515,13 @@ private:
   /// operand classes.
   void BuildOperandClasses();
 
-  void BuildInstructionOperandReference(MatchableInfo *II, StringRef OpName,
+  void BuildInstructionOperandReference(MatchableInfo *II,
+                                        StringRef OpName,
                                         MatchableInfo::AsmOperand &Op);
-
+  void BuildAliasOperandReference(MatchableInfo *II,
+                                  StringRef OpName,
+                                  MatchableInfo::AsmOperand &Op);
+                                  
 public:
   AsmMatcherInfo(Record *AsmParser, CodeGenTarget &Target);
 
@@ -1100,14 +1109,19 @@ void AsmMatcherInfo::BuildInfo() {
         continue;
       }
 
+      // Otherwise this is an operand reference.
       StringRef OperandName;
       if (Token[1] == '{')
         OperandName = Token.substr(2, Token.size() - 3);
       else
         OperandName = Token.substr(1);
       
-      // Otherwise this is an operand reference.
-      BuildInstructionOperandReference(II, OperandName, Op);
+      if (II->DefRec.is<const CodeGenInstruction*>())
+        BuildInstructionOperandReference(II,
+                                         OperandName, Op);
+      else
+        BuildAliasOperandReference(II,
+                                   OperandName, Op);
     }
     
     II->BuildResultOperands();
@@ -1123,8 +1137,8 @@ void AsmMatcherInfo::
 BuildInstructionOperandReference(MatchableInfo *II,
                                  StringRef OperandName,
                                  MatchableInfo::AsmOperand &Op) {
-  const CGIOperandList &Operands = II->TheOperandList;
-  
+  const CodeGenInstruction &CGI = *II->DefRec.get<const CodeGenInstruction*>();
+  const CGIOperandList &Operands = CGI.Operands;
   
   // Map this token to an operand. FIXME: Move elsewhere.
   unsigned Idx;
@@ -1158,6 +1172,49 @@ BuildInstructionOperandReference(MatchableInfo *II,
   Op.SrcOpName = OperandName;
 }
 
+void AsmMatcherInfo::BuildAliasOperandReference(MatchableInfo *II,
+                                                StringRef OperandName,
+                                                MatchableInfo::AsmOperand &Op) {
+  const CodeGenInstAlias &CGA = *II->DefRec.get<const CodeGenInstAlias*>();
+  
+  
+  // FIXME: This is a total hack, it should not be a copy of
+  // BuildInstructionOperandReference
+  
+  const CGIOperandList &Operands = CGA.Operands;
+  
+  // Map this token to an operand. FIXME: Move elsewhere.
+  unsigned Idx;
+  if (!Operands.hasOperandNamed(OperandName, Idx))
+    throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" +
+                  OperandName.str() + "'");
+  
+  // Set up the operand class.
+  Op.Class = getOperandClass(Operands[Idx]);
+  
+  // If the named operand is tied, canonicalize it to the untied operand.
+  // For example, something like:
+  //   (outs GPR:$dst), (ins GPR:$src)
+  // with an asmstring of
+  //   "inc $src"
+  // we want to canonicalize to:
+  //   "inc $dst"
+  // so that we know how to provide the $dst operand when filling in the result.
+  int OITied = Operands[Idx].getTiedRegister();
+  if (OITied != -1) {
+    // The tied operand index is an MIOperand index, find the operand that
+    // contains it.
+    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
+      if (Operands[i].MIOperandNo == unsigned(OITied)) {
+        OperandName = Operands[i].Name;
+        break;
+      }
+    }
+  }
+  
+  Op.SrcOpName = OperandName;
+}
+
 void MatchableInfo::BuildResultOperands() {
   for (unsigned i = 0, e = TheOperandList.size(); i != e; ++i) {
     const CGIOperandList::OperandInfo &OpInfo = TheOperandList[i];