[llvm-commits] [llvm] r73078 - in /llvm/trunk: include/llvm/Target/TargetSelectionDAG.td test/TableGen/Slice.td utils/TableGen/CodeGenDAGPatterns.cpp utils/TableGen/Record.cpp utils/TableGen/Record.h utils/TableGen/TGParser.cpp utils/TableGen/TGParser.h

David Greene greened at obbligato.org
Mon Jun 8 13:23:20 PDT 2009


Author: greened
Date: Mon Jun  8 15:23:18 2009
New Revision: 73078

URL: http://llvm.org/viewvc/llvm-project?rev=73078&view=rev
Log:

Make IntInits and ListInits typed.  This helps deduce types of !if and
other operators.  For the rare cases where a list type cannot be
deduced, provide a []<type> syntax, where <type> is the list element
type.

Added:
    llvm/trunk/test/TableGen/Slice.td
Modified:
    llvm/trunk/include/llvm/Target/TargetSelectionDAG.td
    llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
    llvm/trunk/utils/TableGen/Record.cpp
    llvm/trunk/utils/TableGen/Record.h
    llvm/trunk/utils/TableGen/TGParser.cpp
    llvm/trunk/utils/TableGen/TGParser.h

Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSelectionDAG.td?rev=73078&r1=73077&r2=73078&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetSelectionDAG.td (original)
+++ llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Mon Jun  8 15:23:18 2009
@@ -228,6 +228,7 @@
   SDTypeProfile TypeProfile = typeprof;
 }
 
+// Special TableGen-recognized dag nodes
 def set;
 def implicit;
 def parallel;

Added: llvm/trunk/test/TableGen/Slice.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/Slice.td?rev=73078&view=auto

