[llvm-commits] [llvm] r71803 - in /llvm/trunk: docs/TableGenFundamentals.html test/TableGen/TargetInstrSpec.td test/TableGen/foreach.td utils/TableGen/Record.cpp utils/TableGen/Record.h utils/TableGen/TGLexer.cpp utils/TableGen/TGLexer.h utils/TableGen/TGParser.cpp

David Greene greened at obbligato.org
Thu May 14 15:23:51 PDT 2009


Author: greened
Date: Thu May 14 17:23:47 2009
New Revision: 71803

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

Implement a !foreach operator analogous to GNU make's $(foreach).
Use it on dags and lists like this:

class decls {
  string name;
}

def Decls : decls;

class B<list<string> names> : A<!foreach(Decls.name, names, !strconcat(Decls.name, ", Sr."))>;

Added:
    llvm/trunk/test/TableGen/TargetInstrSpec.td
    llvm/trunk/test/TableGen/foreach.td
Modified:
    llvm/trunk/docs/TableGenFundamentals.html
    llvm/trunk/utils/TableGen/Record.cpp
    llvm/trunk/utils/TableGen/Record.h
    llvm/trunk/utils/TableGen/TGLexer.cpp
    llvm/trunk/utils/TableGen/TGLexer.h
    llvm/trunk/utils/TableGen/TGParser.cpp

Modified: llvm/trunk/docs/TableGenFundamentals.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TableGenFundamentals.html?rev=71803&r1=71802&r2=71803&view=diff

==============================================================================
--- llvm/trunk/docs/TableGenFundamentals.html (original)
+++ llvm/trunk/docs/TableGenFundamentals.html Thu May 14 17:23:47 2009
@@ -407,6 +407,10 @@
 <dt><tt>!subst(a, b, c)</tt></dt>
   <dd>If 'a' and 'b' are of string type or are symbol references, substitute 
 'b' for 'a' in 'c.'  This operation is analogous to $(subst) in GNU make.</dd>
+<dt><tt>!foreach(a, b, c)</tt></dt>
+  <dd>For each member 'b' of dag or list 'a' apply operator 'c.'  'b' is a 
+dummy variable that should be declared as a member variable of an instantiated 
+class.  This operation is analogous to $(foreach) in GNU make.</dd>
 </dl>
 
 <p>Note that all of the values have rules specifying how they convert to values

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

==============================================================================
--- llvm/trunk/test/TableGen/TargetInstrSpec.td (added)
+++ llvm/trunk/test/TableGen/TargetInstrSpec.td Thu May 14 17:23:47 2009
@@ -0,0 +1,97 @@
+// 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 v2i64  : ValueType<128, 22>;   //  2 x i64 vector value
+def v2f64  : ValueType<128, 28>;   //  2 x f64 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 VR128 : RegisterClass<[v2i64, v2f64],
+                          [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+                           XMM8, XMM9, XMM10, XMM11,
+                           XMM12, XMM13, XMM14, XMM15]>;
+
+// Dummy for subst
+def REGCLASS : RegisterClass<[], []>;
+
+class decls {
+  // Dummy for foreach
+  dag pattern;
+  int operand;
+}
+
+def Decls : decls;
+
+// Define intrinsics
+def int_x86_sse2_add_ps : Intrinsic<"addps">;
+def int_x86_sse2_add_pd : Intrinsic<"addpd">;
+def INTRINSIC : Intrinsic<"Dummy">;
+
+multiclass arith<bits<8> opcode, string asmstr, string intr, list<dag> patterns> {
+  def PS : Inst<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
+                 !strconcat(asmstr, "\t$dst, $src1, $src2"),
+                 !foreach(Decls.pattern, patterns, 
+		          !foreach(Decls.operand, Decls.pattern, 
+			           !subst(INTRINSIC, !cast<Intrinsic>(!subst("SUFFIX", "_ps", intr)), 
+				          !subst(REGCLASS, VR128, Decls.operand))))>;
+
+  def PD : Inst<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
+                 !strconcat(asmstr, "\t$dst, $src1, $src2"),
+                 !foreach(Decls.pattern, patterns, 
+		          !foreach(Decls.operand, Decls.pattern, 
+			           !subst(INTRINSIC, !cast<Intrinsic>(!subst("SUFFIX", "_pd", intr)), 
+				          !subst(REGCLASS, VR128, Decls.operand))))>;
+}
+
+defm ADD : arith<0x58, "add", "int_x86_sse2_addSUFFIX",
+                 [(set REGCLASS:$dst, (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))]>;
+

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

