PredicateOperand related bug fix.
[oota-llvm.git] / utils / TableGen / Record.h
index 9bd8708e431e1247c249b65f31552b70a0d79bb8..0971e938baae5dfee6dd1f5fc89aa83e736c0aca 100644 (file)
@@ -1,10 +1,10 @@
 //===- Record.h - Classes to represent Table Records ------------*- C++ -*-===//
-// 
+//
 //                     The LLVM Compiler Infrastructure
 //
 // This file was developed by the LLVM research group and is distributed under
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+//
 //===----------------------------------------------------------------------===//
 //
 // This file defines the main TableGen data structures, including the TableGen
 #include <string>
 #include <vector>
 #include <map>
-#include <iostream>
+#include <ostream>
 #include <cassert>
 
 namespace llvm {
 
-// RecTy subclasses...
+// RecTy subclasses.
 class BitRecTy;
 class BitsRecTy;
 class IntRecTy;
@@ -33,7 +33,7 @@ class CodeRecTy;
 class DagRecTy;
 class RecordRecTy;
 
-// Init subclasses...
+// Init subclasses.
 struct Init;
 class UnsetInit;
 class BitInit;
@@ -42,6 +42,7 @@ class IntInit;
 class StringInit;
 class CodeInit;
 class ListInit;
+class BinOpInit;
 class DefInit;
 class DagInit;
 class TypedInit;
@@ -50,8 +51,9 @@ class FieldInit;
 class VarBitInit;
 class VarListElementInit;
 
-// Other classes...
+// Other classes.
 class Record;
+class RecordVal;
 
 //===----------------------------------------------------------------------===//
 //  Type Classes
@@ -74,6 +76,7 @@ public:   // These methods should only be called from subclasses of Init
   virtual Init *convertValue(   IntInit *II) { return 0; }
   virtual Init *convertValue(StringInit *SI) { return 0; }
   virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
   virtual Init *convertValue(  CodeInit *CI) { return 0; }
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
@@ -109,21 +112,35 @@ inline std::ostream &operator<<(std::ostream &OS, const RecTy &Ty) {
 ///
 class BitRecTy : public RecTy {
 public:
-  Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
-  Init *convertValue(BitInit *BI) { return (Init*)BI; }
-  Init *convertValue(BitsInit *BI);
-  Init *convertValue(IntInit *II);
-  Init *convertValue(TypedInit *VI);
-  Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return (Init*)BI; }
+  virtual Init *convertValue(  BitsInit *BI);
+  virtual Init *convertValue(   IntInit *II);
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
 
   void print(std::ostream &OS) const { OS << "bit"; }
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {
     return RHS->baseClassOf(this);
   }
-  virtual bool baseClassOf(const BitRecTy *RHS) const { return true; }
-  virtual bool baseClassOf(const BitsRecTy *RHS) const;
-  virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const;
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+
 };
 
 
@@ -137,22 +154,38 @@ public:
 
   unsigned getNumBits() const { return Size; }
 
-  Init *convertValue(UnsetInit *UI);
-  Init *convertValue(BitInit *UI);
-  Init *convertValue(BitsInit *BI);
-  Init *convertValue(IntInit *II);
-  Init *convertValue(TypedInit *VI);
+  virtual Init *convertValue( UnsetInit *UI);
+  virtual Init *convertValue(   BitInit *UI);
+  virtual Init *convertValue(  BitsInit *BI);
+  virtual Init *convertValue(   IntInit *II);
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
 
   void print(std::ostream &OS) const { OS << "bits<" << Size << ">"; }
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {
     return RHS->baseClassOf(this);
   }
-  virtual bool baseClassOf(const BitRecTy *RHS) const { return Size == 1; }
-  virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
-  virtual bool baseClassOf(const BitsRecTy *RHS) const {
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return Size == 1; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const {
     return RHS->Size == Size;
   }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+
 };
 
 
@@ -160,11 +193,21 @@ public:
 ///
 class IntRecTy : public RecTy {
 public:
-  Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
-  Init *convertValue(IntInit *II) { return (Init*)II; }
-  Init *convertValue(BitInit *BI);
-  Init *convertValue(BitsInit *BI);
-  Init *convertValue(TypedInit *TI);
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI);
+  virtual Init *convertValue(  BitsInit *BI);
+  virtual Init *convertValue(   IntInit *II) { return (Init*)II; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
 
   void print(std::ostream &OS) const { OS << "int"; }
 
@@ -172,25 +215,50 @@ public:
     return RHS->baseClassOf(this);
   }
 
-  virtual bool baseClassOf(const BitRecTy *RHS) const { return true; }
-  virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
-  virtual bool baseClassOf(const BitsRecTy *RHS) const { return true; }
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return true; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+
 };
 
 /// StringRecTy - 'string' - Represent an string value
 ///
 class StringRecTy : public RecTy {
 public:
-  Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
-  Init *convertValue(StringInit *SI) { return (Init*)SI; }
-  Init *convertValue(TypedInit *TI);
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return (Init*)SI; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue( BinOpInit *BO);
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
   void print(std::ostream &OS) const { OS << "string"; }
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {
     return RHS->baseClassOf(this);
   }
 
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
   virtual bool baseClassOf(const StringRecTy *RHS) const { return true; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
 };
 
 // ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of
@@ -205,51 +273,107 @@ public:
 
   RecTy *getElementType() const { return Ty; }
 
-  Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
-  Init *convertValue(ListInit *LI);
-  Init *convertValue(TypedInit *TI);
-  
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI);
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
   void print(std::ostream &OS) const;
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {
     return RHS->baseClassOf(this);
   }
 