==============================================================================
--- llvm/trunk/test/TableGen/Slice.td (added)
+++ llvm/trunk/test/TableGen/Slice.td Mon Jun  8 15:23:18 2009
@@ -0,0 +1,87 @@
+// RUN: tblgen %s | grep {[(set VR128:$dst, (int_x86_sse2_add_pd VR128:$src1, VR128:$src2))]} | count 1
+// RUN: tblgen %s | grep {[(set VR128:$dst, (int_x86_sse2_add_ps VR128:$src1, VR128:$src2))]} | count 2
+
+class ValueType<int size, int value> {
+  int Size = size;
+  int Value = value;
+}
+
+def f32  : ValueType<32, 1>;   //  2 x i64 vector value
+
+class Intrinsic<string name> {
+  string Name = name;
+}
+
+class Inst<bits<8> opcode, dag oopnds, dag iopnds, string asmstr, 
+           list<dag> pattern> {
+  bits<8> Opcode = opcode;
+  dag OutOperands = oopnds;
+  dag InOperands = iopnds;
+  string AssemblyString = asmstr;
+  list<dag> Pattern = pattern;
+}
+
+def ops;
+def outs;
+def ins;
+
+def set;
+
+// Define registers
+class Register<string n> {
+  string Name = n;
+}
+
+class RegisterClass<list<ValueType> regTypes, list<Register> regList> {
+  list<ValueType> RegTypes = regTypes;
+  list<Register> MemberList = regList;
+}
+
+def XMM0: Register<"xmm0">;
+def XMM1: Register<"xmm1">;
+def XMM2: Register<"xmm2">;
+def XMM3: Register<"xmm3">;
+def XMM4: Register<"xmm4">;
+def XMM5: Register<"xmm5">;
+def XMM6: Register<"xmm6">;
+def XMM7: Register<"xmm7">;
+def XMM8:  Register<"xmm8">;
+def XMM9:  Register<"xmm9">;
+def XMM10: Register<"xmm10">;
+def XMM11: Register<"xmm11">;
+def XMM12: Register<"xmm12">;
+def XMM13: Register<"xmm13">;
+def XMM14: Register<"xmm14">;
+def XMM15: Register<"xmm15">;
+
+def FR32 : RegisterClass<[f32],
+                         [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+                          XMM8, XMM9, XMM10, XMM11,
+                          XMM12, XMM13, XMM14, XMM15]>;
+
+class SDNode {}
+def not : SDNode;
+
+multiclass scalar<bits<8> opcode, string asmstr = "", list<list<dag>> patterns = []> {
+  def SSrr : Inst<opcode, (outs FR32:$dst), (ins FR32:$src),
+                  !strconcat(asmstr, "\t$dst, $src"),
+                  !if(!null(patterns),[]<dag>,patterns[0])>;
+  def SSrm : Inst<opcode, (outs FR32:$dst), (ins FR32:$src),
+                  !strconcat(asmstr, "\t$dst, $src"),
+                  !if(!null(patterns),[]<dag>,!if(!null(!cdr(patterns)),patterns[0],patterns[1]))>;
+}
+
+multiclass vscalar<bits<8> opcode, string asmstr = "", list<list<dag>> patterns = []> {
+  def V#NAME#SSrr : Inst<opcode, (outs FR32:$dst), (ins FR32:$src),
+                  !strconcat(asmstr, "\t$dst, $src"),
+                  !if(!null(patterns),[]<dag>,patterns[0])>;
+  def V#NAME#SSrm : Inst<opcode, (outs FR32:$dst), (ins FR32:$src),
+                  !strconcat(asmstr, "\t$dst, $src"),
+                  !if(!null(patterns),[]<dag>,!if(!null(!cdr(patterns)),patterns[0],patterns[1]))>;
+}
+
+multiclass myscalar<bits<8> opcode, string asmstr = "", list<list<dag>> patterns = []> :
+  scalar<opcode, asmstr, patterns>,
+  vscalar<opcode, asmstr, patterns>;
+
+defm NOT : myscalar<0x10, "not", [[], [(set FR32:$dst, (f32 (not FR32:$src)))]]>;

Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=73078&r1=73077&r2=73078&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Mon Jun  8 15:23:18 2009
@@ -2007,9 +2007,28 @@
       Pattern = new TreePattern(Patterns[i], Tree, true, *this);
     else {
       std::vector<Init*> Values;
-      for (unsigned j = 0, ee = Tree->getNumArgs(); j != ee; ++j)
+      RecTy *ListTy = 0;
+      for (unsigned j = 0, ee = Tree->getNumArgs(); j != ee; ++j) {
         Values.push_back(Tree->getArg(j));
-      ListInit *LI = new ListInit(Values);
+        TypedInit *TArg = dynamic_cast<TypedInit*>(Tree->getArg(j));
+        if (TArg == 0) {
+          cerr << "In dag: " << Tree->getAsString();
+          cerr << " --  Untyped argument in pattern\n";
+          assert(0 && "Untyped argument in pattern");
+        }
+        if (ListTy != 0) {
+          ListTy = resolveTypes(ListTy, TArg->getType());
+          if (ListTy == 0) {
+            cerr << "In dag: " << Tree->getAsString();
+            cerr << " --  Incompatible types in pattern arguments\n";
+            assert(0 && "Incompatible types in pattern arguments");
+          }
+        }
+        else {
+          ListTy - TArg->getType();
+        }
+      }
+      ListInit *LI = new ListInit(Values, new ListRecTy(ListTy));
       Pattern = new TreePattern(Patterns[i], LI, true, *this);
     }
 

Modified: llvm/trunk/utils/TableGen/Record.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.cpp?rev=73078&r1=73077&r2=73078&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/Record.cpp (original)
+++ llvm/trunk/utils/TableGen/Record.cpp Mon Jun  8 15:23:18 2009
@@ -191,7 +191,12 @@
     else
       return 0;
 