==============================================================================
--- llvm/trunk/test/TableGen/foreach.td (added)
+++ llvm/trunk/test/TableGen/foreach.td Thu May 14 17:23:47 2009
@@ -0,0 +1,31 @@
+// RUN: tblgen %s | grep {Jr} | count 2
+// RUN: tblgen %s | grep {Sr} | count 2
+// RUN: tblgen %s | not grep {NAME}
+
+// Variables for foreach
+class decls {
+  string name;
+}
+
+def Decls : decls;
+
+class A<list<string> names> {
+  list<string> Names = names;
+}
+
+class B<list<string> names> : A<!foreach(Decls.name, names, !strconcat(Decls.name, ", Sr."))>;
+
+class C<list<string> names> : A<!foreach(Decls.name, names, !strconcat(Decls.name, ", Jr."))>;
+
+class D<list<string> names> : A<!foreach(Decls.name, names, !subst("NAME", "John Smith", Decls.name))>;
+
+class Names {
+  list<string> values = ["Ken Griffey", "Seymour Cray"];
+}
+
+def People : Names;
+
+def Seniors : B<People.values>;
+def Juniors : C<People.values>;
+def Smiths : D<["NAME", "Jane Smith"]>;
+def Unprocessed : D<People.values>;

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

==============================================================================
--- llvm/trunk/utils/TableGen/Record.cpp (original)
+++ llvm/trunk/utils/TableGen/Record.cpp Thu May 14 17:23:47 2009
@@ -678,6 +678,144 @@
   return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
 }
 
