[llvm-commits] [vector_llvm] CVS: llvm/utils/TableGen/CodeEmitterGen.cpp CodeGenTarget.cpp DAGISelEmitter.cpp DAGISelEmitter.h InstrInfoEmitter.cpp InstrInfoEmitter.h InstrSelectorEmitter.cpp InstrSelectorEmitter.h Record.cpp Record.h RegisterInfoEmitter.cpp SubtargetEmitter.cpp SubtargetEmitter.h TableGen.cpp

Robert Bocchino bocchino at cs.uiuc.edu
Wed Nov 16 10:33:56 PST 2005



Changes in directory llvm/utils/TableGen:

CodeEmitterGen.cpp updated: 1.41 -> 1.41.2.1
CodeGenTarget.cpp updated: 1.40 -> 1.40.2.1
DAGISelEmitter.cpp updated: 1.59 -> 1.59.2.1
DAGISelEmitter.h updated: 1.33 -> 1.33.2.1
InstrInfoEmitter.cpp updated: 1.28 -> 1.28.2.1
InstrInfoEmitter.h updated: 1.10 -> 1.10.2.1
InstrSelectorEmitter.cpp (r1.45) removed
InstrSelectorEmitter.h (r1.27) removed
Record.cpp updated: 1.45 -> 1.45.2.1
Record.h updated: 1.52 -> 1.52.2.1
RegisterInfoEmitter.cpp updated: 1.36 -> 1.36.2.1
SubtargetEmitter.cpp added (r1.14.2.2)
SubtargetEmitter.h added (r1.7.2.2)
TableGen.cpp updated: 1.39 -> 1.39.2.1
---
Log message:

Merged mainline into Vector LLVM branch


---
Diffs of the changes:  (+894 -122)

 CodeEmitterGen.cpp      |    3 
 CodeGenTarget.cpp       |   28 --
 DAGISelEmitter.cpp      |  242 ++++++++++++++++++----
 DAGISelEmitter.h        |   17 +
 InstrInfoEmitter.cpp    |   80 ++++---
 InstrInfoEmitter.h      |    9 
 Record.cpp              |   19 +
 Record.h                |    6 
 RegisterInfoEmitter.cpp |   19 -
 SubtargetEmitter.cpp    |  516 ++++++++++++++++++++++++++++++++++++++++++++++++
 SubtargetEmitter.h      |   62 +++++
 TableGen.cpp            |   15 -
 12 files changed, 894 insertions(+), 122 deletions(-)


Index: llvm/utils/TableGen/CodeEmitterGen.cpp
diff -u llvm/utils/TableGen/CodeEmitterGen.cpp:1.41 llvm/utils/TableGen/CodeEmitterGen.cpp:1.41.2.1
--- llvm/utils/TableGen/CodeEmitterGen.cpp:1.41	Thu Aug 18 20:04:33 2005
+++ llvm/utils/TableGen/CodeEmitterGen.cpp	Wed Nov 16 12:33:45 2005
@@ -76,7 +76,6 @@
   std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
 
   EmitSourceFileHeader("Machine Code Emitter", o);
-  o << "namespace llvm {\n\n";
   std::string Namespace = Insts[0]->getValueAsString("Namespace") + "::";
 
   // Emit function declaration
@@ -255,6 +254,4 @@
     << "  }\n"
     << "  return Value;\n"
     << "}\n\n";
-
-  o << "} // End llvm namespace \n";
 }


Index: llvm/utils/TableGen/CodeGenTarget.cpp
diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.40 llvm/utils/TableGen/CodeGenTarget.cpp:1.40.2.1
--- llvm/utils/TableGen/CodeGenTarget.cpp:1.40	Thu Oct 13 22:54:49 2005
+++ llvm/utils/TableGen/CodeGenTarget.cpp	Wed Nov 16 12:33:45 2005
@@ -84,15 +84,8 @@
     throw std::string("ERROR: Multiple subclasses of Target defined!");
   TargetRec = Targets[0];
 
-  // Read in all of the CalleeSavedRegisters...
-  ListInit *LI = TargetRec->getValueAsListInit("CalleeSavedRegisters");
-  for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
-    if (DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(i)))
-      CalleeSavedRegisters.push_back(DI->getDef());
-    else
-      throw "Target: " + TargetRec->getName() +
-            " expected register definition in CalleeSavedRegisters list!";
-
+  // Read in all of the CalleeSavedRegisters.
+  CalleeSavedRegisters =TargetRec->getValueAsListOfDefs("CalleeSavedRegisters");
   PointerType = getValueType(TargetRec->getValueAsDef("PointerType"));
 }
 