-  return new ListInit(Elements);
+  ListRecTy *LType = dynamic_cast<ListRecTy*>(LI->getType());
+  if (LType == 0) {
+    return 0;
+  }
+
+  return new ListInit(Elements, new ListRecTy(Ty));
 }
 
 Init *ListRecTy::convertValue(TypedInit *TI) {
@@ -272,6 +277,57 @@
 }
 
 
+/// resolveTypes - Find a common type that T1 and T2 convert to.  
+/// Return 0 if no such type exists.
+///
+RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
+  if (!T1->typeIsConvertibleTo(T2)) {
+    if (!T2->typeIsConvertibleTo(T1)) {
+      // If one is a Record type, check superclasses
+      RecordRecTy *RecTy1 = dynamic_cast<RecordRecTy*>(T1);
+      if (RecTy1) {
+        // See if T2 inherits from a type T1 also inherits from
+        const std::vector<Record *> &T1SuperClasses = RecTy1->getRecord()->getSuperClasses();
+        for(std::vector<Record *>::const_iterator i = T1SuperClasses.begin(),
+              iend = T1SuperClasses.end();
+            i != iend;
+            ++i) {
+          RecordRecTy *SuperRecTy1 = new RecordRecTy(*i);
+          RecTy *NewType1 = resolveTypes(SuperRecTy1, T2);
+          if (NewType1 != 0) {
+            if (NewType1 != SuperRecTy1) {
+              delete SuperRecTy1;
+            }
+            return NewType1;
+          }
+        }
+      }
+      RecordRecTy *RecTy2 = dynamic_cast<RecordRecTy*>(T2);
+      if (RecTy2) {
+        // See if T1 inherits from a type T2 also inherits from
+        const std::vector<Record *> &T2SuperClasses = RecTy2->getRecord()->getSuperClasses();
+        for(std::vector<Record *>::const_iterator i = T2SuperClasses.begin(),
+              iend = T2SuperClasses.end();
+            i != iend;
+            ++i) {
+          RecordRecTy *SuperRecTy2 = new RecordRecTy(*i);
+          RecTy *NewType2 = resolveTypes(T1, SuperRecTy2);
+          if (NewType2 != 0) {
+            if (NewType2 != SuperRecTy2) {
+              delete SuperRecTy2;
+            }
+            return NewType2;
+          }
+        }
+      }
+      return 0;
+    }
+    return T2;
+  }
+  return T1;
+}
+
+
 //===----------------------------------------------------------------------===//
 //    Initializer implementations
 //===----------------------------------------------------------------------===//
@@ -400,7 +456,7 @@
       return 0;
     Vals.push_back(getElement(Elements[i]));
   }
-  return new ListInit(Vals);
+  return new ListInit(Vals, getType());
 }
 
 Record *ListInit::getElementAsRecord(unsigned i) const {
@@ -428,10 +484,20 @@
   }
 
   if (Changed)
-    return new ListInit(Resolved);
+    return new ListInit(Resolved, getType());
   return this;
 }
 
+Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV,
+                                           unsigned Elt) {
+  if (Elt >= getSize())
+    return 0;  // Out of range reference.
+  Init *E = getElement(Elt);
+  if (!dynamic_cast<UnsetInit*>(E))  // If the element is set
+    return E;                        // Replace the VarListElementInit with it.
+  return 0;
+}
+
 std::string ListInit::getAsString() const {
   std::string Result = "[";
   for (unsigned i = 0, e = Values.size(); i != e; ++i) {
@@ -540,7 +606,7 @@
         assert(0 && "Empty list in cdr");
         return 0;
       }
-      ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end());
+      ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end(), LHSl->getType());
       return Result;
     }
     break;
@@ -555,6 +621,16 @@
         return new IntInit(0);
       }
     }
+    StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+    if (LHSs) {
+      if (LHSs->getValue().empty()) {
+        return new IntInit(1);
+      }
+      else {
+        return new IntInit(0);
+      }
+    }
+    
     break;
   }
   }