+static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
+                           Record *CurRec, MultiClass *CurMultiClass);
+
+static Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg,
+                               RecTy *Type, Record *CurRec,
+                               MultiClass *CurMultiClass) {
+  std::vector<Init *> NewOperands;
+
+  TypedInit *TArg = dynamic_cast<TypedInit*>(Arg);
+
+  // If this is a dag, recurse
+  if (TArg && TArg->getType()->getAsString() == "dag") {
+    Init *Result = ForeachHelper(LHS, Arg, RHSo, Type,
+                                 CurRec, CurMultiClass);
+    if (Result != 0) {
+      return Result;
+    }
+    else {
+      return 0;
+    }
+  }
+
+  for (int i = 0; i < RHSo->getNumOperands(); ++i) {
+    OpInit *RHSoo = dynamic_cast<OpInit*>(RHSo->getOperand(i));
+
+    if (RHSoo) {
+      Init *Result = EvaluateOperation(RHSoo, LHS, Arg,
+                                       Type, CurRec, CurMultiClass);
+      if (Result != 0) {
+        NewOperands.push_back(Result);
+      }
+      else {
+        NewOperands.push_back(Arg);
+      }
+    }
+    else if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
+      NewOperands.push_back(Arg);
+    }
+    else {
+      NewOperands.push_back(RHSo->getOperand(i));
+    }
+  }
+
+  // Now run the operator and use its result as the new leaf
+  OpInit *NewOp = RHSo->clone(NewOperands);
+  Init *NewVal = NewOp->Fold(CurRec, CurMultiClass);
+  if (NewVal != NewOp) {
+    delete NewOp;
+    return NewVal;
+  }
+  return 0;
+}
+
+static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
+                           Record *CurRec, MultiClass *CurMultiClass) {
+  DagInit *MHSd = dynamic_cast<DagInit*>(MHS);
+  ListInit *MHSl = dynamic_cast<ListInit*>(MHS);
+
+  DagRecTy *DagType = dynamic_cast<DagRecTy*>(Type);
+  ListRecTy *ListType = dynamic_cast<ListRecTy*>(Type);
+
+  OpInit *RHSo = dynamic_cast<OpInit*>(RHS);
+
+  if (!RHSo) {
+    cerr << "!foreach requires an operator\n";
+    assert(0 && "No operator for !foreach");
+  }
+
+  TypedInit *LHSt = dynamic_cast<TypedInit*>(LHS);
+
+  if (!LHSt) {
+    cerr << "!foreach requires typed variable\n";
+    assert(0 && "No typed variable for !foreach");
+  }
+
+  if (MHSd && DagType || MHSl && ListType) {
+    if (MHSd) {
+      Init *Val = MHSd->getOperator();
+      Init *Result = EvaluateOperation(RHSo, LHS, Val,
+                                       Type, CurRec, CurMultiClass);
+      if (Result != 0) {
+        Val = Result;
+      }
+
+      std::vector<std::pair<Init *, std::string> > args;
+      for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) {
+        Init *Arg;
+        std::string ArgName;
+        Arg = MHSd->getArg(i);
+        ArgName = MHSd->getArgName(i);
+
+        // Process args
+        Init *Result = EvaluateOperation(RHSo, LHS, Arg, Type,
+                                         CurRec, CurMultiClass);
+        if (Result != 0) {
+          Arg = Result;
+        }
+
+        // TODO: Process arg names
+        args.push_back(std::make_pair(Arg, ArgName));
+      }
+
+      return new DagInit(Val, "", args);
+    }
+    if (MHSl) {
+      std::vector<Init *> NewOperands;
+      std::vector<Init *> NewList(MHSl->begin(), MHSl->end());
+
+      for (ListInit::iterator li = NewList.begin(),
+             liend = NewList.end();
+           li != liend;
+           ++li) {
+        Init *Item = *li;
+        NewOperands.clear();
+        for(int i = 0; i < RHSo->getNumOperands(); ++i) {
+          // First, replace the foreach variable with the list item
+          if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
+            NewOperands.push_back(Item);
+          }
+          else {
+            NewOperands.push_back(RHSo->getOperand(i));
+          }
+        }
+
+        // Now run the operator and use its result as the new list item
+        OpInit *NewOp = RHSo->clone(NewOperands);
+        Init *NewItem = NewOp->Fold(CurRec, CurMultiClass);
+        if (NewItem != NewOp) {
+          *li = NewItem;
+          delete NewOp;
+        }
+      }
+      return new ListInit(NewList);
+    }
+  }
+  return 0;
+}
+
 Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
   switch (getOpcode()) {
   default: assert(0 && "Unknown binop");
@@ -729,144 +867,10 @@
   }  
 
   case FOREACH: {
-    DagInit *MHSd = dynamic_cast<DagInit*>(MHS);
-    ListInit *MHSl = dynamic_cast<ListInit*>(MHS);
-
-    DagRecTy *DagType = dynamic_cast<DagRecTy*>(getType());
-    ListRecTy *ListType = dynamic_cast<ListRecTy*>(getType());
-
-    OpInit *RHSo = dynamic_cast<OpInit*>(RHS);
-
-    if (!RHSo) {
-      cerr << "!foreach requires an operator\n";
-      assert(0 && "No operator for !foreach");
-    }
-
-    TypedInit *LHSt = dynamic_cast<TypedInit*>(LHS);
-
-    if (!LHSt) {
-      cerr << "!foreach requires typed variable\n";
-      assert(0 && "No typed variable for !foreach");
-    }
-
-    if (MHSd && DagType || MHSl && ListType) {
-      std::vector<Init *> NewOperands;
-      if (MHSd) {
-        Init *Val = MHSd->getOperator();
-        TypedInit *TVal = dynamic_cast<TypedInit*>(Val);
-
-        if (TVal && TVal->getType()->typeIsConvertibleTo(LHSt->getType())) {
-          
-          // First, replace the foreach variable with the DAG leaf
-          for (int i = 0; i < RHSo->getNumOperands(); ++i) {
-            if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
-              NewOperands.push_back(Val);
-            }
-            else {
-              NewOperands.push_back(RHSo->getOperand(i));
-            }
-          }
-
-          // Now run the operator and use its result as the new leaf
-          OpInit *NewOp = RHSo->clone(NewOperands);
-          Val = NewOp->Fold(CurRec, CurMultiClass);
-          if (Val != NewOp) {
-            delete NewOp;
-          }
-        }
-
-        std::vector<std::pair<Init *, std::string> > args;
-        for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) {
-          Init *Arg;
-          std::string ArgName;
-          Arg = MHSd->getArg(i);
-          ArgName = MHSd->getArgName(i);
-
-          TypedInit *TArg = dynamic_cast<TypedInit*>(Arg);
-
-          if (TArg && TArg->getType()->typeIsConvertibleTo(LHSt->getType())) {
-            NewOperands.clear();
-
-            // First, replace the foreach variable with the DAG leaf
-            for (int i = 0; i < RHSo->getNumOperands(); ++i) {
-              if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
-                NewOperands.push_back(Arg);
-              }
-              else {
-                NewOperands.push_back(RHSo->getOperand(i));
-              }
-            }
-
-            // Now run the operator and use its result as the new leaf
-            OpInit *NewOp = RHSo->clone(NewOperands);
-            Arg = NewOp->Fold(CurRec, CurMultiClass);
-            if (Arg != NewOp) {
-              delete NewOp;
-            }
-          }
-         
-          if (LHSt->getType()->getAsString() == "string") {
-            NewOperands.clear();
-
-            // First, replace the foreach variable with the DAG leaf
-            for (int i = 0; i < RHSo->getNumOperands(); ++i) {
-              if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
-                NewOperands.push_back(new StringInit(ArgName));
-              }
-              else {
-                NewOperands.push_back(RHSo->getOperand(i));
-              }
-            }
-
-            // Now run the operator and use its result as the new leaf
-            OpInit *NewOp = RHSo->clone(NewOperands);
-            Init *ArgNameInit = NewOp->Fold(CurRec, CurMultiClass);
-            StringInit *SArgNameInit = dynamic_cast<StringInit*>(ArgNameInit);
-            if (SArgNameInit) {
-              ArgName = SArgNameInit->getValue();
-            }
-            if (ArgNameInit != NewOp) {
-              delete NewOp;
-            }
-            delete ArgNameInit;
-          }
-
-          args.push_back(std::make_pair(Arg, ArgName));
-        }
-
-        return new DagInit(Val, "", args);
-      }
-      if (MHSl) {
-        std::vector<Init *> NewList(MHSl->begin(), MHSl->end());
-
-        for (ListInit::iterator li = NewList.begin(),
-               liend = NewList.end();
-             li != liend;
-             ++li) {
-          Init *Item = *li;
-          TypedInit *TItem = dynamic_cast<TypedInit*>(Item);
-          if (TItem && TItem->getType()->typeIsConvertibleTo(LHSt->getType())) {
-            // First, replace the foreach variable with the list item
-            for (int i = 0; i < RHSo->getNumOperands(); ++i) {
-              if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
-                NewOperands.push_back(Item);
-              }
-              else {
-                NewOperands.push_back(RHSo->getOperand(i));
-              }
-            }
-
-            // Now run the operator and use its result as the new list item
-            OpInit *NewOp = RHSo->clone(NewOperands);
-            *li = NewOp->Fold(CurRec, CurMultiClass);
-            if (*li != NewOp) {
-              delete NewOp;
-            }
-          }
-        }
-          
-        return new ListInit(NewList);
-      }
+    Init *Result = ForeachHelper(LHS, MHS, RHS, getType(),
+                                 CurRec, CurMultiClass);
+    if (Result != 0) {
+      return Result;
     }
     break;
   }

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