@@ -108,12 +101,10 @@
 /// getAsmWriter - Return the AssemblyWriter definition for this target.
 ///
 Record *CodeGenTarget::getAsmWriter() const {
-  ListInit *LI = TargetRec->getValueAsListInit("AssemblyWriters");
-  if (AsmWriterNum >= LI->getSize())
+  std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyWriters");
+  if (AsmWriterNum >= LI.size())
     throw "Target does not have an AsmWriter #" + utostr(AsmWriterNum) + "!";
-  DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(AsmWriterNum));
-  if (!DI) throw std::string("AssemblyWriter list should be a list of defs!");
-  return DI->getDef();
+  return LI[AsmWriterNum];
 }
 
 void CodeGenTarget::ReadRegisters() const {
@@ -159,12 +150,9 @@
   MethodBodies = R->getValueAsCode("MethodBodies");
   MethodProtos = R->getValueAsCode("MethodProtos");
   
-  ListInit *RegList = R->getValueAsListInit("MemberList");
-  for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
-    DefInit *RegDef = dynamic_cast<DefInit*>(RegList->getElement(i));
-    if (!RegDef) throw "Register class member is not a record!";
-    Record *Reg = RegDef->getDef();
-
+  std::vector<Record*> RegList = R->getValueAsListOfDefs("MemberList");
+  for (unsigned i = 0, e = RegList.size(); i != e; ++i) {
+    Record *Reg = RegList[i];
     if (!Reg->isSubClassOf("Register"))
       throw "Register Class member '" + Reg->getName() +
             "' does not derive from the Register class!";


Index: llvm/utils/TableGen/DAGISelEmitter.cpp
diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.59 llvm/utils/TableGen/DAGISelEmitter.cpp:1.59.2.1
--- llvm/utils/TableGen/DAGISelEmitter.cpp:1.59	Mon Oct 17 23:41:01 2005
+++ llvm/utils/TableGen/DAGISelEmitter.cpp	Wed Nov 16 12:33:45 2005
@@ -228,16 +228,14 @@
   
   // Parse the properties.
   Properties = 0;
-  ListInit *LI = R->getValueAsListInit("Properties");
-  for (unsigned i = 0, e = LI->getSize(); i != e; ++i) {
-    DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(i));
-    assert(DI && "Properties list must be list of defs!");
-    if (DI->getDef()->getName() == "SDNPCommutative") {
+  std::vector<Record*> PropList = R->getValueAsListOfDefs("Properties");
+  for (unsigned i = 0, e = PropList.size(); i != e; ++i) {
+    if (PropList[i]->getName() == "SDNPCommutative") {
       Properties |= 1 << SDNPCommutative;
-    } else if (DI->getDef()->getName() == "SDNPAssociative") {
+    } else if (PropList[i]->getName() == "SDNPAssociative") {
       Properties |= 1 << SDNPAssociative;
     } else {
-      std::cerr << "Unknown SD Node property '" << DI->getDef()->getName()
+      std::cerr << "Unknown SD Node property '" << PropList[i]->getName()
                 << "' on node '" << R->getName() << "'!\n";
       exit(1);
     }
@@ -245,14 +243,9 @@
   
   
   // Parse the type constraints.
-  ListInit *Constraints = TypeProfile->getValueAsListInit("Constraints");
-  for (unsigned i = 0, e = Constraints->getSize(); i != e; ++i) {
-    assert(dynamic_cast<DefInit*>(Constraints->getElement(i)) &&
-           "Constraints list should contain constraint definitions!");
-    Record *Constraint = 
-      static_cast<DefInit*>(Constraints->getElement(i))->getDef();
-    TypeConstraints.push_back(Constraint);
-  }
+  std::vector<Record*> ConstraintList =
+    TypeProfile->getValueAsListOfDefs("Constraints");
+  TypeConstraints.assign(ConstraintList.begin(), ConstraintList.end());
 }
 
 //===----------------------------------------------------------------------===//
@@ -291,8 +284,13 @@
     return true;
   }      
 
-  TP.error("Type inference contradiction found in node " + 
-           getOperator()->getName() + "!");
+  if (isLeaf()) {
+    dump();
+    TP.error("Type inference contradiction found in node!");
+  } else {
+    TP.error("Type inference contradiction found in node " + 
+             getOperator()->getName() + "!");
+  }
   return true; // unreachable
 }
 
@@ -462,10 +460,12 @@
     // Pattern fragment types will be resolved when they are inlined.
     return MVT::isUnknown;
   } else if (R->isSubClassOf("Register")) {
-    assert(0 && "Explicit registers not handled here yet!\n");
+    //const CodeGenTarget &T = TP.getDAGISelEmitter().getTargetInfo();
+    // TODO: if a register appears in exactly one regclass, we could use that
+    // type info.
     return MVT::isUnknown;
-  } else if (R->isSubClassOf("ValueType")) {
-    // Using a VTSDNode.
+  } else if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) {
+    // Using a VTSDNode or CondCodeSDNode.
     return MVT::Other;
   } else if (R->getName() == "node") {
     // Placeholder.
@@ -482,10 +482,28 @@
 /// exception.
 bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
   if (isLeaf()) {
-    if (DefInit *DI = dynamic_cast<DefInit*>(getLeafValue()))
+    if (DefInit *DI = dynamic_cast<DefInit*>(getLeafValue())) {
       // If it's a regclass or something else known, include the type.
       return UpdateNodeType(getIntrinsicType(DI->getDef(), NotRegisters, TP),
                             TP);
+    } else if (IntInit *II = dynamic_cast<IntInit*>(getLeafValue())) {
+      // Int inits are always integers. :)
+      bool MadeChange = UpdateNodeType(MVT::isInt, TP);
+      
+      if (hasTypeSet()) {
+        unsigned Size = MVT::getSizeInBits(getType());
+        // Make sure that the value is representable for this type.
+        if (Size < 32) {
+          int Val = (II->getValue() << (32-Size)) >> (32-Size);
+          if (Val != II->getValue())
+            TP.error("Sign-extended integer value '" + itostr(II->getValue()) +
+                     "' is out of range for type 'MVT::" + 
+                     getEnumName(getType()) + "'!");
+        }
+      }
+      
+      return MadeChange;
+    }
     return false;
   }
   
@@ -571,19 +589,22 @@
 // TreePattern implementation
 //
 
-TreePattern::TreePattern(Record *TheRec, ListInit *RawPat,
+TreePattern::TreePattern(Record *TheRec, ListInit *RawPat, bool isInput,
                          DAGISelEmitter &ise) : TheRecord(TheRec), ISE(ise) {
+   isInputPattern = isInput;
    for (unsigned i = 0, e = RawPat->getSize(); i != e; ++i)
      Trees.push_back(ParseTreePattern((DagInit*)RawPat->getElement(i)));
 }
 
-TreePattern::TreePattern(Record *TheRec, DagInit *Pat,
+TreePattern::TreePattern(Record *TheRec, DagInit *Pat, bool isInput,
                          DAGISelEmitter &ise) : TheRecord(TheRec), ISE(ise) {
+  isInputPattern = isInput;
   Trees.push_back(ParseTreePattern(Pat));
 }
 
-TreePattern::TreePattern(Record *TheRec, TreePatternNode *Pat, 
+TreePattern::TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput,
                          DAGISelEmitter &ise) : TheRecord(TheRec), ISE(ise) {
+  isInputPattern = isInput;
   Trees.push_back(Pat);
 }
 
@@ -618,6 +639,10 @@
       New = new TreePatternNode(DI);
     } else if (DagInit *DI = dynamic_cast<DagInit*>(Arg)) {
       New = ParseTreePattern(DI);
+    } else if (IntInit *II = dynamic_cast<IntInit*>(Arg)) {
+      New = new TreePatternNode(II);
+      if (!Dag->getArgName(0).empty())
+        error("Constant int argument should not have a name!");
     } else {
       Arg->dump();
       error("Unknown leaf value for tree pattern!");
@@ -636,6 +661,11 @@
       Operator->getName() != "set")
     error("Unrecognized node '" + Operator->getName() + "'!");
   
+  //  Check to see if this is something that is illegal in an input pattern.
+  if (isInputPattern && (Operator->isSubClassOf("Instruction") ||
+      Operator->isSubClassOf("SDNodeXForm")))
+    error("Cannot use '" + Operator->getName() + "' in an input pattern!");
+  
   std::vector<TreePatternNode*> Children;
   
   for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
@@ -663,8 +693,15 @@
           Args.push_back(Dag->getArgName(i));
         }
       }
+    } else if (IntInit *II = dynamic_cast<IntInit*>(Arg)) {
+      TreePatternNode *Node = new TreePatternNode(II);
+      if (!Dag->getArgName(i).empty())
+        error("Constant int argument should not have a name!");
+      Children.push_back(Node);
     } else {
+      std::cerr << '"';
       Arg->dump();
+      std::cerr << "\": ";
       error("Unknown leaf value for tree pattern!");
     }
   }
