[llvm-commits] CVS: llvm/utils/TableGen/FileParser.y Record.cpp Record.h

Chris Lattner lattner at cs.uiuc.edu
Mon Apr 18 20:36:34 PDT 2005



Changes in directory llvm/utils/TableGen:

FileParser.y updated: 1.32 -> 1.33
Record.cpp updated: 1.39 -> 1.40
Record.h updated: 1.46 -> 1.47
---
Log message:

Major change to tblgen: instead of resolving values every time a class is
finished up, only resolve fully when the def is defined.  This allows things
to be changed and all uses to be propagated through.  This implements
TableGen/LazyChange.td and fixes TemplateArgRename.td in the process.

None of the .td files used in LLVM backends are changed at all by this
patch.



---
Diffs of the changes:  (+119 -73)

 FileParser.y |   51 ++++++++++++++++++++++---------------
 Record.cpp   |   81 ++++++++++++++++++++++++++++++++++++-----------------------
 Record.h     |   60 +++++++++++++++++++++++++++----------------
 3 files changed, 119 insertions(+), 73 deletions(-)


Index: llvm/utils/TableGen/FileParser.y
diff -u llvm/utils/TableGen/FileParser.y:1.32 llvm/utils/TableGen/FileParser.y:1.33
--- llvm/utils/TableGen/FileParser.y:1.32	Mon Apr 18 20:11:03 2005
+++ llvm/utils/TableGen/FileParser.y	Mon Apr 18 22:36:21 2005
@@ -25,6 +25,7 @@
 
 extern int Filelineno;
 static Record *CurRec = 0;
+static bool ParsingTemplateArgs = false;
 
 typedef std::pair<Record*, std::vector<Init*>*> SubClassRefTy;
 
@@ -133,6 +134,8 @@
   }
 }
 
