[llvm-commits] [llvm] r71801 - in /llvm/trunk: docs/TableGenFundamentals.html test/TableGen/subst.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 14:54:43 PDT 2009


Author: greened
Date: Thu May 14 16:54:42 2009
New Revision: 71801

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

Implement a !subst operation simmilar to $(subst) in GNU make to do
def/var/string substitution on generic pattern templates.  For example:

def Type;
def v4f32 : Type;
def TYPE : Type;

class GenType<Type t> {
  let type = !(subst TYPE, v4f32, t);
}

def TheType : GenType<TYPE>;

Added:
    llvm/trunk/test/TableGen/subst.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=71801&r1=71800&r2=71801&view=diff

==============================================================================
--- llvm/trunk/docs/TableGenFundamentals.html (original)
+++ llvm/trunk/docs/TableGenFundamentals.html Thu May 14 16:54:42 2009
@@ -404,6 +404,9 @@
 aborts with an error. </dd>
 <dt><tt>!nameconcat<type>(a, b)</tt></dt>
   <dd>Shorthand for !cast<type>(!strconcat(a, b))</dd>
+<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>
 </dl>
 
 <p>Note that all of the values have rules specifying how they convert to values

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

==============================================================================
--- llvm/trunk/test/TableGen/subst.td (added)
+++ llvm/trunk/test/TableGen/subst.td Thu May 14 16:54:42 2009
@@ -0,0 +1,29 @@
+// RUN: tblgen %s | grep {Smith} | count 7
+// RUN: tblgen %s | grep {Johnson} | count 2
+// RUN: tblgen %s | grep {FIRST} | count 1
+// RUN: tblgen %s | grep {LAST} | count 1
+// RUN: tblgen %s | grep {TVAR} | count 2
+// RUN: tblgen %s | grep {Bogus} | count 1
+
+class Honorific<string t> {
+  string honorific = t;
+}
+
+def Mr : Honorific<"Mr.">;
+def Ms : Honorific<"Ms.">;
+def Mrs : Honorific<"Mrs.">;
+def TVAR : Honorific<"Bogus">;
+
+class Name<string n, Honorific t> {
+  string name = n;
+  Honorific honorific = t;
+}
+
+class AName<string name, Honorific honorific> : 
+  Name<!subst("FIRST", "John", !subst("LAST", "Smith", name)),
+       !subst(TVAR, Mr, honorific)>;
+
+def JohnSmith : AName<"FIRST LAST", TVAR>;
+def JaneSmith : AName<"Jane LAST", Ms>;
+def JohnSmithJones : AName<"FIRST LAST-Jones", Mr>;
+def JimmyJohnson : AName<"Jimmy Johnson", Mr>;

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

==============================================================================
--- llvm/trunk/utils/TableGen/Record.cpp (original)
+++ llvm/trunk/utils/TableGen/Record.cpp Thu May 14 16:54:42 2009
@@ -678,231 +678,222 @@
   return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
 }
 
-// Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
-//   switch (getOpcode()) {
-//   default: assert(0 && "Unknown binop");
-//   case SUBST: {
-//     DefInit *LHSd = dynamic_cast<DefInit*>(LHS);
-//     VarInit *LHSv = dynamic_cast<VarInit*>(LHS);
-//     StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
-
-//     DefInit *MHSd = dynamic_cast<DefInit*>(MHS);
-//     VarInit *MHSv = dynamic_cast<VarInit*>(MHS);
-//     StringInit *MHSs = dynamic_cast<StringInit*>(MHS);
-
-//     DagInit *RHSd = dynamic_cast<DagInit*>(RHS);
-//     ListInit *RHSl = dynamic_cast<ListInit*>(RHS);
-
-//     DagRecTy *DagType = dynamic_cast<DagRecTy*>(getType());
-//     ListRecTy *ListType = dynamic_cast<ListRecTy*>(getType());
-
-//     if ((DagType && RHSd || ListType && RHSl)
-//         && (LHSd && MHSd || LHSv && MHSv || LHSs && MHSs)) {
-//       if (RHSd) {
-//         Init *Val = RHSd->getOperator(); 
-//         if (Val->getAsString() == LHS->getAsString()) {
-//           Val = MHS;
-//         }
-//         std::vector<std::pair<Init *, std::string> > args;
-//         for (int i = 0; i < RHSd->getNumArgs(); ++i) {
-//           Init *Arg;
-//           std::string ArgName;
-//           Arg = RHSd->getArg(i);
-//           ArgName = RHSd->getArgName(i);
-//           if (Arg->getAsString() == LHS->getAsString()) {
-//             Arg = MHS;
-//           }
-//           if (ArgName == LHS->getAsString()) {
-//             ArgName = MHS->getAsString();
-//           }
-//           args.push_back(std::make_pair(Arg, ArgName));
-//         }
-
-//         return new DagInit(Val, args);
-//       }
-//       if (RHSl) {
-//         std::vector<Init *> NewList(RHSl->begin(), RHSl->end());
-
-//         for (ListInit::iterator i = NewList.begin(),
-//                iend = NewList.end();
-//              i != iend;
-//              ++i) {
-//           if ((*i)->getAsString() == LHS->getAsString()) {
-//             *i = MHS;
-//           }
-//         }
-//         return new ListInit(NewList);
-//       }
-//     }
-//     break;
-//   }  
-
-//   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);
+Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
+  switch (getOpcode()) {
+  default: assert(0 && "Unknown binop");
+  case SUBST: {
+    DefInit *LHSd = dynamic_cast<DefInit*>(LHS);
+    VarInit *LHSv = dynamic_cast<VarInit*>(LHS);
+    StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+
+    DefInit *MHSd = dynamic_cast<DefInit*>(MHS);
+    VarInit *MHSv = dynamic_cast<VarInit*>(MHS);
+    StringInit *MHSs = dynamic_cast<StringInit*>(MHS);
+
+    DefInit *RHSd = dynamic_cast<DefInit*>(RHS);
+    VarInit *RHSv = dynamic_cast<VarInit*>(RHS);
+    StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
+
+    if ((LHSd && MHSd && RHSd)
+        || (LHSv && MHSv && RHSv)
+        || (LHSs && MHSs && RHSs)) {
+      if (RHSd) {
+        Record *Val = RHSd->getDef();
+        if (LHSd->getAsString() == RHSd->getAsString()) {
+          Val = MHSd->getDef();
+        }
+        return new DefInit(Val);
+      }
+      if (RHSv) {
+        std::string Val = RHSv->getName();
+        if (LHSv->getAsString() == RHSv->getAsString()) {
+          Val = MHSv->getName();
+        }
+        return new VarInit(Val, getType());
+      }
+      if (RHSs) {
+        std::string Val = RHSs->getValue();
+
+        std::string::size_type found;
+        do {
+          found = Val.find(LHSs->getValue());
+          if (found != std::string::npos) {
+            Val.replace(found, LHSs->getValue().size(), MHSs->getValue());
+          }
+        } while (found != std::string::npos);
 
-//         if (TVal && TVal->getType()->typeIsConvertibleTo(LHSt->getType())) {
+        return new StringInit(Val);
+      }
+    }
+    break;
+  }  
+
+  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 (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;
-//             }
-//           }
+          // 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();
+          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;
-//             }
-//           }
-//         }
+            // 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);
-//       }
-//     }
-//     break;
-//   }
-//   }
-
-//   return this;
-// }
-
-// Init *TernOpInit::resolveReferences(Record &R, const RecordVal *RV) {
-//   Init *lhs = LHS->resolveReferences(R, RV);
-//   Init *mhs = MHS->resolveReferences(R, RV);
-//   Init *rhs = RHS->resolveReferences(R, RV);
+        return new ListInit(NewList);
+      }
+    }
+    break;
+  }
+  }
+
+  return this;
+}
+
+Init *TernOpInit::resolveReferences(Record &R, const RecordVal *RV) {
+  Init *lhs = LHS->resolveReferences(R, RV);
+  Init *mhs = MHS->resolveReferences(R, RV);
+  Init *rhs = RHS->resolveReferences(R, RV);
   
-//   if (LHS != lhs || MHS != mhs || RHS != rhs)
-//     return (new TernOpInit(getOpcode(), lhs, mhs, rhs, getType()))->Fold(&R, 0);
-//   return Fold(&R, 0);
-// }
-
-// std::string TernOpInit::getAsString() const {
-//   std::string Result;
-//   switch (Opc) {
-//   case SUBST: Result = "!subst"; break;
-//   case FOREACH: Result = "!foreach"; break; 
-//  }
-//   return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", " 
-//     + RHS->getAsString() + ")";
-// }
+  if (LHS != lhs || MHS != mhs || RHS != rhs)
+    return (new TernOpInit(getOpcode(), lhs, mhs, rhs, getType()))->Fold(&R, 0);
+  return Fold(&R, 0);
+}
+
+std::string TernOpInit::getAsString() const {
+  std::string Result;
+  switch (Opc) {
+  case SUBST: Result = "!subst"; break;
+  case FOREACH: Result = "!foreach"; break; 
+ }
+  return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", " 
+    + RHS->getAsString() + ")";
+}
 
 Init *TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
   BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());

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