@@ -771,7 +808,7 @@
   OS << "\n// Predicate functions.\n";
   for (unsigned i = 0, e = Fragments.size(); i != e; ++i) {
     DagInit *Tree = Fragments[i]->getValueAsDag("Fragment");
-    TreePattern *P = new TreePattern(Fragments[i], Tree, *this);
+    TreePattern *P = new TreePattern(Fragments[i], Tree, true, *this);
     PatternFragments[Fragments[i]] = P;
     
     // Validate the argument list, converting it to map, to discard duplicates.
@@ -975,14 +1012,39 @@
   std::vector<Record*> Instrs = Records.getAllDerivedDefinitions("Instruction");
   
   for (unsigned i = 0, e = Instrs.size(); i != e; ++i) {
-    if (!dynamic_cast<ListInit*>(Instrs[i]->getValueInit("Pattern")))
-      continue; // no pattern yet, ignore it.
+    ListInit *LI = 0;
     
-    ListInit *LI = Instrs[i]->getValueAsListInit("Pattern");
-    if (LI->getSize() == 0) continue;  // no pattern.
+    if (dynamic_cast<ListInit*>(Instrs[i]->getValueInit("Pattern")))
+      LI = Instrs[i]->getValueAsListInit("Pattern");
+    
+    // If there is no pattern, only collect minimal information about the
+    // instruction for its operand list.  We have to assume that there is one
+    // result, as we have no detailed info.
+    if (!LI || LI->getSize() == 0) {
+      std::vector<MVT::ValueType> ResultTypes;
+      std::vector<MVT::ValueType> OperandTypes;
+      
+      CodeGenInstruction &InstInfo =Target.getInstruction(Instrs[i]->getName());
+      
+      // Doesn't even define a result?
+      if (InstInfo.OperandList.size() == 0)
+        continue;
+      
+      // Assume the first operand is the result.
+      ResultTypes.push_back(InstInfo.OperandList[0].Ty);
+      
+      // The rest are inputs.
+      for (unsigned j = 1, e = InstInfo.OperandList.size(); j != e; ++j)
+        OperandTypes.push_back(InstInfo.OperandList[j].Ty);
+      
+      // Create and insert the instruction.
+      Instructions.insert(std::make_pair(Instrs[i], 
+                            DAGInstruction(0, ResultTypes, OperandTypes)));
+      continue;  // no pattern.
+    }
     
     // Parse the instruction.
-    TreePattern *I = new TreePattern(Instrs[i], LI, *this);
+    TreePattern *I = new TreePattern(Instrs[i], LI, true, *this);
     // Inline pattern fragments into it.
     I->InlinePatternFragments();
     
@@ -1099,7 +1161,7 @@
     // Use a temporary tree pattern to infer all types and make sure that the
     // constructed result is correct.  This depends on the instruction already
     // being inserted into the Instructions map.
-    TreePattern Temp(I->getRecord(), ResultPattern, *this);
+    TreePattern Temp(I->getRecord(), ResultPattern, false, *this);
     Temp.InferAllTypes();
 
     DAGInstruction &TheInsertedInst = Instructions.find(I->getRecord())->second;
@@ -1112,6 +1174,7 @@
   for (std::map<Record*, DAGInstruction>::iterator II = Instructions.begin(),
        E = Instructions.end(); II != E; ++II) {
     TreePattern *I = II->second.getPattern();
+    if (I == 0) continue;  // No pattern.
     
     if (I->getNumTrees() != 1) {
       std::cerr << "CANNOT HANDLE: " << I->getRecord()->getName() << " yet!";
@@ -1140,7 +1203,7 @@
 
   for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
     DagInit *Tree = Patterns[i]->getValueAsDag("PatternToMatch");
-    TreePattern *Pattern = new TreePattern(Patterns[i], Tree, *this);
+    TreePattern *Pattern = new TreePattern(Patterns[i], Tree, true, *this);
 
     // Inline pattern fragments into it.
     Pattern->InlinePatternFragments();
@@ -1154,7 +1217,7 @@
     if (LI->getSize() == 0) continue;  // no pattern.
     
     // Parse the instruction.
-    TreePattern *Result = new TreePattern(Patterns[i], LI, *this);
+    TreePattern *Result = new TreePattern(Patterns[i], LI, false, *this);
     
     // Inline pattern fragments into it.
     Result->InlinePatternFragments();
@@ -1437,6 +1500,9 @@
     TreePatternNode *Child = P->getChild(i);
     if (!Child->isLeaf() && Child->getExtType() != MVT::Other)
       Size += getPatternSize(Child);
+    else if (Child->isLeaf() && dynamic_cast<IntInit*>(Child->getLeafValue())) {
+      ++Size;  // Matches a ConstantSDNode.
+    }
   }
   
   return Size;
@@ -1477,7 +1543,16 @@
                                          const std::string &RootName,
                                      std::map<std::string,std::string> &VarMap,
                                          unsigned PatternNo, std::ostream &OS) {
-  assert(!N->isLeaf() && "Cannot match against a leaf!");
+  if (N->isLeaf()) {
+    if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
+      OS << "      if (cast<ConstantSDNode>(" << RootName
+         << ")->getSignExtended() != " << II->getValue() << ")\n"
+         << "        goto P" << PatternNo << "Fail;\n";
+      return;
+    }
+    assert(0 && "Cannot match this as a leaf value!");
+    abort();
+  }
   
   // If this node has a name associated with it, capture it in VarMap.  If
   // we already saw this in the pattern, emit code to verify dagness.
@@ -1527,15 +1602,29 @@
       }
       
       // Handle leaves of various types.
-      Init *LeafVal = Child->getLeafValue();
-      Record *LeafRec = dynamic_cast<DefInit*>(LeafVal)->getDef();
-      if (LeafRec->isSubClassOf("RegisterClass")) {
-        // Handle register references.  Nothing to do here.
-      } else if (LeafRec->isSubClassOf("ValueType")) {
-        // Make sure this is the specified value type.
-        OS << "      if (cast<VTSDNode>(" << RootName << i << ")->getVT() != "
-           << "MVT::" << LeafRec->getName() << ") goto P" << PatternNo
-           << "Fail;\n";
+      if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
+        Record *LeafRec = DI->getDef();
+        if (LeafRec->isSubClassOf("RegisterClass")) {
+          // Handle register references.  Nothing to do here.
+        } else if (LeafRec->isSubClassOf("ValueType")) {
+          // Make sure this is the specified value type.
+          OS << "      if (cast<VTSDNode>(" << RootName << i << ")->getVT() != "
+          << "MVT::" << LeafRec->getName() << ") goto P" << PatternNo
+          << "Fail;\n";
+        } else if (LeafRec->isSubClassOf("CondCode")) {
+          // Make sure this is the specified cond code.
+          OS << "      if (cast<CondCodeSDNode>(" << RootName << i
+             << ")->get() != " << "ISD::" << LeafRec->getName()
+             << ") goto P" << PatternNo << "Fail;\n";
+        } else {
+          Child->dump();
+          assert(0 && "Unknown leaf type!");
+        }
+      } else if (IntInit *II = dynamic_cast<IntInit*>(Child->getLeafValue())) {
+        OS << "      if (!isa<ConstantSDNode>(" << RootName << i << ") ||\n"
+           << "          cast<ConstantSDNode>(" << RootName << i
+           << ")->getSignExtended() != " << II->getValue() << ")\n"
+           << "        goto P" << PatternNo << "Fail;\n";
       } else {
         Child->dump();
         assert(0 && "Unknown leaf type!");
@@ -1589,6 +1678,25 @@
   }
   
   if (N->isLeaf()) {
+    // If this is an explicit register reference, handle it.
+    if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
+      unsigned ResNo = Ctr++;
+      if (DI->getDef()->isSubClassOf("Register")) {
+        OS << "      SDOperand Tmp" << ResNo << " = CurDAG->getRegister("
+           << getQualifiedName(DI->getDef()) << ", MVT::"
+           << getEnumName(N->getType())
+           << ");\n";
+        return ResNo;
+      }
+    } else if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
+      unsigned ResNo = Ctr++;
+      OS << "      SDOperand Tmp" << ResNo << " = CurDAG->getTargetConstant("
+         << II->getValue() << ", MVT::"
+        << getEnumName(N->getType())
+        << ");\n";
+      return ResNo;
+    }
+    
     N->dump();
     assert(0 && "Unknown leaf type!");
     return ~0U;
@@ -1685,6 +1793,12 @@
   return false;
 }
 
+Record *DAGISelEmitter::getSDNodeNamed(const std::string &Name) const {
+  Record *N = Records.getDef(Name);
+  assert(N && N->isSubClassOf("SDNode") && "Bad argument");
+  return N;
+}
+
 /// EmitCodeForPattern - Given a pattern to match, emit code to the specified
 /// stream to match the pattern, and generate the code for the match if it
 /// succeeds.
@@ -1785,14 +1899,52 @@
      << "    SDOperand Tmp0 = Select(N.getOperand(0));\n"
      << "    if (!N.Val->hasOneUse()) CodeGenMap[N] = Tmp0;\n"
      << "    return Tmp0;\n"