-  virtual bool baseClassOf(const ListRecTy *RHS) const {
-    return RHS->getElementType()->typeIsConvertibleTo(Ty); 
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const {
+    return RHS->getElementType()->typeIsConvertibleTo(Ty);
   }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
 };
 
 /// CodeRecTy - 'code' - Represent an code fragment, function or method.
 ///
 class CodeRecTy : public RecTy {
 public:
-  Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
-  Init *convertValue( CodeInit *CI) { return (Init*)CI; }
-  Init *convertValue(TypedInit *TI);
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return (Init*)CI; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
 
   void print(std::ostream &OS) const { OS << "code"; }
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {
     return RHS->baseClassOf(this);
   }
-  virtual bool baseClassOf(const CodeRecTy *RHS) const { return true; }
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return true; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
 };
 
 /// DagRecTy - 'dag' - Represent a dag fragment
 ///
 class DagRecTy : public RecTy {
 public:
-  Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
-  Init *convertValue( DagInit *CI) { return (Init*)CI; }
-  Init *convertValue(TypedInit *TI);
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
+  virtual Init *convertValue(   DagInit *CI) { return (Init*)CI; }
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
 
   void print(std::ostream &OS) const { OS << "dag"; }
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {
     return RHS->baseClassOf(this);
   }
-  virtual bool baseClassOf(const DagRecTy *RHS) const { return true; }
+
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
 };
 
 
@@ -263,15 +387,33 @@ public:
 
   Record *getRecord() const { return Rec; }
 
-  Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
-  Init *convertValue(  DefInit *DI);
-  Init *convertValue(TypedInit *VI); 
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
+  virtual Init *convertValue(   DefInit *DI);
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( TypedInit *VI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
 
   void print(std::ostream &OS) const;
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {
     return RHS->baseClassOf(this);
   }
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
   virtual bool baseClassOf(const RecordRecTy *RHS) const;
 };
 
@@ -338,7 +480,9 @@ struct Init {
   /// 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) {
@@ -407,7 +551,7 @@ public:
   }
   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.
@@ -482,6 +626,8 @@ public:
     return Values[i];
   }
 
+  Record *getElementAsRecord(unsigned i) const;
+  
   Init *convertInitListSlice(const std::vector<unsigned> &Elements);
 
   virtual Init *convertInitializerTo(RecTy *Ty) {
@@ -493,18 +639,48 @@ public:
   /// 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;
 };
 
+/// BinOpInit - !op (X, Y) - Combine two inits.
+///
+class BinOpInit : public Init {
+public:
+  enum BinaryOp { SHL, SRA, SRL, STRCONCAT };
+private:
+  BinaryOp Opc;
+  Init *LHS, *RHS;
+public:
+  BinOpInit(BinaryOp opc, Init *lhs, Init *rhs) : Opc(opc), LHS(lhs), RHS(rhs) {
+  }
+  
+  BinaryOp getOpcode() const { return Opc; }
+  Init *getLHS() const { return LHS; }
+  Init *getRHS() const { return RHS; }
+
+  // Fold - If possible, fold this to a simpler init.  Return this if not
+  // possible to fold.
+  Init *Fold();
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+  
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+  
+  virtual void print(std::ostream &OS) const;
+};
+
+
 
 /// TypedInit - This is the common super-class of types that have a specific,
 /// explicit, type.
 ///
 class TypedInit : public Init {
   RecTy *Ty;
-public:  
+public:
   TypedInit(RecTy *T) : Ty(T) {}
 
   RecTy *getType() const { return Ty; }
@@ -516,12 +692,14 @@ public:
   /// 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.
@@ -530,15 +708,17 @@ class VarInit : public TypedInit {
   std::string VarName;
 public:
   VarInit(const std::string &VN, RecTy *T) : TypedInit(T), VarName(VN) {}
-  
+
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
   }
 
   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;
@@ -548,8 +728,8 @@ public:
   /// 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; }
 };
 
@@ -572,14 +752,14 @@ public:
 
   TypedInit *getVariable() const { return TI; }
   unsigned getBitNum() const { return Bit; }
-  
+
   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 
+/// VarListElementInit - List[4] - Represent access to one element of a var or
 /// field.
 class VarListElementInit : public TypedInit {
   TypedInit *TI;
@@ -599,17 +779,19 @@ public:
   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
@@ -618,7 +800,7 @@ class DefInit : public Init {
   Record *Def;
 public:
   DefInit(Record *D) : Def(D) {}
-  
+
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
   }
@@ -629,7 +811,7 @@ public:
 
   virtual RecTy *getFieldType(const std::string &FieldName) const;
   virtual Init *getFieldInit(Record &R, const std::string &FieldName) const;
-  
+
   virtual void print(std::ostream &OS) const;
 };
 