==============================================================================
--- llvm/trunk/utils/TableGen/Record.h (original)
+++ llvm/trunk/utils/TableGen/Record.h Thu May 14 16:54:42 2009
@@ -43,7 +43,7 @@
 class ListInit;
 class UnOpInit;
 class BinOpInit;
-  //class TernOpInit;
+class TernOpInit;
 class DefInit;
 class DagInit;
 class TypedInit;
@@ -85,9 +85,9 @@
   virtual Init *convertValue( BinOpInit *UI) {
     return convertValue((TypedInit*)UI);
   }
-//   virtual Init *convertValue( TernOpInit *UI) {
-//     return convertValue((TypedInit*)UI);
-//   }
+  virtual Init *convertValue( TernOpInit *UI) {
+    return convertValue((TypedInit*)UI);
+  }
   virtual Init *convertValue(  CodeInit *CI) { return 0; }
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
@@ -135,7 +135,7 @@
   virtual Init *convertValue(   DagInit *DI) { return 0; }
   virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
-  //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( TypedInit *TI);
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -179,7 +179,7 @@
   virtual Init *convertValue(   DagInit *DI) { return 0; }
   virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
-  //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( TypedInit *TI);
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -219,7 +219,7 @@
   virtual Init *convertValue(   DagInit *DI) { return 0; }
   virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
-  //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( TypedInit *TI);
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -253,7 +253,7 @@
   virtual Init *convertValue(  ListInit *LI) { return 0; }
   virtual Init *convertValue( UnOpInit *BO);
   virtual Init *convertValue( BinOpInit *BO);
-  //virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
+  virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
 
   virtual Init *convertValue(  CodeInit *CI) { return 0; }
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
@@ -303,7 +303,7 @@
   virtual Init *convertValue(   DagInit *DI) { return 0; }
   virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
-  //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( TypedInit *TI);
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -342,7 +342,7 @@
   virtual Init *convertValue(   DagInit *DI) { return 0; }
   virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
-  //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( TypedInit *TI);
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -377,7 +377,7 @@
   virtual Init *convertValue(   DefInit *DI) { return 0; }
   virtual Init *convertValue( UnOpInit *BO);
   virtual Init *convertValue( BinOpInit *BO);
-  //virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
+  virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
   virtual Init *convertValue(   DagInit *CI) { return (Init*)CI; }
   virtual Init *convertValue( TypedInit *TI);
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
@@ -420,7 +420,7 @@
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
-  //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue(   DefInit *DI);
   virtual Init *convertValue(   DagInit *DI) { return 0; }
   virtual Init *convertValue( TypedInit *VI);
@@ -820,50 +820,50 @@
 
 /// TernOpInit - !op (X, Y, Z) - Combine two inits.
 ///