+     << "  }\n"
+     << "  case ISD::TokenFactor:\n"
+     << "    if (N.getNumOperands() == 2) {\n"
+     << "      SDOperand Op0 = Select(N.getOperand(0));\n"
+     << "      SDOperand Op1 = Select(N.getOperand(1));\n"
+     << "      return CodeGenMap[N] =\n"
+     << "          CurDAG->getNode(ISD::TokenFactor, MVT::Other, Op0, Op1);\n"
+     << "    } else {\n"
+     << "      std::vector<SDOperand> Ops;\n"
+     << "      for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i)\n"
+     << "        Ops.push_back(Select(N.getOperand(i)));\n"
+     << "       return CodeGenMap[N] = \n"
+     << "               CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops);\n"
+     << "    }\n"
+     << "  case ISD::CopyFromReg: {\n"
+     << "    SDOperand Chain = Select(N.getOperand(0));\n"
+     << "    if (Chain == N.getOperand(0)) return N; // No change\n"
+     << "    SDOperand New = CurDAG->getCopyFromReg(Chain,\n"
+     << "                    cast<RegisterSDNode>(N.getOperand(1))->getReg(),\n"
+     << "                                         N.Val->getValueType(0));\n"
+     << "    return New.getValue(N.ResNo);\n"
+     << "  }\n"
+     << "  case ISD::CopyToReg: {\n"
+     << "    SDOperand Chain = Select(N.getOperand(0));\n"
+     << "    SDOperand Reg = N.getOperand(1);\n"
+     << "    SDOperand Val = Select(N.getOperand(2));\n"
+     << "    return CodeGenMap[N] = \n"
+     << "                   CurDAG->getNode(ISD::CopyToReg, MVT::Other,\n"
+     << "                                   Chain, Reg, Val);\n"
      << "  }\n";
     
   // Group the patterns by their top-level opcodes.
   std::map<Record*, std::vector<PatternToMatch*>,
            CompareByRecordName> PatternsByOpcode;
   for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i)
-    PatternsByOpcode[PatternsToMatch[i].first->getOperator()]
-      .push_back(&PatternsToMatch[i]);
+    if (!PatternsToMatch[i].first->isLeaf()) {
+      PatternsByOpcode[PatternsToMatch[i].first->getOperator()]
+         .push_back(&PatternsToMatch[i]);
+    } else {
+      if (IntInit *II = 
+             dynamic_cast<IntInit*>(PatternsToMatch[i].first->getLeafValue())) {
+        PatternsByOpcode[getSDNodeNamed("imm")].push_back(&PatternsToMatch[i]);
+      } else {
+        assert(0 && "Unknown leaf value");
+      }
+    }
   
   // Loop over all of the case statements.
   for (std::map<Record*, std::vector<PatternToMatch*>,


Index: llvm/utils/TableGen/DAGISelEmitter.h
diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.33 llvm/utils/TableGen/DAGISelEmitter.h:1.33.2.1
--- llvm/utils/TableGen/DAGISelEmitter.h:1.33	Sat Oct 15 20:41:58 2005
+++ llvm/utils/TableGen/DAGISelEmitter.h	Wed Nov 16 12:33:45 2005
@@ -226,7 +226,7 @@
     /// ContainsUnresolvedType - Return true if this tree contains any
     /// unresolved types.
     bool ContainsUnresolvedType() const {
-      if (Ty == MVT::LAST_VALUETYPE) return true;
+      if (!hasTypeSet()) return true;
       for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
         if (getChild(i)->ContainsUnresolvedType()) return true;
       return false;
@@ -258,13 +258,20 @@
     /// ISE - the DAG isel emitter coordinating this madness.
     ///
     DAGISelEmitter &ISE;
+
+    /// isInputPattern - True if this is an input pattern, something to match.
+    /// False if this is an output pattern, something to emit.
+    bool isInputPattern;
   public:
       
     /// TreePattern constructor - Parse the specified DagInits into the
     /// current record.
-    TreePattern(Record *TheRec, ListInit *RawPat, DAGISelEmitter &ise);
-    TreePattern(Record *TheRec, DagInit *Pat, DAGISelEmitter &ise);
-    TreePattern(Record *TheRec, TreePatternNode *Pat, DAGISelEmitter &ise);
+    TreePattern(Record *TheRec, ListInit *RawPat, bool isInput,
+                DAGISelEmitter &ise);
+    TreePattern(Record *TheRec, DagInit *Pat, bool isInput,
+                DAGISelEmitter &ise);
+    TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput,
+                DAGISelEmitter &ise);
         
     /// getTrees - Return the tree patterns which corresponds to this pattern.
     ///
@@ -375,6 +382,8 @@
   
   const CodeGenTarget &getTargetInfo() const { return Target; }
   
+  Record *getSDNodeNamed(const std::string &Name) const;
+  
   const SDNodeInfo &getSDNodeInfo(Record *R) const {
     assert(SDNodes.count(R) && "Unknown node!");
     return SDNodes.find(R)->second;


Index: llvm/utils/TableGen/InstrInfoEmitter.cpp
diff -u llvm/utils/TableGen/InstrInfoEmitter.cpp:1.28 llvm/utils/TableGen/InstrInfoEmitter.cpp:1.28.2.1
--- llvm/utils/TableGen/InstrInfoEmitter.cpp:1.28	Fri Aug 26 15:42:52 2005
+++ llvm/utils/TableGen/InstrInfoEmitter.cpp	Wed Nov 16 12:33:45 2005
@@ -15,6 +15,7 @@
 #include "InstrInfoEmitter.h"
 #include "CodeGenTarget.h"
 #include "Record.h"
+#include <algorithm>
 using namespace llvm;
 
 // runEnums - Print out enum values for all of the instructions.
@@ -47,16 +48,6 @@
   OS << "} // End llvm namespace \n";
 }
 
-static std::vector<Record*> GetDefList(ListInit *LI, const std::string &Name) {
-  std::vector<Record*> Result;
-  for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
-    if (DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(i)))
-      Result.push_back(DI->getDef());
-    else
-      throw "Illegal value in '" + Name + "' list!";
-  return Result;
-}
-
 void InstrInfoEmitter::printDefList(const std::vector<Record*> &Uses,
                                     unsigned Num, std::ostream &OS) const {
   OS << "static const unsigned ImplicitList" << Num << "[] = { ";
@@ -86,6 +77,8 @@
 
 // run - Emit the main instruction description records for the target...
 void InstrInfoEmitter::run(std::ostream &OS) {
+  GatherItinClasses();
+
   EmitSourceFileHeader("Target Instruction Descriptors", OS);
   OS << "namespace llvm {\n\n";
 
@@ -99,26 +92,21 @@
 
   // Keep track of all of the def lists we have emitted already.
   std::map<std::vector<Record*>, unsigned> EmittedLists;
-  std::map<ListInit*, unsigned> ListNumbers;
   unsigned ListNumber = 0;
  
   // Emit all of the instruction's implicit uses and defs.
   for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
          E = Target.inst_end(); II != E; ++II) {
     Record *Inst = II->second.TheDef;
-    ListInit *LI = Inst->getValueAsListInit("Uses");
-    if (LI->getSize()) {
-      std::vector<Record*> Uses = GetDefList(LI, Inst->getName());
+    std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses");
+    if (!Uses.empty()) {
       unsigned &IL = EmittedLists[Uses];
       if (!IL) printDefList(Uses, IL = ++ListNumber, OS);
-      ListNumbers[LI] = IL;
     }
-    LI = Inst->getValueAsListInit("Defs");
-    if (LI->getSize()) {
-      std::vector<Record*> Uses = GetDefList(LI, Inst->getName());
-      unsigned &IL = EmittedLists[Uses];
-      if (!IL) printDefList(Uses, IL = ++ListNumber, OS);
-      ListNumbers[LI] = IL;
+    std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs");
+    if (!Defs.empty()) {
+      unsigned &IL = EmittedLists[Defs];
+      if (!IL) printDefList(Defs, IL = ++ListNumber, OS);
     }
   }
 
@@ -150,14 +138,14 @@
   //
   OS << "\nstatic const TargetInstrDescriptor " << TargetName
      << "Insts[] = {\n";
-  emitRecord(Target.getPHIInstruction(), 0, InstrInfo, ListNumbers,
+  emitRecord(Target.getPHIInstruction(), 0, InstrInfo, EmittedLists,
              OperandInfosEmitted, OS);
 
   unsigned i = 0;
   for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
          E = Target.inst_end(); II != E; ++II)
     if (II->second.TheDef != PHI)
-      emitRecord(II->second, ++i, InstrInfo, ListNumbers,
+      emitRecord(II->second, ++i, InstrInfo, EmittedLists,
                  OperandInfosEmitted, OS);
   OS << "};\n";
   OS << "} // End llvm namespace \n";
@@ -165,7 +153,7 @@
 
 void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
                                   Record *InstrInfo,
-                                  std::map<ListInit*, unsigned> &ListNumbers,
+                         std::map<std::vector<Record*>, unsigned> &EmittedLists,
                                std::map<std::vector<Record*>, unsigned> &OpInfo,
                                   std::ostream &OS) {
   int NumOperands;
@@ -183,7 +171,13 @@
     OS << Inst.TheDef->getName();
   else
     OS << Inst.Name;
-  OS << "\",\t" << NumOperands << ", -1, 0, false, 0, 0, 0, 0";
+  
+  unsigned ItinClass = !IsItineraries ? 0 :
+            ItinClassNumber(Inst.TheDef->getValueAsDef("Itinerary")->getName());
+  
+  OS << "\",\t" << NumOperands << ", -1, 0, false, 0, 0, "
+     << ItinClass
+     << ", 0";
 
   // Emit all of the target indepedent flags...
   if (Inst.isReturn)     OS << "|M_RET_FLAG";
@@ -215,17 +209,17 @@
   OS << ", ";
 
   // Emit the implicit uses and defs lists...
-  LI = Inst.TheDef->getValueAsListInit("Uses");
-  if (!LI->getSize())
+  std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses");
+  if (UseList.empty())
     OS << "EmptyImpList, ";
   else
-    OS << "ImplicitList" << ListNumbers[LI] << ", ";
+    OS << "ImplicitList" << EmittedLists[UseList] << ", ";
 
-  LI = Inst.TheDef->getValueAsListInit("Defs");
-  if (!LI->getSize())
+  std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs");
+  if (DefList.empty())
     OS << "EmptyImpList, ";
   else
-    OS << "ImplicitList" << ListNumbers[LI] << ", ";
+    OS << "ImplicitList" << EmittedLists[DefList] << ", ";
 
   // Emit the operand info.
   std::vector<Record*> OperandInfo = GetOperandInfo(Inst);
@@ -237,6 +231,30 @@
   OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
 }
 
+struct LessRecord {
+  bool operator()(const Record *Rec1, const Record *Rec2) const {
+    return Rec1->getName() < Rec2->getName();
+  }
+};
+void InstrInfoEmitter::GatherItinClasses() {
+  std::vector<Record*> DefList =
+                          Records.getAllDerivedDefinitions("InstrItinClass");
+  IsItineraries = !DefList.empty();
+  
+  if (!IsItineraries) return;
+  
+  sort(DefList.begin(), DefList.end(), LessRecord());
+
+  for (unsigned i = 0, N = DefList.size(); i < N; i++) {
+    Record *Def = DefList[i];
+    ItinClassMap[Def->getName()] = i;
+  }
+}  
+  
+unsigned InstrInfoEmitter::ItinClassNumber(std::string ItinName) {
+  return ItinClassMap[ItinName];
+}
+
 void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val,
                                         IntInit *ShiftInt, std::ostream &OS) {
   if (Val == 0 || ShiftInt == 0)


Index: llvm/utils/TableGen/InstrInfoEmitter.h
diff -u llvm/utils/TableGen/InstrInfoEmitter.h:1.10 llvm/utils/TableGen/InstrInfoEmitter.h:1.10.2.1
--- llvm/utils/TableGen/InstrInfoEmitter.h:1.10	Fri Aug 19 13:46:26 2005
+++ llvm/utils/TableGen/InstrInfoEmitter.h	Wed Nov 16 12:33:45 2005
@@ -28,8 +28,11 @@
 
 class InstrInfoEmitter : public TableGenBackend {
   RecordKeeper &Records;
+  bool IsItineraries;
+  std::map<std::string, unsigned> ItinClassMap;
+  
 public:
-  InstrInfoEmitter(RecordKeeper &R) : Records(R) {}
+  InstrInfoEmitter(RecordKeeper &R) : Records(R), IsItineraries(false) {}
 
   // run - Output the instruction set description, returning true on failure.
   void run(std::ostream &OS);
@@ -41,9 +44,11 @@
                     std::ostream &OS) const;
   void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
                   Record *InstrInfo, 
-                  std::map<ListInit*, unsigned> &ListNumbers,
+                  std::map<std::vector<Record*>, unsigned> &EL,
                   std::map<std::vector<Record*>, unsigned> &OpInfo,
                   std::ostream &OS);
+  void GatherItinClasses();
+  unsigned ItinClassNumber(std::string ItinName);
   void emitShiftedValue(Record *R, StringInit *Val, IntInit *Shift,
                         std::ostream &OS);
 };


Index: llvm/utils/TableGen/Record.cpp
diff -u llvm/utils/TableGen/Record.cpp:1.45 llvm/utils/TableGen/Record.cpp:1.45.2.1
--- llvm/utils/TableGen/Record.cpp:1.45	Tue Sep 13 16:44:28 2005
+++ llvm/utils/TableGen/Record.cpp	Wed Nov 16 12:33:45 2005
@@ -709,6 +709,25 @@
         "' does not have a list initializer!";
 }
 