@@ -649,27 +831,29 @@ public:
     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;
   }
 };
 
-/// DagInit - (def a, b) - Represent a DAG tree value.  DAG inits are required
-/// to have Records for their first value, after that, any legal Init is
-/// possible.
+/// DagInit - (v a, b) - Represent a DAG tree value.  DAG inits are required
+/// 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 {
-  Record *NodeTypeDef;
+  Init *Val;
   std::vector<Init*> Args;
   std::vector<std::string> ArgNames;
 public:
-  DagInit(Record *D, const std::vector<std::pair<Init*, std::string> > &args)
-    : NodeTypeDef(D) {
+  DagInit(Init *V, const std::vector<std::pair<Init*, std::string> > &args)
+    : Val(V) {
     Args.reserve(args.size());
     ArgNames.reserve(args.size());
     for (unsigned i = 0, e = args.size(); i != e; ++i) {
@@ -677,12 +861,16 @@ public:
       ArgNames.push_back(args[i].second);
     }
   }
+  DagInit(Init *V, const std::vector<Init*> &args, 
+          const std::vector<std::string> &argNames)
+  : Val(V), Args(args), ArgNames(argNames) {
+  }
   
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
   }
 
-  Record *getNodeType() const { return NodeTypeDef; }
+  Init *getOperator() const { return Val; }
 
   unsigned getNumArgs() const { return Args.size(); }
   Init *getArg(unsigned Num) const {
@@ -698,6 +886,8 @@ public:
     assert(Num < Args.size() && "Arg number out of range!");
     Args[Num] = I;
   }
+  
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
 
   virtual void print(std::ostream &OS) const;
 };
@@ -739,7 +929,7 @@ inline std::ostream &operator<<(std::ostream &OS, const RecordVal &RV) {
 }
 
 class Record {
-  const std::string Name;
+  std::string Name;
   std::vector<std::string> TemplateArgs;
   std::vector<RecordVal> Values;
   std::vector<Record*> SuperClasses;
@@ -749,6 +939,7 @@ public:
   ~Record() {}
 
   const std::string &getName() const { return Name; }
+  void setName(const std::string &Name);  // Also updates RecordKeeper.
   const std::vector<std::string> &getTemplateArgs() const {
     return TemplateArgs;
   }
@@ -795,7 +986,7 @@ public:
   bool isSubClassOf(Record *R) const {
     for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
       if (SuperClasses[i] == R)
-       return true;
+        return true;
     return false;
   }
 
@@ -811,10 +1002,15 @@ public:
     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;
 
@@ -845,6 +1041,12 @@ public:
   ///
   ListInit *getValueAsListInit(const std::string &FieldName) const;
 
+  /// getValueAsListOfDefs - This method looks up the specified field and
+  /// returnsits value as a vector of records, throwing an exception if the
+  /// field does not exist or if the value is not the right type.
+  ///
+  std::vector<Record*> getValueAsListOfDefs(const std::string &FieldName) const;
+
   /// getValueAsDef - This method looks up the specified field and returns its
   /// value as a Record, throwing an exception if the field does not exist or if
   /// the value is not the right type.
@@ -868,6 +1070,12 @@ public:
   /// the value is not the right type.
   ///
   DagInit *getValueAsDag(const std::string &FieldName) const;
+  
+  /// getValueAsCode - This method looks up the specified field and returns
+  /// its value as the string data in a CodeInit, throwing an exception if the
+  /// field does not exist or if the value is not a code object.
+  ///
+  std::string getValueAsCode(const std::string &FieldName) const;
 };
 
 std::ostream &operator<<(std::ostream &OS, const Record &R);
@@ -877,13 +1085,13 @@ class RecordKeeper {
 public:
   ~RecordKeeper() {
     for (std::map<std::string, Record*>::iterator I = Classes.begin(),
-          E = Classes.end(); I != E; ++I)
+           E = Classes.end(); I != E; ++I)
       delete I->second;
     for (std::map<std::string, Record*>::iterator I = Defs.begin(),
-          E = Defs.end(); I != E; ++I)
+           E = Defs.end(); I != E; ++I)
       delete I->second;
   }
-  
+
   const std::map<std::string, Record*> &getClasses() const { return Classes; }
   const std::map<std::string, Record*> &getDefs() const { return Defs; }
 
@@ -904,6 +1112,19 @@ public:
     Defs.insert(std::make_pair(R->getName(), R));
   }
 
+  /// removeClass - Remove, but do not delete, the specified record.
+  ///
+  void removeClass(const std::string &Name) {
+    assert(Classes.count(Name) && "Class does not exist!");
+    Classes.erase(Name);
+  }
+  /// removeDef - Remove, but do not delete, the specified record.
+  ///
+  void removeDef(const std::string &Name) {
+    assert(Defs.count(Name) && "Def does not exist!");
+    Defs.erase(Name);
+  }
+  
   //===--------------------------------------------------------------------===//
   // High-level helper methods, useful for tablegen backends...