@@ -667,8 +743,8 @@
       if (Record *D = Records.getDef(Name))
         return new DefInit(D);
 
-      cerr << "Variable not defined: '" + Name + "'\n";
-      assert(0 && "Variable not found");
+      cerr << "Variable not defined in !nameconcat: '" + Name + "'\n";
+      assert(0 && "Variable not found in !nameconcat");
       return 0;
     }
     break;
@@ -881,7 +957,7 @@
           delete NewOp;
         }
       }
-      return new ListInit(NewList);
+      return new ListInit(NewList, MHSl->getType());
     }
   }
   return 0;
@@ -1027,7 +1103,7 @@
   ListInits.reserve(Elements.size());
   for (unsigned i = 0, e = Elements.size(); i != e; ++i)
     ListInits.push_back(new VarListElementInit(this, Elements[i]));
-  return new ListInit(ListInits);
+  return new ListInit(ListInits, T);
 }
 
 

Modified: llvm/trunk/utils/TableGen/Record.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.h?rev=73078&r1=73077&r2=73078&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/Record.h (original)
+++ llvm/trunk/utils/TableGen/Record.h Mon Jun  8 15:23:18 2009
@@ -442,7 +442,10 @@
   virtual bool baseClassOf(const RecordRecTy *RHS) const;
 };
 
-
+/// resolveTypes - Find a common type that T1 and T2 convert to.  
+/// Return 0 if no such type exists.
+///
+RecTy *resolveTypes(RecTy *T1, RecTy *T2);
 
 //===----------------------------------------------------------------------===//
 //  Initializer Classes
@@ -618,10 +621,10 @@
 
 /// IntInit - 7 - Represent an initalization by a literal integer value.
 ///
-class IntInit : public Init {
+class IntInit : public TypedInit {
   int64_t Value;
 public:
-  explicit IntInit(int64_t V) : Value(V) {}
+  explicit IntInit(int64_t V) : TypedInit(new IntRecTy), Value(V) {}
 
   int64_t getValue() const { return Value; }
 
@@ -631,6 +634,25 @@
   virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
 
   virtual std::string getAsString() const;
+
+  /// resolveBitReference - This method is used to implement
+  /// VarBitInit::resolveReferences.  If the bit is able to be resolved, we
+  /// simply return the resolved value, otherwise we return null.
+  ///
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit) {
+    assert(0 && "Illegal bit reference off int");
+    return 0;
+  }
+
+  /// resolveListElementReference - This method is used to implement
+  /// VarListElementInit::resolveReferences.  If the list element is resolvable
+  /// now, we return the resolved value, otherwise we return null.
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt) {
+    assert(0 && "Illegal element reference off int");
+    return 0;
+  }
 };
 
 
@@ -688,17 +710,18 @@
 
 /// ListInit - [AL, AH, CL] - Represent a list of defs
 ///
-class ListInit : public Init {
+class ListInit : public TypedInit {
   std::vector<Init*> Values;
 public:
   typedef std::vector<Init*>::iterator       iterator;
   typedef std::vector<Init*>::const_iterator const_iterator;
 
-  explicit ListInit(std::vector<Init*> &Vs) {
+  explicit ListInit(std::vector<Init*> &Vs, RecTy *EltTy)
+    : TypedInit(new ListRecTy(EltTy)) {
     Values.swap(Vs);
   }
-  explicit ListInit(iterator Start, iterator End)
-    : Values(Start, End) {}
+  explicit ListInit(iterator Start, iterator End, RecTy *EltTy)
+      : TypedInit(new ListRecTy(EltTy)), Values(Start, End) {}
 
   unsigned getSize() const { return Values.size(); }
   Init *getElement(unsigned i) const {
@@ -730,6 +753,22 @@
 
   inline size_t         size () const { return Values.size();  }
   inline bool           empty() const { return Values.empty(); }
+
+  /// resolveBitReference - This method is used to implement
+  /// VarBitInit::resolveReferences.  If the bit is able to be resolved, we
+  /// simply return the resolved value, otherwise we return null.
+  ///
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit) {
+    assert(0 && "Illegal bit reference off list");
+    return 0;
+  }
+
+  /// resolveListElementReference - This method is used to implement
+  /// VarListElementInit::resolveReferences.  If the list element is resolvable
+  /// now, we return the resolved value, otherwise we return null.
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt);
 };
 
 

Modified: llvm/trunk/utils/TableGen/TGParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.cpp?rev=73078&r1=73077&r2=73078&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGParser.cpp (original)
+++ llvm/trunk/utils/TableGen/TGParser.cpp Mon Jun  8 15:23:18 2009
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include <algorithm>
+#include <sstream>
 
 #include "TGParser.h"
 #include "Record.h"
@@ -396,7 +397,7 @@
     return Result;
   }
   