+/// getValueAsListOfDefs - This method looks up the specified field and returns
+/// its 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*> 
+Record::getValueAsListOfDefs(const std::string &FieldName) const {
+  ListInit *List = getValueAsListInit(FieldName);
+  std::vector<Record*> Defs;
+  for (unsigned i = 0; i < List->getSize(); i++) {
+    if (DefInit *DI = dynamic_cast<DefInit*>(List->getElement(i))) {
+      Defs.push_back(DI->getDef());
+    } else {
+      throw "Record `" + getName() + "', field `" + FieldName +
+            "' list is not entirely DefInit!";
+    }
+  }
+  return Defs;
+}
+
 /// getValueAsInt - This method looks up the specified field and returns its
 /// value as an int, throwing an exception if the field does not exist or if
 /// the value is not the right type.


Index: llvm/utils/TableGen/Record.h
diff -u llvm/utils/TableGen/Record.h:1.52 llvm/utils/TableGen/Record.h:1.52.2.1
--- llvm/utils/TableGen/Record.h:1.52	Tue Sep 13 16:44:28 2005
+++ llvm/utils/TableGen/Record.h	Wed Nov 16 12:33:45 2005
@@ -1000,6 +1000,12 @@
   ///
   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.


Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp
diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.36 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.36.2.1
--- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.36	Sun Oct  2 01:23:37 2005
+++ llvm/utils/TableGen/RegisterInfoEmitter.cpp	Wed Nov 16 12:33:45 2005
@@ -163,23 +163,22 @@
 
   for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
     Record *R = Regs[i].TheDef;
-    ListInit *LI = Regs[i].TheDef->getValueAsListInit("Aliases");
+    std::vector<Record*> LI = Regs[i].TheDef->getValueAsListOfDefs("Aliases");
     // Add information that R aliases all of the elements in the list... and
     // that everything in the list aliases R.