==============================================================================
--- llvm/trunk/utils/TableGen/Record.h (original)
+++ llvm/trunk/utils/TableGen/Record.h Thu May 14 17:23:47 2009
@@ -517,6 +517,33 @@
   I.print(OS); return OS;
 }
 
+/// TypedInit - This is the common super-class of types that have a specific,
+/// explicit, type.
+///
+class TypedInit : public Init {
+  RecTy *Ty;
+public:
+  explicit TypedInit(RecTy *T) : Ty(T) {}
+
+  RecTy *getType() const { return Ty; }
+
+  virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
+  virtual Init *convertInitListSlice(const std::vector<unsigned> &Elements);
+
+  /// 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) = 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) = 0;
+};
+
 
 /// UnsetInit - ? - Represents an uninitialized value
 ///
@@ -609,10 +636,10 @@
 
 /// StringInit - "foo" - Represent an initialization by a string value.
 ///
-class StringInit : public Init {
+class StringInit : public TypedInit {
   std::string Value;
 public:
-  explicit StringInit(const std::string &V) : Value(V) {}
+  explicit StringInit(const std::string &V) : TypedInit(new StringRecTy), Value(V) {}
 
   const std::string &getValue() const { return Value; }
 
@@ -621,6 +648,25 @@
   }
 
   virtual std::string getAsString() const { return "\"" + Value + "\""; }
+
+  /// 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 string");
+    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 string");
+    return 0;
+  }
 };
 
 /// CodeInit - "[{...}]" - Represent a code fragment.