-// class TernOpInit : public OpInit {
-// public:
-//   enum TernaryOp { SUBST, FOREACH };
-// private:
-//   TernaryOp Opc;
-//   Init *LHS, *MHS, *RHS;
-// public:
-//   TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type) :
-//       OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {
-//   }
-  
-//   // Clone - Clone this operator, replacing arguments with the new list
-//   virtual OpInit *clone(std::vector<Init *> &Operands) {
-//     assert(Operands.size() == 3 && "Wrong number of operands for ternary operation");
-//     return new TernOpInit(getOpcode(), Operands[0], Operands[1], Operands[2], getType());
-//   }
-
-//   int getNumOperands(void) const { return 3; }
-//   Init *getOperand(int i) {
-//     assert(i == 0 || i == 1 || i == 2 && "Invalid operand id for ternary operator");
-//     if (i == 0) {
-//       return getLHS();
-//     }
-//     else if (i == 1) {
-//       return getMHS();
-//     }
-//     else {
-//       return getRHS();
-//     }
-//   }
-
-//   TernaryOp getOpcode() const { return Opc; }
-//   Init *getLHS() const { return LHS; }
-//   Init *getMHS() const { return MHS; }
-//   Init *getRHS() const { return RHS; }
-
-//   // Fold - If possible, fold this to a simpler init.  Return this if not
-//   // possible to fold.
-//   Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
+class TernOpInit : public OpInit {
+public:
+  enum TernaryOp { SUBST, FOREACH };
+private:
+  TernaryOp Opc;
+  Init *LHS, *MHS, *RHS;
+public:
+  TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type) :
+      OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {
+  }
+  
+  // Clone - Clone this operator, replacing arguments with the new list
+  virtual OpInit *clone(std::vector<Init *> &Operands) {
+    assert(Operands.size() == 3 && "Wrong number of operands for ternary operation");
+    return new TernOpInit(getOpcode(), Operands[0], Operands[1], Operands[2], getType());
+  }
+
+  int getNumOperands(void) const { return 3; }
+  Init *getOperand(int i) {
+    assert(i == 0 || i == 1 || i == 2 && "Invalid operand id for ternary operator");
+    if (i == 0) {
+      return getLHS();
+    }
+    else if (i == 1) {
+      return getMHS();
+    }
+    else {
+      return getRHS();
+    }
+  }
+
+  TernaryOp getOpcode() const { return Opc; }
+  Init *getLHS() const { return LHS; }
+  Init *getMHS() const { return MHS; }
+  Init *getRHS() const { return RHS; }
+
+  // Fold - If possible, fold this to a simpler init.  Return this if not
+  // possible to fold.
+  Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
   
-//   virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
   
-//   virtual std::string getAsString() const;
-// };
+  virtual std::string getAsString() const;
+};
 
 
 /// VarInit - 'Opcode' - Represent a reference to an entire variable object.

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

==============================================================================
--- llvm/trunk/utils/TableGen/TGLexer.cpp (original)
+++ llvm/trunk/utils/TableGen/TGLexer.cpp Thu May 14 16:54:42 2009
@@ -447,7 +447,7 @@
   if (Len == 3  && !memcmp(Start, "shl", 3)) return tgtok::XSHL;
   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 == 5 && !memcmp(Start, "subst", 5)) return tgtok::XSubst;
 //   if (Len == 7 && !memcmp(Start, "foreach", 7)) return tgtok::XForEach;
   if (Len == 4 && !memcmp(Start, "cast", 4)) return tgtok::XCast;
 

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

==============================================================================
--- llvm/trunk/utils/TableGen/TGLexer.h (original)
+++ llvm/trunk/utils/TableGen/TGLexer.h Thu May 14 16:54:42 2009
@@ -45,7 +45,7 @@
     MultiClass, String,
     
     // !keywords.
-    XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, // XSubst,
+    XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, XSubst,
     //XForEach,
 
     // Integer value.

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

==============================================================================
--- llvm/trunk/utils/TableGen/TGParser.cpp (original)
+++ llvm/trunk/utils/TableGen/TGParser.cpp Thu May 14 16:54:42 2009
@@ -793,78 +793,78 @@
   }
 
 //   case tgtok::XForEach:
-//   case tgtok::XSubst: {  // Value ::= !ternop '(' Value ',' Value ',' Value ')'
-//     TernOpInit::TernaryOp Code;
-//     RecTy *Type = 0;
-
-
-//     tgtok::TokKind LexCode = Lex.getCode();
-//     Lex.Lex();  // eat the operation
-//     switch (LexCode) {
-//     default: assert(0 && "Unhandled code!");
-//     case tgtok::XForEach:
-//       Code = TernOpInit::FOREACH;
-//       break;
-//     case tgtok::XSubst:
-//       Code = TernOpInit::SUBST;
-//       break;
-//     }
-//     if (Lex.getCode() != tgtok::l_paren) {
-//       TokError("expected '(' after ternary operator");
-//       return 0;
-//     }
-//     Lex.Lex();  // eat the '('
-
-//     Init *LHS = ParseValue(CurRec);
-//     if (LHS == 0) return 0;
-
-//     if (Lex.getCode() != tgtok::comma) {
-//       TokError("expected ',' in ternary operator");
-//       return 0;
-//     }
-//     Lex.Lex();  // eat the ','
-    
-//     Init *MHS = ParseValue(CurRec);
-//     if (MHS == 0) return 0;
-
-//     if (Lex.getCode() != tgtok::comma) {
-//       TokError("expected ',' in ternary operator");
-//       return 0;
-//     }
-//     Lex.Lex();  // eat the ','
-    
-//     Init *RHS = ParseValue(CurRec);
-//     if (RHS == 0) return 0;
-
-//     if (Lex.getCode() != tgtok::r_paren) {
-//       TokError("expected ')' in binary operator");
-//       return 0;
-//     }
-//     Lex.Lex();  // eat the ')'
-
-//     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::XSubst: {
-//       TypedInit *RHSt = dynamic_cast<TypedInit *>(RHS);
-//       if (RHSt == 0) {
-//         TokError("could not get type for !subst");
-//         return 0;
-//       }
-//       Type = RHSt->getType();
-//       break;
-//     }
-//     }
-//     return (new TernOpInit(Code, LHS, MHS, RHS, Type))->Fold(CurRec, CurMultiClass);
-//   }
+  case tgtok::XSubst: {  // Value ::= !ternop '(' Value ',' Value ',' Value ')'
+    TernOpInit::TernaryOp Code;
+    RecTy *Type = 0;
+
+
+    tgtok::TokKind LexCode = Lex.getCode();
+    Lex.Lex();  // eat the operation
+    switch (LexCode) {
+    default: assert(0 && "Unhandled code!");
+      //case tgtok::XForEach:
+      //Code = TernOpInit::FOREACH;
+      //break;
+    case tgtok::XSubst:
+      Code = TernOpInit::SUBST;
+      break;
+    }
+    if (Lex.getCode() != tgtok::l_paren) {
+      TokError("expected '(' after ternary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the '('
+
+    Init *LHS = ParseValue(CurRec);
+    if (LHS == 0) return 0;
+
+    if (Lex.getCode() != tgtok::comma) {
+      TokError("expected ',' in ternary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the ','
+    
+    Init *MHS = ParseValue(CurRec);
+    if (MHS == 0) return 0;
+
+    if (Lex.getCode() != tgtok::comma) {
+      TokError("expected ',' in ternary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the ','
+    
+    Init *RHS = ParseValue(CurRec);
+    if (RHS == 0) return 0;
+
+    if (Lex.getCode() != tgtok::r_paren) {
+      TokError("expected ')' in binary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the ')'
+
+    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::XSubst: {
+      TypedInit *RHSt = dynamic_cast<TypedInit *>(RHS);
+      if (RHSt == 0) {
+        TokError("could not get type for !subst");
+        return 0;
+      }
+      Type = RHSt->getType();
+      break;
+    }
+    }
+    return (new TernOpInit(Code, LHS, MHS, RHS, Type))->Fold(CurRec, CurMultiClass);
+  }
   }
   TokError("could not parse operation");
   return 0;
@@ -1078,9 +1078,9 @@
   case tgtok::XSRL:
   case tgtok::XSHL:
   case tgtok::XStrConcat:
-  case tgtok::XNameConcat: {  // Value ::= !binop '(' Value ',' Value ')'
+  case tgtok::XNameConcat:  // Value ::= !binop '(' Value ',' Value ')'
     //  case tgtok::XForEach:
-    //  case tgtok::XSubst: {  // Value ::= !ternop '(' Value ',' Value ',' Value ')'
+  case tgtok::XSubst: {  // Value ::= !ternop '(' Value ',' Value ',' Value ')'
     return ParseOperation(CurRec);
     break;
   }





More information about the llvm-commits mailing list