-    for (unsigned j = 0, e = LI->getSize(); j != e; ++j) {
-      DefInit *Reg = dynamic_cast<DefInit*>(LI->getElement(j));
-      if (!Reg) throw "ERROR: Alias list element is not a def!";
-      if (RegisterAliases[R].count(Reg->getDef()))
+    for (unsigned j = 0, e = LI.size(); j != e; ++j) {
+      Record *Reg = LI[j];
+      if (RegisterAliases[R].count(Reg))
         std::cerr << "Warning: register alias between " << getQualifiedName(R)
-                  << " and " << getQualifiedName(Reg->getDef())
+                  << " and " << getQualifiedName(Reg)
                   << " specified multiple times!\n";
-      RegisterAliases[R].insert(Reg->getDef());
+      RegisterAliases[R].insert(Reg);
 
-      if (RegisterAliases[Reg->getDef()].count(R))
+      if (RegisterAliases[Reg].count(R))
         std::cerr << "Warning: register alias between " << getQualifiedName(R)
-                  << " and " << getQualifiedName(Reg->getDef())
+                  << " and " << getQualifiedName(Reg)
                   << " specified multiple times!\n";
-      RegisterAliases[Reg->getDef()].insert(R);
+      RegisterAliases[Reg].insert(R);
     }
   }
 