@@ -684,33 +730,6 @@
 };
 
 
-/// TypedInit - This is the common super-class of types that have a specific,
-/// explicit, type.
-///
-class TypedInit : public Init {
-  RecTy *Ty;
-public:
-  explicit TypedInit(RecTy *T) : Ty(T) {}
-
-  RecTy *getType() const { return Ty; }
-
-  virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
-  virtual Init *convertInitListSlice(const std::vector<unsigned> &Elements);
-
-  /// 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) = 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) = 0;
-};
-
 /// OpInit - Base class for operators
 ///
 class OpInit : public TypedInit {
@@ -957,10 +976,10 @@
 
 /// DefInit - AL - Represent a reference to a 'def' in the description
 ///
-class DefInit : public Init {
+class DefInit : public TypedInit {
   Record *Def;
 public:
-  explicit DefInit(Record *D) : Def(D) {}
+  explicit DefInit(Record *D) : TypedInit(new RecordRecTy(D)), Def(D) {}
 
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
@@ -974,6 +993,25 @@
   virtual Init *getFieldInit(Record &R, const std::string &FieldName) const;
 
   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 def");
+    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 def");
+    return 0;
+  }
 };
 
 
@@ -1008,7 +1046,7 @@
 /// to have at least one value then a (possibly empty) list of arguments.  Each
 /// argument can have a name associated with it.
 ///
-class DagInit : public Init {
+class DagInit : public TypedInit {
   Init *Val;
   std::string ValName;
   std::vector<Init*> Args;
@@ -1016,7 +1054,7 @@
 public:
   DagInit(Init *V, std::string VN, 
           const std::vector<std::pair<Init*, std::string> > &args)
-    : Val(V), ValName(VN) {
+    : TypedInit(new DagRecTy), Val(V), ValName(VN) {
     Args.reserve(args.size());
     ArgNames.reserve(args.size());
     for (unsigned i = 0, e = args.size(); i != e; ++i) {
@@ -1026,7 +1064,7 @@
   }
   DagInit(Init *V, std::string VN, const std::vector<Init*> &args, 
           const std::vector<std::string> &argNames)
-  : Val(V), ValName(VN), Args(args), ArgNames(argNames) {
+  : TypedInit(new DagRecTy), Val(V), ValName(VN), Args(args), ArgNames(argNames) {
   }
   
   virtual Init *convertInitializerTo(RecTy *Ty) {
@@ -1077,6 +1115,18 @@
   inline size_t              name_size () const { return ArgNames.size();  }
   inline bool                name_empty() const { return ArgNames.empty(); }
 
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit) {
+    assert(0 && "Illegal bit reference off dag");
+    return 0;
+  }
+  
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt) {
+    assert(0 && "Illegal element reference off dag");
+    return 0;
+  }
+  
 };
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/utils/TableGen/TGLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.cpp?rev=71803&r1=71802&r2=71803&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGLexer.cpp (original)
+++ llvm/trunk/utils/TableGen/TGLexer.cpp Thu May 14 17:23:47 2009
@@ -448,7 +448,7 @@
   if (Len == 9  && !memcmp(Start, "strconcat", 9))   return tgtok::XStrConcat;
   if (Len == 10 && !memcmp(Start, "nameconcat", 10)) return tgtok::XNameConcat;
   if (Len == 5 && !memcmp(Start, "subst", 5)) return tgtok::XSubst;
-//   if (Len == 7 && !memcmp(Start, "foreach", 7)) return tgtok::XForEach;
+  if (Len == 7 && !memcmp(Start, "foreach", 7)) return tgtok::XForEach;
   if (Len == 4 && !memcmp(Start, "cast", 4)) return tgtok::XCast;
 
   return ReturnError(Start-1, "Unknown operator");

Modified: llvm/trunk/utils/TableGen/TGLexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.h?rev=71803&r1=71802&r2=71803&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGLexer.h (original)
+++ llvm/trunk/utils/TableGen/TGLexer.h Thu May 14 17:23:47 2009
@@ -46,7 +46,7 @@
     
     // !keywords.
     XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, XSubst,
-    //XForEach,
+    XForEach,
 
     // Integer value.
     IntVal,

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

==============================================================================
--- llvm/trunk/utils/TableGen/TGParser.cpp (original)
+++ llvm/trunk/utils/TableGen/TGParser.cpp Thu May 14 17:23:47 2009
@@ -792,7 +792,7 @@
     return (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass);
   }
 
-//   case tgtok::XForEach:
+  case tgtok::XForEach:
   case tgtok::XSubst: {  // Value ::= !ternop '(' Value ',' Value ',' Value ')'
     TernOpInit::TernaryOp Code;
     RecTy *Type = 0;
@@ -802,9 +802,9 @@
     Lex.Lex();  // eat the operation
     switch (LexCode) {
     default: assert(0 && "Unhandled code!");
-      //case tgtok::XForEach:
-      //Code = TernOpInit::FOREACH;
-      //break;
+    case tgtok::XForEach:
+      Code = TernOpInit::FOREACH;
+      break;
     case tgtok::XSubst:
       Code = TernOpInit::SUBST;
       break;
@@ -844,15 +844,15 @@
 
     switch (LexCode) {
     default: assert(0 && "Unhandled code!");
-      //case tgtok::XForEach: {
-      //TypedInit *MHSt = dynamic_cast<TypedInit *>(MHS);
-      //if (MHSt == 0) {
-      //  TokError("could not get type for !foreach");
-      //  return 0;
-      //}
-      //Type = MHSt->getType();
-      //break;
-      //}
+    case tgtok::XForEach: {
+      TypedInit *MHSt = dynamic_cast<TypedInit *>(MHS);
+      if (MHSt == 0) {
+        TokError("could not get type for !foreach");
+        return 0;
+      }
+      Type = MHSt->getType();
+      break;
+    }
     case tgtok::XSubst: {
       TypedInit *RHSt = dynamic_cast<TypedInit *>(RHS);
       if (RHSt == 0) {
@@ -1079,7 +1079,7 @@
   case tgtok::XSHL:
   case tgtok::XStrConcat:
   case tgtok::XNameConcat:  // Value ::= !binop '(' Value ',' Value ')'
-    //  case tgtok::XForEach:
+  case tgtok::XForEach:
   case tgtok::XSubst: {  // Value ::= !ternop '(' Value ',' Value ',' Value ')'
     return ParseOperation(CurRec);
     break;





More information about the llvm-commits mailing list