+// addSubClass - Add SC as a subclass to CurRec, resolving TemplateArgs as SC's
+// template arguments.
 static void addSubClass(Record *SC, const std::vector<Init*> &TemplateArgs) {
   // Add all of the values in the subclass into the current class...
   const std::vector<RecordVal> &Vals = SC->getValues();
@@ -147,11 +150,19 @@
     exit(1);
   } else {    // This class expects template arguments...
     // Loop over all of the template arguments, setting them to the specified
-    // value or leaving them as the default as necessary.
+    // value or leaving them as the default if necessary.
     for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
       if (i < TemplateArgs.size()) {  // A value is specified for this temp-arg?
 	// Set it now.
 	setValue(TArgs[i], 0, TemplateArgs[i]);
+
+        // Resolve it next.
+        CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
+                                    
+        
+        // Now remove it.
+        CurRec->removeValue(TArgs[i]);
+
       } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
 	err() << "ERROR: Value not specified for template argument #"
 	      << i << " (" << TArgs[i] << ") of subclass '" << SC->getName()
@@ -268,6 +279,10 @@
   } | ID {
     if (const RecordVal *RV = (CurRec ? CurRec->getValue(*$1) : 0)) {
       $$ = new VarInit(*$1, RV->getType());
+    } else if (CurRec && CurRec->isTemplateArg(CurRec->getName()+":"+*$1)) {
+      const RecordVal *RV = CurRec->getValue(CurRec->getName()+":"+*$1);
+      assert(RV && "Template arg doesn't exist??");
+      $$ = new VarInit(CurRec->getName()+":"+*$1, RV->getType());
     } else if (Record *D = Records.getDef(*$1)) {
       $$ = new DefInit(D);
     } else {
@@ -434,9 +449,13 @@
   };
 
 Declaration : OptPrefix Type ID OptValue {
-  addValue(RecordVal(*$3, $2, $1));
-  setValue(*$3, 0, $4);
-  $$ = $3;
+  std::string DecName = *$3;
+  if (ParsingTemplateArgs)
+    DecName = CurRec->getName() + ":" + DecName;
+
+  addValue(RecordVal(DecName, $2, $1));
+  setValue(DecName, 0, $4);
+  $$ = new std::string(DecName);
 };
 
 BodyItem : Declaration ';' {
@@ -492,12 +511,15 @@
              *$1 = "anonymous."+utostr(AnonCounter++);
            CurRec = new Record(*$1);
            delete $1;
+           ParsingTemplateArgs = true;
          } OptTemplateArgList ClassList {
+           ParsingTemplateArgs = false;
            for (unsigned i = 0, e = $4->size(); i != e; ++i) {
 	     addSubClass((*$4)[i].first, *(*$4)[i].second);
              // Delete the template arg values for the class
              delete (*$4)[i].second;
            }
+           delete $4;   // Delete the class list...
 
 	   // Process any variables on the set stack...
 	   for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
@@ -506,22 +528,9 @@
                         LetStack[i][j].HasBits ? &LetStack[i][j].Bits : 0,
                         LetStack[i][j].Value);
          } Body {
-  CurRec->resolveReferences();
-
-  // Now that all of the references have been resolved, we can delete template
-  // arguments for superclasses, so they don't pollute our record, and so that
-  // their names won't conflict with later uses of the name...
-  for (unsigned i = 0, e = $4->size(); i != e; ++i) {
-    Record *SuperClass = (*$4)[i].first;
-    for (unsigned i = 0, e = SuperClass->getTemplateArgs().size(); i != e; ++i)
-      if (!CurRec->isTemplateArg(SuperClass->getTemplateArgs()[i]))
-        CurRec->removeValue(SuperClass->getTemplateArgs()[i]);
-  }
-  delete $4;   // Delete the class list...
-
-  $$ = CurRec;
-  CurRec = 0;
-};
+           $$ = CurRec;
+           CurRec = 0;
+         };
 
 ClassInst : CLASS ObjectBody {
   if (Records.getClass($2->getName())) {
@@ -532,6 +541,8 @@
 };
 
 DefInst : DEF ObjectBody {
+  $2->resolveReferences();
+
   if (!$2->getTemplateArgs().empty()) {
     err() << "Def '" << $2->getName()
           << "' is not permitted to have template arguments!\n";


Index: llvm/utils/TableGen/Record.cpp
diff -u llvm/utils/TableGen/Record.cpp:1.39 llvm/utils/TableGen/Record.cpp:1.40
--- llvm/utils/TableGen/Record.cpp:1.39	Mon Apr 18 20:17:34 2005
+++ llvm/utils/TableGen/Record.cpp	Mon Apr 18 22:36:21 2005
@@ -275,7 +275,7 @@
 // resolveReferences - If there are any field references that refer to fields
 // that have been filled in, we can propagate the values now.
 //
-Init *BitsInit::resolveReferences(Record &R) {
+Init *BitsInit::resolveReferences(Record &R, const RecordVal *RV) {
   bool Changed = false;
   BitsInit *New = new BitsInit(getNumBits());
 
@@ -285,7 +285,7 @@
 
     do {
       B = CurBit;
-      CurBit = CurBit->resolveReferences(R);
+      CurBit = CurBit->resolveReferences(R, RV);
       Changed |= B != CurBit;
     } while (B != CurBit);
     New->setBit(i, CurBit);
@@ -334,7 +334,7 @@
   return new ListInit(Vals);
 }
 
-Init *ListInit::resolveReferences(Record &R) {
+Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) {
   std::vector<Init*> Resolved;
   Resolved.reserve(getSize());
   bool Changed = false;
@@ -345,7 +345,7 @@
 
     do {
       E = CurElt;
-      CurElt = CurElt->resolveReferences(R);
+      CurElt = CurElt->resolveReferences(R, RV);
       Changed |= E != CurElt;
     } while (E != CurElt);
     Resolved.push_back(E);
@@ -396,9 +396,10 @@
 }
 
 
-Init *VarInit::resolveBitReference(Record &R, unsigned Bit) {
-  if (R.isTemplateArg(getName()))
-    return 0;
+Init *VarInit::resolveBitReference(Record &R, const RecordVal *IRV,
+                                   unsigned Bit) {
+  if (R.isTemplateArg(getName())) return 0;
+  if (IRV && IRV->getName() != getName()) return 0;
 
   RecordVal *RV = R.getValue(getName());
   assert(RV && "Reference to a non-existant variable?");
@@ -413,9 +414,10 @@
   return 0;
 }
 
-Init *VarInit::resolveListElementReference(Record &R, unsigned Elt) {
-  if (R.isTemplateArg(getName()))
-    return 0;
+Init *VarInit::resolveListElementReference(Record &R, const RecordVal *IRV,
+                                           unsigned Elt) {
+  if (R.isTemplateArg(getName())) return 0;
+  if (IRV && IRV->getName() != getName()) return 0;
 
   RecordVal *RV = R.getValue(getName());
   assert(RV && "Reference to a non-existant variable?");
@@ -456,33 +458,36 @@
 /// If a value is set for the variable later, this method will be called on
 /// users of the value to allow the value to propagate out.
 ///
-Init *VarInit::resolveReferences(Record &R) {
+Init *VarInit::resolveReferences(Record &R, const RecordVal *RV) {
   if (RecordVal *Val = R.getValue(VarName))
-    if (!dynamic_cast<UnsetInit*>(Val->getValue()))
+    if (RV == Val || (RV == 0 && !dynamic_cast<UnsetInit*>(Val->getValue())))
       return Val->getValue();
   return this;
 }
   
 
-Init *VarBitInit::resolveReferences(Record &R) {
-  if (Init *I = getVariable()->resolveBitReference(R, getBitNum()))
+Init *VarBitInit::resolveReferences(Record &R, const RecordVal *RV) {
+  if (Init *I = getVariable()->resolveBitReference(R, RV, getBitNum()))
     return I;
   return this;
 }
 
-Init *VarListElementInit::resolveReferences(Record &R) {
-  if (Init *I = getVariable()->resolveListElementReference(R, getElementNum()))
+Init *VarListElementInit::resolveReferences(Record &R, const RecordVal *RV) {
+  if (Init *I = getVariable()->resolveListElementReference(R, RV,
+                                                           getElementNum()))
     return I;
   return this;
 }
 
-Init *VarListElementInit::resolveBitReference(Record &R, unsigned Bit) {
+Init *VarListElementInit::resolveBitReference(Record &R, const RecordVal *RV,
+                                              unsigned Bit) {
   // FIXME: This should be implemented, to support references like:
   // bit B = AA[0]{1};
   return 0;
 }
 
-Init *VarListElementInit::resolveListElementReference(Record &R, unsigned Elt) {
+Init *VarListElementInit::
+resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) {
   // FIXME: This should be implemented, to support references like:
   // int B = AA[0][1];
   return 0;
@@ -503,7 +508,8 @@
   OS << Def->getName();
 }
 
-Init *FieldInit::resolveBitReference(Record &R, unsigned Bit) {
+Init *FieldInit::resolveBitReference(Record &R, const RecordVal *RV,
+                                     unsigned Bit) {
   if (Init *BitsVal = Rec->getFieldInit(R, FieldName))
     if (BitsInit *BI = dynamic_cast<BitsInit*>(BitsVal)) {
       assert(Bit < BI->getNumBits() && "Bit reference out of range!");
@@ -515,7 +521,8 @@
   return 0;
 }
 
-Init *FieldInit::resolveListElementReference(Record &R, unsigned Elt) {
+Init *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV,
+                                             unsigned Elt) {
   if (Init *ListVal = Rec->getFieldInit(R, FieldName))
     if (ListInit *LI = dynamic_cast<ListInit*>(ListVal)) {
       if (Elt >= LI->getSize()) return 0;
@@ -527,12 +534,20 @@
   return 0;
 }
 
-Init *FieldInit::resolveReferences(Record &R) {
-  Init *BitsVal = Rec->getFieldInit(R, FieldName);
+Init *FieldInit::resolveReferences(Record &R, const RecordVal *RV) {
+  Init *NewRec = RV ? Rec->resolveReferences(R, RV) : Rec;
+
+  Init *BitsVal = NewRec->getFieldInit(R, FieldName);
   if (BitsVal) {
-    Init *BVR = BitsVal->resolveReferences(R);
+    Init *BVR = BitsVal->resolveReferences(R, RV);
     return BVR->isComplete() ? BVR : this;
   }
+
+  if (NewRec != Rec) {
+    dump();
+    NewRec->dump(); std::cerr << "\n";
+    return new FieldInit(NewRec, FieldName);
+  }
   return this;
 }
 
@@ -566,20 +581,24 @@
 void RecordVal::print(std::ostream &OS, bool PrintSem) const {
   if (getPrefix()) OS << "field ";
   OS << *getType() << " " << getName();
-  if (getValue()) {
+
+  if (getValue())
     OS << " = " << *getValue();
-  }
+
   if (PrintSem) OS << ";\n";
 }
 
-// resolveReferences - If there are any field references that refer to fields
-// that have been filled in, we can propagate the values now.
-//
-void Record::resolveReferences() {
-  for (unsigned i = 0, e = Values.size(); i != e; ++i)
-    Values[i].setValue(Values[i].getValue()->resolveReferences(*this));
+/// resolveReferencesTo - If anything in this record refers to RV, replace the
+/// reference to RV with the RHS of RV.  If RV is null, we resolve all possible
+/// references.
+void Record::resolveReferencesTo(const RecordVal *RV) {
+  for (unsigned i = 0, e = Values.size(); i != e; ++i) {
+    if (Init *V = Values[i].getValue())
+      Values[i].setValue(V->resolveReferences(*this, RV));
+  }
 }
 
+
 void Record::dump() const { std::cerr << *this; }
 
 std::ostream &llvm::operator<<(std::ostream &OS, const Record &R) {


Index: llvm/utils/TableGen/Record.h
diff -u llvm/utils/TableGen/Record.h:1.46 llvm/utils/TableGen/Record.h:1.47
--- llvm/utils/TableGen/Record.h:1.46	Mon Apr 18 20:17:35 2005
+++ llvm/utils/TableGen/Record.h	Mon Apr 18 22:36:21 2005
@@ -23,7 +23,7 @@
 
 namespace llvm {
 
-// RecTy subclasses...
+// RecTy subclasses.
 class BitRecTy;
 class BitsRecTy;
 class IntRecTy;
@@ -33,7 +33,7 @@
 class DagRecTy;
 class RecordRecTy;
 
-// Init subclasses...
+// Init subclasses.
 struct Init;
 class UnsetInit;
 class BitInit;
@@ -50,8 +50,9 @@
 class VarBitInit;
 class VarListElementInit;
 
-// Other classes...
+// Other classes.
 class Record;
+class RecordVal;
 
 //===----------------------------------------------------------------------===//
 //  Type Classes
@@ -474,7 +475,9 @@
   /// If a value is set for the variable later, this method will be called on
   /// users of the value to allow the value to propagate out.
   ///
-  virtual Init *resolveReferences(Record &R) { return this; }
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV) {
+    return this;
+  }
 };
 
 inline std::ostream &operator<<(std::ostream &OS, const Init &I) {
@@ -543,7 +546,7 @@
   }
   virtual void print(std::ostream &OS) const;
 
-  virtual Init *resolveReferences(Record &R);
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
 
   // printXX - Print this bitstream with the specified format, returning true if
   // it is not possible.
@@ -631,7 +634,7 @@
   /// If a value is set for the variable later, this method will be called on
   /// users of the value to allow the value to propagate out.
   ///
-  virtual Init *resolveReferences(Record &R);
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
 
   virtual void print(std::ostream &OS) const;
 };
@@ -654,12 +657,14 @@
   /// 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, unsigned Bit) = 0;
+  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, unsigned Elt) = 0;
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt) = 0;
 };
 
 /// VarInit - 'Opcode' - Represent a reference to an entire variable object.
@@ -675,8 +680,10 @@
 
   const std::string &getName() const { return VarName; }
 
-  virtual Init *resolveBitReference(Record &R, unsigned Bit);
-  virtual Init *resolveListElementReference(Record &R, unsigned Elt);
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit);
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt);
 
   virtual RecTy *getFieldType(const std::string &FieldName) const;
   virtual Init *getFieldInit(Record &R, const std::string &FieldName) const;
@@ -686,7 +693,7 @@
   /// If a value is set for the variable later, this method will be called on
   /// users of the value to allow the value to propagate out.
   ///
-  virtual Init *resolveReferences(Record &R);
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
   
   virtual void print(std::ostream &OS) const { OS << VarName; }
 };
@@ -714,7 +721,7 @@
   virtual void print(std::ostream &OS) const {
     TI->print(OS); OS << "{" << Bit << "}";
   }
-  virtual Init *resolveReferences(Record &R);
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
 };
 
 /// VarListElementInit - List[4] - Represent access to one element of a var or 
@@ -737,17 +744,19 @@
   TypedInit *getVariable() const { return TI; }
   unsigned getElementNum() const { return Element; }
 
-  virtual Init *resolveBitReference(Record &R, unsigned Bit);
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit);
 
   /// 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, unsigned Elt);
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt);
 
   virtual void print(std::ostream &OS) const {
     TI->print(OS); OS << "[" << Element << "]";
   }
-  virtual Init *resolveReferences(Record &R);
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
 };
 
 /// DefInit - AL - Represent a reference to a 'def' in the description
@@ -787,10 +796,12 @@
     return Ty->convertValue(this);
   }
 
-  virtual Init *resolveBitReference(Record &R, unsigned Bit);
-  virtual Init *resolveListElementReference(Record &R, unsigned Elt);
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit);
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt);
 
-  virtual Init *resolveReferences(Record &R);
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
 
   virtual void print(std::ostream &OS) const {
     Rec->print(OS); OS << "." << FieldName;
@@ -949,10 +960,15 @@
     SuperClasses.push_back(R);
   }
 
-  // resolveReferences - If there are any field references that refer to fields
-  // that have been filled in, we can propagate the values now.
-  //
-  void resolveReferences();
+  /// resolveReferences - If there are any field references that refer to fields
+  /// that have been filled in, we can propagate the values now.
+  ///
+  void resolveReferences() { resolveReferencesTo(0); }
+
+  /// resolveReferencesTo - If anything in this record refers to RV, replace the
+  /// reference to RV with the RHS of RV.  If RV is null, we resolve all
+  /// possible references.
+  void resolveReferencesTo(const RecordVal *RV);
 
   void dump() const;
 






More information about the llvm-commits mailing list