Index: llvm/utils/TableGen/SubtargetEmitter.cpp
diff -c /dev/null llvm/utils/TableGen/SubtargetEmitter.cpp:1.14.2.2
*** /dev/null	Wed Nov 16 12:33:56 2005
--- llvm/utils/TableGen/SubtargetEmitter.cpp	Wed Nov 16 12:33:45 2005
***************
*** 0 ****
--- 1,516 ----
+ //===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by James M. Laskey and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This tablegen backend emits subtarget enumerations.  The format is in a state
+ // flux and will be tightened up when integration to scheduling is complete.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "SubtargetEmitter.h"
+ #include "CodeGenTarget.h"
+ #include "Record.h"
+ #include "llvm/ADT/StringExtras.h"
+ #include "llvm/Support/Debug.h"
+ #include <algorithm>
+ using namespace llvm;
+ 
+ //
+ // Record sort by name function.
+ //
+ struct LessRecord {
+   bool operator()(const Record *Rec1, const Record *Rec2) const {
+     return Rec1->getName() < Rec2->getName();
+   }
+ };
+ 
+ //
+ // Record sort by field "Name" function.
+ //
+ struct LessRecordFieldName {
+   bool operator()(const Record *Rec1, const Record *Rec2) const {
+     return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
+   }
+ };
+ 
+ //
+ // Enumeration - Emit the specified class as an enumeration.
+ //
+ void SubtargetEmitter::Enumeration(std::ostream &OS,
+                                    const char *ClassName,
+                                    bool isBits) {
+   // Get all records of class and sort
+   std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);
+   sort(DefList.begin(), DefList.end(), LessRecord());
+ 
+   // Open enumeration
+   OS << "enum {\n";
+   
+   // For each record
+   for (unsigned i = 0, N = DefList.size(); i < N;) {
+     // Next record
+     Record *Def = DefList[i];
+     
+     // Get and emit name
+     std::string Name = Def->getName();
+     OS << "  " << Name;
+     
+     // If bit flags then emit expression (1 << i)
+     if (isBits)  OS << " = " << " 1 << " << i;
+ 
+     // Depending on 'if more in the list' emit comma
+     if (++i < N) OS << ",";
+     
+     OS << "\n";
+   }
+   
+   // Close enumeration
+   OS << "};\n";
+ }
+ 
+ //
+ // FeatureKeyValues - Emit data of all the subtarget features.  Used by command
+ // line.
+ //
+ void SubtargetEmitter::FeatureKeyValues(std::ostream &OS) {
+   // Gather and sort all the features
+   std::vector<Record*> FeatureList =
+                            Records.getAllDerivedDefinitions("SubtargetFeature");
+   sort(FeatureList.begin(), FeatureList.end(), LessRecord());
+ 
+   // Begin feature table
+   OS << "// Sorted (by key) array of values for CPU features.\n"
+      << "static llvm::SubtargetFeatureKV FeatureKV[] = {\n";
+   
+   // For each feature
+   for (unsigned i = 0, N = FeatureList.size(); i < N;) {
+     // Next feature
+     Record *Feature = FeatureList[i];
+ 
+     std::string Name = Feature->getName();
+     std::string CommandLineName = Feature->getValueAsString("Name");
+     std::string Desc = Feature->getValueAsString("Desc");
+     
+     // Emit as { "feature", "decription", feactureEnum }
+     OS << "  { "
+        << "\"" << CommandLineName << "\", "
+        << "\"" << Desc << "\", "
+        << Name
+        << " }";
+     
+     // Depending on 'if more in the list' emit comma
+     if (++i < N) OS << ",";
+     
+     OS << "\n";
+   }
+   
+   // End feature table
+   OS << "};\n";
+ 
+   // Emit size of table
+   OS<<"\nenum {\n";
+   OS<<"  FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n";
+   OS<<"};\n";
+ }
+ 
+ //
+ // CPUKeyValues - Emit data of all the subtarget processors.  Used by command
+ // line.
+ //
+ void SubtargetEmitter::CPUKeyValues(std::ostream &OS) {
+   // Gather and sort processor information
+   std::vector<Record*> ProcessorList =
+                           Records.getAllDerivedDefinitions("Processor");
+   sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
+ 
+   // Begin processor table
+   OS << "// Sorted (by key) array of values for CPU subtype.\n"
+      << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n";
+      
+   // For each processor
+   for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
+     // Next processor
+     Record *Processor = ProcessorList[i];
+ 
+     std::string Name = Processor->getValueAsString("Name");
+     std::vector<Record*> FeatureList = 
+       Processor->getValueAsListOfDefs("Features");
+     
+     // Emit as { "cpu", "description", f1 | f2 | ... fn },
+     OS << "  { "
+        << "\"" << Name << "\", "
+        << "\"Select the " << Name << " processor\", ";
+     
+     if (FeatureList.empty()) {
+       OS << "0";
+     } else {
+       for (unsigned j = 0, M = FeatureList.size(); j < M;) {
+         Record *Feature = FeatureList[j];
+         std::string Name = Feature->getName();
+         OS << Name;
+         if (++j < M) OS << " | ";
+       }
+     }
+     
+     OS << " }";
+     
+     // Depending on 'if more in the list' emit comma
+     if (++i < N) OS << ",";
+     
+     OS << "\n";
+   }
+   
+   // End processor table
+   OS << "};\n";
+ 
+   // Emit size of table
+   OS<<"\nenum {\n";
+   OS<<"  SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n";
+   OS<<"};\n";
+ }
+ 
+ //
+ // CollectAllItinClasses - Gathers and enumerates all the itinerary classes.
+ // Returns itinerary class count.
+ //
+ unsigned SubtargetEmitter::CollectAllItinClasses(std::ostream &OS,
+                               std::map<std::string, unsigned> &ItinClassesMap) {
+   // Gather and sort all itinerary classes
+   std::vector<Record*> ItinClassList =
+                             Records.getAllDerivedDefinitions("InstrItinClass");
+   sort(ItinClassList.begin(), ItinClassList.end(), LessRecord());
+ 
+   // For each itinerary class
+   unsigned N = ItinClassList.size();
+   for (unsigned i = 0; i < N; i++) {
+     // Next itinerary class
+     Record *ItinClass = ItinClassList[i];
+     // Get name of itinerary class
+     std::string Name = ItinClass->getName();
+     // Assign itinerary class a unique number
+     ItinClassesMap[Name] = i;
+   }
+   
+   // Emit size of table
+   OS<<"\nenum {\n";
+   OS<<"  ItinClassesSize = " << N << "\n";
+   OS<<"};\n";
+ 
+   // Return itinerary class count
+   return N;
+ }
+ 
+ //
+ // FormItineraryString - Compose a string containing the data initialization
+ // for the specified itinerary.  N is the number of stages.
+ //
+ void SubtargetEmitter::FormItineraryString(Record *ItinData,
+                                            std::string &ItinString,
+                                            unsigned &NStages) {
+   // Get states list
+   std::vector<Record*> StageList = ItinData->getValueAsListOfDefs("Stages");
+ 
+   // For each stage
+   unsigned N = NStages = StageList.size();
+   for (unsigned i = 0; i < N; i++) {
+     // Next stage
+     Record *Stage = StageList[i];
+   
+     // Form string as ,{ cycles, u1 | u2 | ... | un }
+     int Cycles = Stage->getValueAsInt("Cycles");
+     ItinString += "  { " + itostr(Cycles) + ", ";
+     
+     // Get unit list
+     std::vector<Record*> UnitList = Stage->getValueAsListOfDefs("Units");
+     
+     // For each unit
+     for (unsigned j = 0, M = UnitList.size(); j < M;) {
+       // Next unit
+       Record *Unit = UnitList[j];
+       
+       // Add name and bitwise or
+       ItinString += Unit->getName();
+       if (++j < M) ItinString += " | ";
+     }
+     
+     // Close off stage
+     ItinString += " }";
+   }
+ }
+ 
+ //
+ // EmitStageData - Generate unique itinerary stages.  Record itineraries for 
+ // processors.
+ //
+ void SubtargetEmitter::EmitStageData(std::ostream &OS,
+        unsigned NItinClasses,
+        std::map<std::string, unsigned> &ItinClassesMap, 
+        std::vector<std::vector<InstrItinerary> > &ProcList) {
+   // Gather processor iteraries
+   std::vector<Record*> ProcItinList =
+                        Records.getAllDerivedDefinitions("ProcessorItineraries");
+   
+   // If just no itinerary then don't bother
+   if (ProcItinList.size() < 2) return;
+ 
+   // Begin stages table
+   OS << "static llvm::InstrStage Stages[] = {\n"
+         "  { 0, 0 }, // No itinerary\n";
+         
+   unsigned ItinEnum = 1;
+   std::map<std::string, unsigned> ItinMap;
+   for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) {
+     // Next record
+     Record *Proc = ProcItinList[i];
+     
+     // Get processor itinerary name
+     std::string Name = Proc->getName();
+     
+     // Skip default
+     if (Name == "NoItineraries") continue;
+     
+     // Create and expand processor itinerary to cover all itinerary classes
+     std::vector<InstrItinerary> ItinList;
+     ItinList.resize(NItinClasses);
+     
+     // Get itinerary data list
+     std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID");
+     
+     // For each itinerary data
+     for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) {
+       // Next itinerary data
+       Record *ItinData = ItinDataList[j];
+       
+       // Get string and stage count
+       std::string ItinString;
+       unsigned NStages;
+       FormItineraryString(ItinData, ItinString, NStages);
+ 
+       // Check to see if it already exists
+       unsigned Find = ItinMap[ItinString];
+       
+       // If new itinerary
+       if (Find == 0) {
+         // Emit as { cycles, u1 | u2 | ... | un }, // index
+         OS << ItinString << ", // " << ItinEnum << "\n";
+         // Record Itin class number
+         ItinMap[ItinString] = Find = ItinEnum++;
+       }
+       
+       // Set up itinerary as location and location + stage count
+       InstrItinerary Intinerary = { Find, Find + NStages };
+ 
+       // Locate where to inject into processor itinerary table
+       std::string Name = ItinData->getValueAsDef("TheClass")->getName();
+       Find = ItinClassesMap[Name];
+       
+       // Inject - empty slots will be 0, 0
+       ItinList[Find] = Intinerary;
+     }
+     
+     // Add process itinerary to list
+     ProcList.push_back(ItinList);
+   }
+   
+   // Closing stage
+   OS << "  { 0, 0 } // End itinerary\n";
+   // End stages table
+   OS << "};\n";
+   
+   // Emit size of table
+   OS<<"\nenum {\n";
+   OS<<"  StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage)\n";
+   OS<<"};\n";
+ }
+ 
+ //
+ // EmitProcessorData - Generate data for processor itineraries.
+ //
+ void SubtargetEmitter::EmitProcessorData(std::ostream &OS,
+       std::vector<std::vector<InstrItinerary> > &ProcList) {
+   // Get an iterator for processor itinerary stages
+   std::vector<std::vector<InstrItinerary> >::iterator
+       ProcListIter = ProcList.begin();
+   
+   // For each processor itinerary
+   std::vector<Record*> Itins =
+                        Records.getAllDerivedDefinitions("ProcessorItineraries");
+   for (unsigned i = 0, N = Itins.size(); i < N; i++) {
+     // Next record
+     Record *Itin = Itins[i];
+ 
+     // Get processor itinerary name
+     std::string Name = Itin->getName();
+     
+     // Skip default
+     if (Name == "NoItineraries") continue;
+ 
+     // Begin processor itinerary table
+     OS << "\n";
+     OS << "static llvm::InstrItinerary " << Name << "[] = {\n";
+     
+     // For each itinerary class
+     std::vector<InstrItinerary> &ItinList = *ProcListIter++;
+     unsigned ItinIndex = 0;
+     for (unsigned j = 0, M = ItinList.size(); j < M;) {
+       InstrItinerary &Intinerary = ItinList[j];
+       
+       // Emit in the form of { first, last } // index
+       if (Intinerary.First == 0) {
+         OS << "  { 0, 0 }";
+       } else {
+         OS << "  { " << Intinerary.First << ", " << Intinerary.Last << " }";
+       }
+       
+       // If more in list add comma
+       if (++j < M) OS << ",";
+       
+       OS << " // " << (j - 1) << "\n";
+     }
+     
+     // End processor itinerary table
+     OS << "};\n";
+   }
+   
+     OS << "\n";
+     OS << "static llvm::InstrItinerary NoItineraries[] = {};\n";
+ }
+ 
+ //
+ // EmitProcessorLookup - generate cpu name to itinerary lookup table.
+ //
+ void SubtargetEmitter::EmitProcessorLookup(std::ostream &OS) {
+   // Gather and sort processor information
+   std::vector<Record*> ProcessorList =
+                           Records.getAllDerivedDefinitions("Processor");
+   sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
+ 
+   // Begin processor table
+   OS << "\n";
+   OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
+      << "static const llvm::SubtargetInfoKV ProcItinKV[] = {\n";
+      
+   // For each processor
+   for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
+     // Next processor
+     Record *Processor = ProcessorList[i];
+ 
+     std::string Name = Processor->getValueAsString("Name");
+     std::string ProcItin = Processor->getValueAsDef("ProcItin")->getName();
+     
+     // Emit as { "cpu", procinit },
+     OS << "  { "
+        << "\"" << Name << "\", "
+        << "(void *)&" << ProcItin;
+         
+     OS << " }";
+     
+     // Depending on ''if more in the list'' emit comma
+     if (++i < N) OS << ",";
+     
+     OS << "\n";
+   }
+   
+   // End processor table
+   OS << "};\n";
+ 
+   // Emit size of table
+   OS<<"\nenum {\n";
+   OS<<"  ProcItinKVSize = sizeof(ProcItinKV)/"
+                             "sizeof(llvm::SubtargetInfoKV)\n";
+   OS<<"};\n";
+ }
+ 
+ //
+ // EmitData - Emits all stages and itineries, folding common patterns.
+ //
+ void SubtargetEmitter::EmitData(std::ostream &OS) {
+   std::map<std::string, unsigned> ItinClassesMap;
+   std::vector<std::vector<InstrItinerary> > ProcList;
+   
+   // Enumerate all the itinerary classes
+   unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap);
+   // Make sure the rest is worth the effort
+   HasItineraries = NItinClasses != 0;
+   
+   if (HasItineraries) {
+     // Emit the stage data
+     EmitStageData(OS, NItinClasses, ItinClassesMap, ProcList);
+     // Emit the processor itinerary data
+     EmitProcessorData(OS, ProcList);
+     // Emit the processor lookup data
+     EmitProcessorLookup(OS);
+   }
+ }
+ 
+ //
+ // ParseFeaturesFunction - Produces a subtarget specific function for parsing
+ // the subtarget features string.
+ //
+ void SubtargetEmitter::ParseFeaturesFunction(std::ostream &OS) {
+   std::vector<Record*> Features =
+                        Records.getAllDerivedDefinitions("SubtargetFeature");
+   sort(Features.begin(), Features.end(), LessRecord());
+ 
+   OS << "// ParseSubtargetFeatures - Parses features string setting specified\n" 
+         "// subtarget options.\n" 
+         "void llvm::";
+   OS << Target;
+   OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
+         "                                  const std::string &CPU) {\n"
+         "  SubtargetFeatures Features(FS);\n"
+         "  Features.setCPUIfNone(CPU);\n"
+         "  uint32_t Bits =  Features.getBits(SubTypeKV, SubTypeKVSize,\n"
+         "                                    FeatureKV, FeatureKVSize);\n";
+         
+   for (unsigned i = 0; i < Features.size(); i++) {
+     // Next record
+     Record *R = Features[i];
+     std::string Instance = R->getName();
+     std::string Name = R->getValueAsString("Name");
+     std::string Type = R->getValueAsString("Type");
+     std::string Attribute = R->getValueAsString("Attribute");
+     
+     OS << "  " << Attribute << " = (Bits & " << Instance << ") != 0;\n";
+   }
+   
+   if (HasItineraries) {
+     OS << "\n"
+        << "  InstrItinerary *Itinerary = (InstrItinerary *)"
+                         "Features.getInfo(ProcItinKV, ProcItinKVSize);\n"
+           "  InstrItins = InstrItineraryData(Stages, Itinerary);\n";
+   }
+   
+   OS << "}\n";
+ }
+ 
+ // 
+ // SubtargetEmitter::run - Main subtarget enumeration emitter.
+ //
+ void SubtargetEmitter::run(std::ostream &OS) {
+   Target = CodeGenTarget().getName();
+ 
+   EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
+ 
+   OS << "#include \"llvm/Target/SubtargetFeature.h\"\n";
+   OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n";
+   
+   Enumeration(OS, "FuncUnit", true);
+   OS<<"\n";
+ //  Enumeration(OS, "InstrItinClass", false);
+ //  OS<<"\n";
+   Enumeration(OS, "SubtargetFeature", true);
+   OS<<"\n";
+   FeatureKeyValues(OS);
+   OS<<"\n";
+   CPUKeyValues(OS);
+   OS<<"\n";
+   EmitData(OS);
+   OS<<"\n";
+   ParseFeaturesFunction(OS);
+ }