-  Result.TemplateArgs = ParseValueList(CurRec);
+  Result.TemplateArgs = ParseValueList(CurRec, Result.Rec);
   if (Result.TemplateArgs.empty()) {
     Result.Rec = 0;   // Error parsing value list.
     return Result;
@@ -438,7 +439,7 @@
     return Result;
   }
 
-  Result.TemplateArgs = ParseValueList(&CurMC->Rec);
+  Result.TemplateArgs = ParseValueList(&CurMC->Rec, &Result.MC->Rec);
   if (Result.TemplateArgs.empty()) {
     Result.MC = 0;   // Error parsing value list.
     return Result;
@@ -728,21 +729,28 @@
         || Code == UnOpInit::CDR
         || Code == UnOpInit::LNULL) {
       ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
+      StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
       TypedInit *LHSt = dynamic_cast<TypedInit*>(LHS);
-      if (LHSl == 0 && LHSt == 0) {
-        TokError("expected list type argument in unary operator");
+      if (LHSl == 0 && LHSs == 0 && LHSt == 0) {
+        TokError("expected list or string type argument in unary operator");
         return 0;
       }
       if (LHSt) {
         ListRecTy *LType = dynamic_cast<ListRecTy*>(LHSt->getType());
-        if (LType == 0) {
-          TokError("expected list type argumnet in unary operator");
+        StringRecTy *SType = dynamic_cast<StringRecTy*>(LHSt->getType());
+        if (LType == 0 && SType == 0) {
+          TokError("expected list or string type argumnet in unary operator");
           return 0;
         }
       }
 
       if (Code == UnOpInit::CAR
           || Code == UnOpInit::CDR) {
+        if (LHSl == 0 && LHSt == 0) {
+          TokError("expected list type argumnet in unary operator");
+          return 0;
+        }
+        
         if (LHSl && LHSl->getSize() == 0) {
           TokError("empty list argument in unary operator");
           return 0;
@@ -1017,7 +1025,7 @@
 ///   SimpleValue ::= SRLTOK '(' Value ',' Value ')'
 ///   SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
 ///
-Init *TGParser::ParseSimpleValue(Record *CurRec) {
+Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
   Init *R = 0;
   switch (Lex.getCode()) {
   default: TokError("Unknown token when parsing a value"); break;
@@ -1049,15 +1057,7 @@
       TokError("expected non-empty value list");
       return 0;
     }
-    std::vector<Init*> ValueList = ParseValueList(CurRec);
-    if (ValueList.empty()) return 0;
-    
-    if (Lex.getCode() != tgtok::greater) {
-      TokError("expected '>' at end of value list");
-      return 0;
-    }
-    Lex.Lex();  // eat the '>'
-    
+
     // This is a CLASS<initvalslist> expression.  This is supposed to synthesize
     // a new anonymous definition, deriving from CLASS<initvalslist> with no
     // body.
@@ -1066,6 +1066,15 @@
       Error(NameLoc, "Expected a class name, got '" + Name + "'");
       return 0;
     }
+
+    std::vector<Init*> ValueList = ParseValueList(CurRec, Class);
+    if (ValueList.empty()) return 0;
+    
+    if (Lex.getCode() != tgtok::greater) {
+      TokError("expected '>' at end of value list");
+      return 0;
+    }
+    Lex.Lex();  // eat the '>'
     
     // Create the new record, set it as CurRec temporarily.
     static unsigned AnonCounter = 0;
@@ -1114,8 +1123,22 @@
     Lex.Lex(); // eat the '['
     std::vector<Init*> Vals;
     
+    RecTy *DeducedEltTy = 0;
+    ListRecTy *GivenListTy = 0;
+    
+    if (ItemType != 0) {
+      ListRecTy *ListType = dynamic_cast<ListRecTy*>(ItemType);
+      if (ListType == 0) {
+        std::stringstream s;
+        s << "Type mismatch for list, expected list type, got " 
+          << ItemType->getAsString();
+        TokError(s.str());
+      }
+      GivenListTy = ListType;
+    }    
+
     if (Lex.getCode() != tgtok::r_square) {
-      Vals = ParseValueList(CurRec);
+      Vals = ParseValueList(CurRec, 0, GivenListTy ? GivenListTy->getElementType() : 0);
       if (Vals.empty()) return 0;
     }
     if (Lex.getCode() != tgtok::r_square) {
@@ -1123,7 +1146,77 @@
       return 0;
     }
     Lex.Lex();  // eat the ']'
-    return new ListInit(Vals);
+
+    RecTy *GivenEltTy = 0;
+    if (Lex.getCode() == tgtok::less) {
+      // Optional list element type
+      Lex.Lex();  // eat the '<'
+
+      GivenEltTy = ParseType();
+      if (GivenEltTy == 0) {
+        // Couldn't parse element type
+        return 0;
+      }
+
+      if (Lex.getCode() != tgtok::greater) {
+        TokError("expected '>' at end of list element type");
+        return 0;
+      }
+      Lex.Lex();  // eat the '>'
+    }
+
+    // Check elements
+    RecTy *EltTy = 0;
+    for (std::vector<Init *>::iterator i = Vals.begin(), ie = Vals.end();
+         i != ie;
+         ++i) {
+      TypedInit *TArg = dynamic_cast<TypedInit*>(*i);
+      if (TArg == 0) {
+        TokError("Untyped list element");
+        return 0;
+      }
+      if (EltTy != 0) {
+        EltTy = resolveTypes(EltTy, TArg->getType());
+        if (EltTy == 0) {
+          TokError("Incompatible types in list elements");
+          return 0;
+        }
+      }
+      else {
+        EltTy = TArg->getType();
+      }
+    }
+
+    if (GivenEltTy != 0) {
+      if (EltTy != 0) {
+        // Verify consistency
+        if (!EltTy->typeIsConvertibleTo(GivenEltTy)) {
+          TokError("Incompatible types in list elements");
+          return 0;
+        }
+      }
+      EltTy = GivenEltTy;
+    }
+
+    if (EltTy == 0) {
+      if (ItemType == 0) {
+        TokError("No type for list");
+        return 0;
+      }
+      DeducedEltTy = GivenListTy->getElementType();
+   }
+    else {
+      // Make sure the deduced type is compatible with the given type
+      if (GivenListTy) {
+        if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) {
+          TokError("Element type mismatch for list");
+          return 0;
+        }
+      }
+      DeducedEltTy = EltTy;
+    }
+    
+    return new ListInit(Vals, DeducedEltTy);
   }
   case tgtok::l_paren: {         // Value ::= '(' IDValue DagArgList ')'
     Lex.Lex();   // eat the '('
@@ -1200,8 +1293,8 @@
 ///   ValueSuffix ::= '[' BitList ']'
 ///   ValueSuffix ::= '.' ID
 ///
-Init *TGParser::ParseValue(Record *CurRec) {
-  Init *Result = ParseSimpleValue(CurRec);
+Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType) {
+  Init *Result = ParseSimpleValue(CurRec, ItemType);
   if (Result == 0) return 0;
   
   // Parse the suffixes now if present.
@@ -1306,15 +1399,31 @@
 ///
 ///   ValueList ::= Value (',' Value)
 ///
-std::vector<Init*> TGParser::ParseValueList(Record *CurRec) {
+std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, RecTy *EltTy) {
   std::vector<Init*> Result;
-  Result.push_back(ParseValue(CurRec));
+  RecTy *ItemType = EltTy;
+  int ArgN = 0;
+  if (ArgsRec != 0 && EltTy == 0) {
+    const std::vector<std::string> &TArgs = ArgsRec->getTemplateArgs();
+    const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
+    assert(RV && "Template argument record not found??");
+    ItemType = RV->getType();
+    ++ArgN;
+  }
+  Result.push_back(ParseValue(CurRec, ItemType));
   if (Result.back() == 0) return std::vector<Init*>();
   
   while (Lex.getCode() == tgtok::comma) {
     Lex.Lex();  // Eat the comma
     
-    Result.push_back(ParseValue(CurRec));
+    if (ArgsRec != 0 && EltTy == 0) {
+      const std::vector<std::string> &TArgs = ArgsRec->getTemplateArgs();
+      const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
+      assert(RV && "Template argument record not found??");
+      ItemType = RV->getType();
+      ++ArgN;
+    }
+    Result.push_back(ParseValue(CurRec, ItemType));
     if (Result.back() == 0) return std::vector<Init*>();
   }
   
@@ -1369,7 +1478,7 @@
   if (Lex.getCode() == tgtok::equal) {
     Lex.Lex();
     TGLoc ValLoc = Lex.getLoc();
-    Init *Val = ParseValue(CurRec);
+    Init *Val = ParseValue(CurRec, Type);
     if (Val == 0 ||
         SetValue(CurRec, ValLoc, DeclName, std::vector<unsigned>(), Val))
       return "";
@@ -1447,7 +1556,13 @@
     return TokError("expected '=' in let expression");
   Lex.Lex();  // eat the '='.
   
-  Init *Val = ParseValue(CurRec);
+  RecordVal *Field = CurRec->getValue(FieldName);
+  if (Field == 0)
+    return TokError("Value '" + FieldName + "' unknown!");
+
+  RecTy *Type = Field->getType();
+  
+  Init *Val = ParseValue(CurRec, Type);
   if (Val == 0) return true;
   
   if (Lex.getCode() != tgtok::semi)

Modified: llvm/trunk/utils/TableGen/TGParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.h?rev=73078&r1=73077&r2=73078&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGParser.h (original)
+++ llvm/trunk/utils/TableGen/TGParser.h Mon Jun  8 15:23:18 2009
@@ -93,9 +93,9 @@
 
   Init *ParseIDValue(Record *CurRec);
   Init *ParseIDValue(Record *CurRec, const std::string &Name, TGLoc NameLoc);
-  Init *ParseSimpleValue(Record *CurRec);
-  Init *ParseValue(Record *CurRec);
-  std::vector<Init*> ParseValueList(Record *CurRec);
+  Init *ParseSimpleValue(Record *CurRec, RecTy *ItemType = 0);
+  Init *ParseValue(Record *CurRec, RecTy *ItemType = 0);
+  std::vector<Init*> ParseValueList(Record *CurRec, Record *ArgsRec = 0, RecTy *EltTy = 0);
   std::vector<std::pair<llvm::Init*, std::string> > ParseDagArgList(Record *);
   bool ParseOptionalRangeList(std::vector<unsigned> &Ranges);
   bool ParseOptionalBitList(std::vector<unsigned> &Ranges);





More information about the llvm-commits mailing list