Index: llvm/utils/TableGen/SubtargetEmitter.h
diff -c /dev/null llvm/utils/TableGen/SubtargetEmitter.h:1.7.2.2
*** /dev/null	Wed Nov 16 12:33:56 2005
--- llvm/utils/TableGen/SubtargetEmitter.h	Wed Nov 16 12:33:45 2005
***************
*** 0 ****
--- 1,62 ----
+ //===- SubtargetEmitter.h - Generate subtarget enumerations -----*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by James M. Laskey and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This tablegen backend emits subtarget enumerations.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef SUBTARGET_EMITTER_H
+ #define SUBTARGET_EMITTER_H
+ 
+ #include "TableGenBackend.h"
+ #include "llvm/Target/TargetInstrItineraries.h"
+ #include <vector>
+ #include <map>
+ #include <string>
+ 
+ 
+ namespace llvm {
+ 
+ class SubtargetEmitter : public TableGenBackend {
+   
+   RecordKeeper &Records;
+   std::string Target;
+   bool HasItineraries;
+   
+   void Enumeration(std::ostream &OS, const char *ClassName, bool isBits);
+   void FeatureKeyValues(std::ostream &OS);
+   void CPUKeyValues(std::ostream &OS);
+   unsigned CollectAllItinClasses(std::ostream &OS,
+                                std::map<std::string, unsigned> &ItinClassesMap);
+   void FormItineraryString(Record *ItinData, std::string &ItinString,
+                            unsigned &NStages);
+   void EmitStageData(std::ostream &OS, unsigned NItinClasses,
+                      std::map<std::string, unsigned> &ItinClassesMap,
+                      std::vector<std::vector<InstrItinerary> > &ProcList);
+   void EmitProcessorData(std::ostream &OS,
+                        std::vector<std::vector<InstrItinerary> > &ProcList);
+   void EmitProcessorLookup(std::ostream &OS);
+   void EmitData(std::ostream &OS);
+   void ParseFeaturesFunction(std::ostream &OS);
+   
+ public:
+   SubtargetEmitter(RecordKeeper &R) : Records(R), HasItineraries(false) {}
+ 
+   // run - Output the subtarget enumerations, returning true on failure.
+   void run(std::ostream &o);
+ 
+ };
+ 
+ 
+ } // End llvm namespace
+ 
+ #endif
+ 
+ 
+ 


Index: llvm/utils/TableGen/TableGen.cpp
diff -u llvm/utils/TableGen/TableGen.cpp:1.39 llvm/utils/TableGen/TableGen.cpp:1.39.2.1
--- llvm/utils/TableGen/TableGen.cpp:1.39	Fri Sep  2 20:14:03 2005
+++ llvm/utils/TableGen/TableGen.cpp	Wed Nov 16 12:33:45 2005
@@ -23,8 +23,8 @@
 #include "RegisterInfoEmitter.h"
 #include "InstrInfoEmitter.h"
 #include "AsmWriterEmitter.h"
-#include "InstrSelectorEmitter.h"
 #include "DAGISelEmitter.h"
+#include "SubtargetEmitter.h"
 #include <algorithm>
 #include <cstdio>
 #include <fstream>
@@ -34,8 +34,9 @@
   PrintRecords,
   GenEmitter,
   GenRegisterEnums, GenRegister, GenRegisterHeader,
-  GenInstrEnums, GenInstrs, GenAsmWriter, GenInstrSelector,
+  GenInstrEnums, GenInstrs, GenAsmWriter, 
   GenDAGISel,
+  GenSubtarget,
   PrintEnums,
   Parse
 };
@@ -59,10 +60,10 @@
                                "Generate instruction descriptions"),
                     clEnumValN(GenAsmWriter, "gen-asm-writer",
                                "Generate assembly writer"),
-                    clEnumValN(GenInstrSelector, "gen-instr-selector",
-                               "Generate an instruction selector"),
                     clEnumValN(GenDAGISel, "gen-dag-isel",
                                "Generate a DAG instruction selector"),
+                    clEnumValN(GenSubtarget, "gen-subtarget",
+                               "Generate subtarget enumerations"),
                     clEnumValN(PrintEnums, "print-enums",
                                "Print enum values for a class"),
                     clEnumValN(Parse, "parse",
@@ -466,12 +467,12 @@
       AsmWriterEmitter(Records).run(*Out);
       break;
 
-    case GenInstrSelector:
-      InstrSelectorEmitter(Records).run(*Out);
-      break;
     case GenDAGISel:
       DAGISelEmitter(Records).run(*Out);
       break;
+    case GenSubtarget:
+      SubtargetEmitter(Records).run(*Out);
+      break;
     case PrintEnums:
     {
       std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);






More information about the llvm-commits mailing list