Add full support for code generating expanders!
authorChris Lattner <sabre@nondot.org>
Sun, 10 Aug 2003 23:51:52 +0000 (23:51 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 10 Aug 2003 23:51:52 +0000 (23:51 +0000)
This includes support for referencing named arguments.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7715 91177308-0d34-0410-b5e6-96231b3b80d8

support/tools/TableGen/InstrSelectorEmitter.cpp
support/tools/TableGen/InstrSelectorEmitter.h
utils/TableGen/InstrSelectorEmitter.cpp
utils/TableGen/InstrSelectorEmitter.h

index 99f22f07b9577b9b2be8ae3b72ee5af9de80b1ab..61b9f81305f8648f9ef3b4f921c18847d81b3888 100644 (file)
@@ -55,8 +55,8 @@ bool TreePatternNode::updateNodeType(MVT::ValueType VT,
 ///
 void TreePatternNode::InstantiateNonterminals(InstrSelectorEmitter &ISE) {
   if (!isLeaf()) {
-    for (unsigned i = 0, e = Children.size(); i != e; ++i)
-      Children[i]->InstantiateNonterminals(ISE);
+    for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+      getChild(i)->InstantiateNonterminals(ISE);
     return;
   }
   
@@ -82,9 +82,10 @@ TreePatternNode *TreePatternNode::clone() const {
   if (isLeaf()) {
     New = new TreePatternNode(Value);
   } else {
-    std::vector<TreePatternNode*> CChildren(Children.size());
-    for (unsigned i = 0, e = Children.size(); i != e; ++i)
-      CChildren[i] = Children[i]->clone();
+    std::vector<std::pair<TreePatternNode*, std::string> > CChildren;
+    CChildren.reserve(Children.size());
+    for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+      CChildren.push_back(std::make_pair(getChild(i)->clone(),getChildName(i)));
     New = new TreePatternNode(Operator, CChildren);
   }
   New->setType(Type);
@@ -97,11 +98,10 @@ std::ostream &operator<<(std::ostream &OS, const TreePatternNode &N) {
   OS << "(" << N.getType() << ":";
   OS << N.getOperator()->getName();
   
-  const std::vector<TreePatternNode*> &Children = N.getChildren();
-  if (!Children.empty()) {
-    OS << " " << *Children[0];
-    for (unsigned i = 1, e = Children.size(); i != e; ++i)
-      OS << ", " << *Children[i];
+  if (N.getNumChildren() != 0) {
+    OS << " " << *N.getChild(0);
+    for (unsigned i = 1, e = N.getNumChildren(); i != e; ++i)
+      OS << ", " << *N.getChild(i);
   }  
   return OS << ")";
 }
@@ -133,13 +133,15 @@ Pattern::Pattern(PatternType pty, DagInit *RawPat, Record *TheRec,
 
     // Check to see if we have a top-level (set) of a register.
     if (Tree->getOperator()->getName() == "set") {
-      assert(Tree->getChildren().size() == 2 && "Set with != 2 arguments?");
+      assert(Tree->getNumChildren() == 2 && "Set with != 2 arguments?");
       if (!Tree->getChild(0)->isLeaf())
         error("Arg #0 of set should be a register or register class!");
       Result = Tree->getChild(0)->getValueRecord();
       Tree = Tree->getChild(1);
     }
   }
+
+  calculateArgs(Tree, "");
 }
 
 void Pattern::error(const std::string &Msg) const {
@@ -152,6 +154,19 @@ void Pattern::error(const std::string &Msg) const {
   throw M + TheRecord->getName() + ": " + Msg;  
 }
 
+/// calculateArgs - Compute the list of all of the arguments to this pattern,
+/// which are the non-void leaf nodes in this pattern.
+///
+void Pattern::calculateArgs(TreePatternNode *N, const std::string &Name) {
+  if (N->isLeaf() || N->getNumChildren() == 0) {
+    if (N->getType() != MVT::isVoid)
+      Args.push_back(std::make_pair(N, Name));
+  } else {
+    for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
+      calculateArgs(N->getChild(i), N->getChildName(i));
+  }
+}
+
 /// getIntrinsicType - Check to see if the specified record has an intrinsic
 /// type which should be applied to it.  This infer the type of register
 /// references from the register file information, for example.
@@ -199,12 +214,13 @@ TreePatternNode *Pattern::ParseTreePattern(DagInit *Dag) {
   if (!ISE.getNodeTypes().count(Operator))
     error("Unrecognized node '" + Operator->getName() + "'!");
 
-  std::vector<TreePatternNode*> Children;
+  std::vector<std::pair<TreePatternNode*, std::string> > Children;
   
   for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
     Init *Arg = Dag->getArg(i);
     if (DagInit *DI = dynamic_cast<DagInit*>(Arg)) {
-      Children.push_back(ParseTreePattern(DI));
+      Children.push_back(std::make_pair(ParseTreePattern(DI),
+                                        Dag->getArgName(i)));
     } else if (DefInit *DefI = dynamic_cast<DefInit*>(Arg)) {
       Record *R = DefI->getDef();
       // Direct reference to a leaf DagNode?  Turn it into a DagNode if its own.
@@ -213,9 +229,10 @@ TreePatternNode *Pattern::ParseTreePattern(DagInit *Dag) {
                                 std::vector<std::pair<Init*, std::string> >()));
         --i;  // Revisit this node...
       } else {
-        Children.push_back(new TreePatternNode(DefI));
+        Children.push_back(std::make_pair(new TreePatternNode(DefI),
+                                          Dag->getArgName(i)));
         // If it's a regclass or something else known, set the type.
-        Children.back()->setType(getIntrinsicType(R));
+        Children.back().first->setType(getIntrinsicType(R));
       }
     } else {
       Arg->dump();
@@ -248,17 +265,16 @@ bool Pattern::InferTypes(TreePatternNode *N, bool &MadeChange) {
 
   // Check to see if we can infer anything about the argument types from the
   // return types...
-  const std::vector<TreePatternNode*> &Children = N->getChildren();
-  if (Children.size() != NT.ArgTypes.size())
+  if (N->getNumChildren() != NT.ArgTypes.size())
     error("Incorrect number of children for " + Operator->getName() + " node!");
 
-  for (unsigned i = 0, e = Children.size(); i != e; ++i) {
-    TreePatternNode *Child = Children[i];
+  for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
+    TreePatternNode *Child = N->getChild(i);
     AnyUnset |= InferTypes(Child, MadeChange);
 
     switch (NT.ArgTypes[i]) {
     case NodeType::Arg0:
-      MadeChange |= Child->updateNodeType(Children[0]->getType(),
+      MadeChange |= Child->updateNodeType(N->getChild(0)->getType(),
                                           TheRecord->getName());
       break;
     case NodeType::Val:
@@ -279,7 +295,7 @@ bool Pattern::InferTypes(TreePatternNode *N, bool &MadeChange) {
     MadeChange |= N->updateNodeType(MVT::isVoid, TheRecord->getName());
     break;
   case NodeType::Arg0:
-    MadeChange |= N->updateNodeType(Children[0]->getType(),
+    MadeChange |= N->updateNodeType(N->getChild(0)->getType(),
                                     TheRecord->getName());
     break;
 
@@ -647,10 +663,9 @@ void InstrSelectorEmitter::EmitMatchCosters(std::ostream &OS,
   OS << "\n" << Indent << "// Operand matching costs...\n";
   std::set<std::string> ComputedValues;   // Avoid duplicate computations...
   for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
-    const std::vector<TreePatternNode*> &Children =
-      Patterns[i].second->getChildren();
-    for (unsigned c = 0, e = Children.size(); c != e; ++c) {
-      TreePatternNode *N = Children[c];
+    TreePatternNode *NParent = Patterns[i].second;
+    for (unsigned c = 0, e = NParent->getNumChildren(); c != e; ++c) {
+      TreePatternNode *N = NParent->getChild(c);
       if (N->isLeaf()) {
         Record *VR = N->getValueRecord();
         const std::string &LeafName = VR->getName();
@@ -820,6 +835,60 @@ static void ReduceAllOperands(TreePatternNode *N, const std::string &Name,
   }
 }
 
+/// PrintExpanderOperand - Print out Arg as part of the instruction emission
+/// process for the expander pattern P.  This argument may be referencing some
+/// values defined in P, or may just be physical register references or
+/// something like that.  If PrintArg is true, we are printing out arguments to
+/// the BuildMI call.  If it is false, we are printing the result register
+/// name.
+void InstrSelectorEmitter::PrintExpanderOperand(Init *Arg,
+                                                const std::string &NameVar,
+                                                Record *ArgDecl,
+                                                Pattern *P, bool PrintArg,
+                                                std::ostream &OS) {
+  if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
+    Record *Arg = DI->getDef();
+    if (Arg->isSubClassOf("Register")) {
+      // This is a physical register reference... make sure that the instruction
+      // requested a register!
+      if (!ArgDecl->isSubClassOf("RegisterClass"))
+        P->error("Argument mismatch for instruction pattern!");
+
+      // FIXME: This should check to see if the register is in the specified
+      // register class!
+      if (PrintArg) OS << ".addReg(";
+      OS << getQualifiedName(Arg);
+      if (PrintArg) OS << ")";
+      return;
+    } else if (Arg->isSubClassOf("RegisterClass")) {
+      // If this is a symbolic register class reference, we must be using a
+      // named value.
+      if (NameVar.empty()) P->error("Did not specify WHICH register to pass!");
+      if (Arg != ArgDecl) P->error("Instruction pattern mismatch!");
+
+      if (PrintArg) OS << ".addReg(";
+      OS << NameVar;
+      if (PrintArg) OS << ")";
+      return;
+    }
+    P->error("Unknown operand type '" + Arg->getName() + "' to expander!");
+  }
+  P->error("Unknown operand type to expander!");
+}
+
+static std::string getArgName(Pattern *P, const std::string &ArgName, 
+       const std::vector<std::pair<TreePatternNode*, std::string> > &Operands) {
+  assert(P->getNumArgs() == Operands.size() &&"Argument computation mismatch!");
+  if (ArgName.empty()) return "";
+
+  for (unsigned i = 0, e = P->getNumArgs(); i != e; ++i)
+    if (P->getArgName(i) == ArgName)
+      return Operands[i].second + "->Val";
+  P->error("Pattern does not define a value named $" + ArgName + "!");
+  return "";
+}
+
+
 void InstrSelectorEmitter::run(std::ostream &OS) {
   // Type-check all of the node types to ensure we "understand" them.
   ReadNodeTypes();
@@ -1074,6 +1143,7 @@ void InstrSelectorEmitter::run(std::ostream &OS) {
         // pattern that this is...
         switch (P->getPatternType()) {
         case Pattern::Instruction:
+          // Instruction patterns just emit a single MachineInstr, using BuildMI
           OS << "    BuildMI(MBB, " << Target.getName() << "::"
              << P->getRecord()->getName() << ", " << Operands.size();
           if (P->getResult()) OS << ", NewReg";
@@ -1089,10 +1159,49 @@ void InstrSelectorEmitter::run(std::ostream &OS) {
               OS << ".addZImm(" << Operands[i].second << "->Val)";
             }
           OS << ";\n";
-
           break;
-        case Pattern::Expander:
+        case Pattern::Expander: {
+          // Expander patterns emit one machine instr for each instruction in
+          // the list of instructions expanded to.
+          ListInit *Insts = P->getRecord()->getValueAsListInit("Result");
+          for (unsigned IN = 0, e = Insts->getSize(); IN != e; ++IN) {
+            DagInit *DIInst = dynamic_cast<DagInit*>(Insts->getElement(IN));
+            if (!DIInst) P->error("Result list must contain instructions!");
+            Pattern *InstPat = getPattern(DIInst->getNodeType());
+            if (!InstPat || InstPat->getPatternType() != Pattern::Instruction)
+              P->error("Instruction list must contain Instruction patterns!");
+            
+            bool hasResult = InstPat->getResult() != 0;
+            if (InstPat->getNumArgs() != DIInst->getNumArgs()-hasResult) {
+              P->error("Incorrect number of arguments specified for inst '" +
+                       InstPat->getRecord()->getName() + "' in result list!");
+            }
+
+            // Start emission of the instruction...
+            OS << "    BuildMI(MBB, " << Target.getName() << "::"
+               << InstPat->getRecord()->getName() << ", "
+               << DIInst->getNumArgs()-hasResult;
+            // Emit register result if necessary..
+            if (Record *R = InstPat->getResult()) {
+              std::string ArgNameVal =
+                getArgName(P, DIInst->getArgName(0), Operands);
+              PrintExpanderOperand(DIInst->getArg(0), ArgNameVal,
+                                   R, P, false, OS << ", ");
+            }
+            OS << ")";
+
+            for (unsigned i = hasResult, e = DIInst->getNumArgs(); i != e; ++i){
+              std::string ArgNameVal =
+                getArgName(P, DIInst->getArgName(i), Operands);
+
+              PrintExpanderOperand(DIInst->getArg(i), ArgNameVal,
+                                  InstPat->getArgRec(i-hasResult), P, true, OS);
+            }
+
+            OS << ";\n";
+          }
           break;
+        }
         default:
           assert(0 && "Reduction of this type of pattern not implemented!");
         }
index ec0231ad12c2cde8c038dfd87cee722b3d65d1bd..20e800bf73959d9fc1f78d8c43c03f2e4e21db59 100644 (file)
@@ -57,13 +57,14 @@ class TreePatternNode {
 
   /// Children - If this is not a leaf (Operator != 0), this is the subtrees
   /// that we contain.
-  std::vector<TreePatternNode*> Children;
+  std::vector<std::pair<TreePatternNode*, std::string> > Children;
 
   /// Value - If this node is a leaf, this indicates what the thing is.
   ///
   Init *Value;
 public:
-  TreePatternNode(Record *o, const std::vector<TreePatternNode*> &c)
+  TreePatternNode(Record *o, const std::vector<std::pair<TreePatternNode*,
+                                                         std::string> > &c)
     : Operator(o), Type(MVT::Other), Children(c), Value(0) {}
   TreePatternNode(Init *V) : Operator(0), Type(MVT::Other), Value(V) {}
 
@@ -76,14 +77,16 @@ public:
 
   bool isLeaf() const { return Operator == 0; }
 
-  const std::vector<TreePatternNode*> &getChildren() const {
-    assert(Operator != 0 && "This is a leaf node!");
-    return Children;
-  }
   unsigned getNumChildren() const { return Children.size(); }
   TreePatternNode *getChild(unsigned c) const {
+    assert(Operator != 0 && "This is a leaf node!");
     assert(c < Children.size() && "Child access out of range!");
-    return getChildren()[c];
+    return Children[c].first;
+  }
+  const std::string &getChildName(unsigned c) const {
+    assert(Operator != 0 && "This is a leaf node!");
+    assert(c < Children.size() && "Child access out of range!");
+    return Children[c].second;
   }
 
   Init *getValue() const {
@@ -151,6 +154,10 @@ private:
   ///
   bool Resolved;
 
+  /// Args - This is a list of all of the arguments to this pattern, which are
+  /// the non-void leaf nodes in this pattern.
+  std::vector<std::pair<TreePatternNode*, std::string> > Args;
+
   /// ISE - the instruction selector emitter coordinating this madness.
   ///
   InstrSelectorEmitter &ISE;
@@ -164,7 +171,9 @@ public:
   /// Pattern - Constructor used for cloning nonterminal patterns
   Pattern(TreePatternNode *tree, Record *rec, bool res,
           InstrSelectorEmitter &ise) : PTy(Nonterminal), Tree(tree), Result(0),
-                                       TheRecord(rec), Resolved(res), ISE(ise){}
+                                       TheRecord(rec), Resolved(res), ISE(ise) {
+    calculateArgs(Tree, "");
+  }
 
   /// getPatternType - Return what flavor of Record this pattern originated from
   ///
@@ -181,6 +190,19 @@ public:
   ///
   Record *getRecord() const { return TheRecord; }
 
+  unsigned getNumArgs() const { return Args.size(); }
+  TreePatternNode *getArg(unsigned i) const {
+    assert(i < Args.size() && "Argument reference out of range!");
+    return Args[i].first;
+  }
+  Record *getArgRec(unsigned i) const {
+    return getArg(i)->getValueRecord();
+  }
+  const std::string &getArgName(unsigned i) const {
+    assert(i < Args.size() && "Argument reference out of range!");
+    return Args[i].second;
+  }
+
   bool isResolved() const { return Resolved; }
 
   /// InferAllTypes - Runs the type inference engine on the current pattern,
@@ -211,6 +233,7 @@ public:
   void dump() const;
 
 private:
+  void calculateArgs(TreePatternNode *N, const std::string &Name);
   MVT::ValueType getIntrinsicType(Record *R) const;
   TreePatternNode *ParseTreePattern(DagInit *DI);
   bool InferTypes(TreePatternNode *N, bool &MadeChange);
@@ -338,6 +361,16 @@ private:
   void EmitMatchCosters(std::ostream &OS,
             const std::vector<std::pair<Pattern*, TreePatternNode*> > &Patterns,
                         const std::string &VarPrefix, unsigned Indent);
+  
+  /// PrintExpanderOperand - Print out Arg as part of the instruction emission
+  /// process for the expander pattern P.  This argument may be referencing some
+  /// values defined in P, or may just be physical register references or
+  /// something like that.  If PrintArg is true, we are printing out arguments
+  /// to the BuildMI call.  If it is false, we are printing the result register
+  /// name.
+  void PrintExpanderOperand(Init *Arg, const std::string &NameVar,
+                            Record *ArgDecl, Pattern *P,
+                            bool PrintArg, std::ostream &OS);
 };
 
 #endif
index 99f22f07b9577b9b2be8ae3b72ee5af9de80b1ab..61b9f81305f8648f9ef3b4f921c18847d81b3888 100644 (file)
@@ -55,8 +55,8 @@ bool TreePatternNode::updateNodeType(MVT::ValueType VT,
 ///
 void TreePatternNode::InstantiateNonterminals(InstrSelectorEmitter &ISE) {
   if (!isLeaf()) {
-    for (unsigned i = 0, e = Children.size(); i != e; ++i)
-      Children[i]->InstantiateNonterminals(ISE);
+    for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+      getChild(i)->InstantiateNonterminals(ISE);
     return;
   }
   
@@ -82,9 +82,10 @@ TreePatternNode *TreePatternNode::clone() const {
   if (isLeaf()) {
     New = new TreePatternNode(Value);
   } else {
-    std::vector<TreePatternNode*> CChildren(Children.size());
-    for (unsigned i = 0, e = Children.size(); i != e; ++i)
-      CChildren[i] = Children[i]->clone();
+    std::vector<std::pair<TreePatternNode*, std::string> > CChildren;
+    CChildren.reserve(Children.size());
+    for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+      CChildren.push_back(std::make_pair(getChild(i)->clone(),getChildName(i)));
     New = new TreePatternNode(Operator, CChildren);
   }
   New->setType(Type);
@@ -97,11 +98,10 @@ std::ostream &operator<<(std::ostream &OS, const TreePatternNode &N) {
   OS << "(" << N.getType() << ":";
   OS << N.getOperator()->getName();
   
-  const std::vector<TreePatternNode*> &Children = N.getChildren();
-  if (!Children.empty()) {
-    OS << " " << *Children[0];
-    for (unsigned i = 1, e = Children.size(); i != e; ++i)
-      OS << ", " << *Children[i];
+  if (N.getNumChildren() != 0) {
+    OS << " " << *N.getChild(0);
+    for (unsigned i = 1, e = N.getNumChildren(); i != e; ++i)
+      OS << ", " << *N.getChild(i);
   }  
   return OS << ")";
 }
@@ -133,13 +133,15 @@ Pattern::Pattern(PatternType pty, DagInit *RawPat, Record *TheRec,
 
     // Check to see if we have a top-level (set) of a register.
     if (Tree->getOperator()->getName() == "set") {
-      assert(Tree->getChildren().size() == 2 && "Set with != 2 arguments?");
+      assert(Tree->getNumChildren() == 2 && "Set with != 2 arguments?");
       if (!Tree->getChild(0)->isLeaf())
         error("Arg #0 of set should be a register or register class!");
       Result = Tree->getChild(0)->getValueRecord();
       Tree = Tree->getChild(1);
     }
   }
+
+  calculateArgs(Tree, "");
 }
 
 void Pattern::error(const std::string &Msg) const {
@@ -152,6 +154,19 @@ void Pattern::error(const std::string &Msg) const {
   throw M + TheRecord->getName() + ": " + Msg;  
 }
 
+/// calculateArgs - Compute the list of all of the arguments to this pattern,
+/// which are the non-void leaf nodes in this pattern.
+///
+void Pattern::calculateArgs(TreePatternNode *N, const std::string &Name) {
+  if (N->isLeaf() || N->getNumChildren() == 0) {
+    if (N->getType() != MVT::isVoid)
+      Args.push_back(std::make_pair(N, Name));
+  } else {
+    for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
+      calculateArgs(N->getChild(i), N->getChildName(i));
+  }
+}
+
 /// getIntrinsicType - Check to see if the specified record has an intrinsic
 /// type which should be applied to it.  This infer the type of register
 /// references from the register file information, for example.
@@ -199,12 +214,13 @@ TreePatternNode *Pattern::ParseTreePattern(DagInit *Dag) {
   if (!ISE.getNodeTypes().count(Operator))
     error("Unrecognized node '" + Operator->getName() + "'!");
 
-  std::vector<TreePatternNode*> Children;
+  std::vector<std::pair<TreePatternNode*, std::string> > Children;
   
   for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
     Init *Arg = Dag->getArg(i);
     if (DagInit *DI = dynamic_cast<DagInit*>(Arg)) {
-      Children.push_back(ParseTreePattern(DI));
+      Children.push_back(std::make_pair(ParseTreePattern(DI),
+                                        Dag->getArgName(i)));
     } else if (DefInit *DefI = dynamic_cast<DefInit*>(Arg)) {
       Record *R = DefI->getDef();
       // Direct reference to a leaf DagNode?  Turn it into a DagNode if its own.
@@ -213,9 +229,10 @@ TreePatternNode *Pattern::ParseTreePattern(DagInit *Dag) {
                                 std::vector<std::pair<Init*, std::string> >()));
         --i;  // Revisit this node...
       } else {
-        Children.push_back(new TreePatternNode(DefI));
+        Children.push_back(std::make_pair(new TreePatternNode(DefI),
+                                          Dag->getArgName(i)));
         // If it's a regclass or something else known, set the type.
-        Children.back()->setType(getIntrinsicType(R));
+        Children.back().first->setType(getIntrinsicType(R));
       }
     } else {
       Arg->dump();
@@ -248,17 +265,16 @@ bool Pattern::InferTypes(TreePatternNode *N, bool &MadeChange) {
 
   // Check to see if we can infer anything about the argument types from the
   // return types...
-  const std::vector<TreePatternNode*> &Children = N->getChildren();
-  if (Children.size() != NT.ArgTypes.size())
+  if (N->getNumChildren() != NT.ArgTypes.size())
     error("Incorrect number of children for " + Operator->getName() + " node!");
 
-  for (unsigned i = 0, e = Children.size(); i != e; ++i) {
-    TreePatternNode *Child = Children[i];
+  for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
+    TreePatternNode *Child = N->getChild(i);
     AnyUnset |= InferTypes(Child, MadeChange);
 
     switch (NT.ArgTypes[i]) {
     case NodeType::Arg0:
-      MadeChange |= Child->updateNodeType(Children[0]->getType(),
+      MadeChange |= Child->updateNodeType(N->getChild(0)->getType(),
                                           TheRecord->getName());
       break;
     case NodeType::Val:
@@ -279,7 +295,7 @@ bool Pattern::InferTypes(TreePatternNode *N, bool &MadeChange) {
     MadeChange |= N->updateNodeType(MVT::isVoid, TheRecord->getName());
     break;
   case NodeType::Arg0:
-    MadeChange |= N->updateNodeType(Children[0]->getType(),
+    MadeChange |= N->updateNodeType(N->getChild(0)->getType(),
                                     TheRecord->getName());
     break;
 
@@ -647,10 +663,9 @@ void InstrSelectorEmitter::EmitMatchCosters(std::ostream &OS,
   OS << "\n" << Indent << "// Operand matching costs...\n";
   std::set<std::string> ComputedValues;   // Avoid duplicate computations...
   for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
-    const std::vector<TreePatternNode*> &Children =
-      Patterns[i].second->getChildren();
-    for (unsigned c = 0, e = Children.size(); c != e; ++c) {
-      TreePatternNode *N = Children[c];
+    TreePatternNode *NParent = Patterns[i].second;
+    for (unsigned c = 0, e = NParent->getNumChildren(); c != e; ++c) {
+      TreePatternNode *N = NParent->getChild(c);
       if (N->isLeaf()) {
         Record *VR = N->getValueRecord();
         const std::string &LeafName = VR->getName();
@@ -820,6 +835,60 @@ static void ReduceAllOperands(TreePatternNode *N, const std::string &Name,
   }
 }
 
+/// PrintExpanderOperand - Print out Arg as part of the instruction emission
+/// process for the expander pattern P.  This argument may be referencing some
+/// values defined in P, or may just be physical register references or
+/// something like that.  If PrintArg is true, we are printing out arguments to
+/// the BuildMI call.  If it is false, we are printing the result register
+/// name.
+void InstrSelectorEmitter::PrintExpanderOperand(Init *Arg,
+                                                const std::string &NameVar,
+                                                Record *ArgDecl,
+                                                Pattern *P, bool PrintArg,
+                                                std::ostream &OS) {
+  if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
+    Record *Arg = DI->getDef();
+    if (Arg->isSubClassOf("Register")) {
+      // This is a physical register reference... make sure that the instruction
+      // requested a register!
+      if (!ArgDecl->isSubClassOf("RegisterClass"))
+        P->error("Argument mismatch for instruction pattern!");
+
+      // FIXME: This should check to see if the register is in the specified
+      // register class!
+      if (PrintArg) OS << ".addReg(";
+      OS << getQualifiedName(Arg);
+      if (PrintArg) OS << ")";
+      return;
+    } else if (Arg->isSubClassOf("RegisterClass")) {
+      // If this is a symbolic register class reference, we must be using a
+      // named value.
+      if (NameVar.empty()) P->error("Did not specify WHICH register to pass!");
+      if (Arg != ArgDecl) P->error("Instruction pattern mismatch!");
+
+      if (PrintArg) OS << ".addReg(";
+      OS << NameVar;
+      if (PrintArg) OS << ")";
+      return;
+    }
+    P->error("Unknown operand type '" + Arg->getName() + "' to expander!");
+  }
+  P->error("Unknown operand type to expander!");
+}
+
+static std::string getArgName(Pattern *P, const std::string &ArgName, 
+       const std::vector<std::pair<TreePatternNode*, std::string> > &Operands) {
+  assert(P->getNumArgs() == Operands.size() &&"Argument computation mismatch!");
+  if (ArgName.empty()) return "";
+
+  for (unsigned i = 0, e = P->getNumArgs(); i != e; ++i)
+    if (P->getArgName(i) == ArgName)
+      return Operands[i].second + "->Val";
+  P->error("Pattern does not define a value named $" + ArgName + "!");
+  return "";
+}
+
+
 void InstrSelectorEmitter::run(std::ostream &OS) {
   // Type-check all of the node types to ensure we "understand" them.
   ReadNodeTypes();
@@ -1074,6 +1143,7 @@ void InstrSelectorEmitter::run(std::ostream &OS) {
         // pattern that this is...
         switch (P->getPatternType()) {
         case Pattern::Instruction:
+          // Instruction patterns just emit a single MachineInstr, using BuildMI
           OS << "    BuildMI(MBB, " << Target.getName() << "::"
              << P->getRecord()->getName() << ", " << Operands.size();
           if (P->getResult()) OS << ", NewReg";
@@ -1089,10 +1159,49 @@ void InstrSelectorEmitter::run(std::ostream &OS) {
               OS << ".addZImm(" << Operands[i].second << "->Val)";
             }
           OS << ";\n";
-
           break;
-        case Pattern::Expander:
+        case Pattern::Expander: {
+          // Expander patterns emit one machine instr for each instruction in
+          // the list of instructions expanded to.
+          ListInit *Insts = P->getRecord()->getValueAsListInit("Result");
+          for (unsigned IN = 0, e = Insts->getSize(); IN != e; ++IN) {
+            DagInit *DIInst = dynamic_cast<DagInit*>(Insts->getElement(IN));
+            if (!DIInst) P->error("Result list must contain instructions!");
+            Pattern *InstPat = getPattern(DIInst->getNodeType());
+            if (!InstPat || InstPat->getPatternType() != Pattern::Instruction)
+              P->error("Instruction list must contain Instruction patterns!");
+            
+            bool hasResult = InstPat->getResult() != 0;
+            if (InstPat->getNumArgs() != DIInst->getNumArgs()-hasResult) {
+              P->error("Incorrect number of arguments specified for inst '" +
+                       InstPat->getRecord()->getName() + "' in result list!");
+            }
+
+            // Start emission of the instruction...
+            OS << "    BuildMI(MBB, " << Target.getName() << "::"
+               << InstPat->getRecord()->getName() << ", "
+               << DIInst->getNumArgs()-hasResult;
+            // Emit register result if necessary..
+            if (Record *R = InstPat->getResult()) {
+              std::string ArgNameVal =
+                getArgName(P, DIInst->getArgName(0), Operands);
+              PrintExpanderOperand(DIInst->getArg(0), ArgNameVal,
+                                   R, P, false, OS << ", ");
+            }
+            OS << ")";
+
+            for (unsigned i = hasResult, e = DIInst->getNumArgs(); i != e; ++i){
+              std::string ArgNameVal =
+                getArgName(P, DIInst->getArgName(i), Operands);
+
+              PrintExpanderOperand(DIInst->getArg(i), ArgNameVal,
+                                  InstPat->getArgRec(i-hasResult), P, true, OS);
+            }
+
+            OS << ";\n";
+          }
           break;
+        }
         default:
           assert(0 && "Reduction of this type of pattern not implemented!");
         }
index ec0231ad12c2cde8c038dfd87cee722b3d65d1bd..20e800bf73959d9fc1f78d8c43c03f2e4e21db59 100644 (file)
@@ -57,13 +57,14 @@ class TreePatternNode {
 
   /// Children - If this is not a leaf (Operator != 0), this is the subtrees
   /// that we contain.
-  std::vector<TreePatternNode*> Children;
+  std::vector<std::pair<TreePatternNode*, std::string> > Children;
 
   /// Value - If this node is a leaf, this indicates what the thing is.
   ///
   Init *Value;
 public:
-  TreePatternNode(Record *o, const std::vector<TreePatternNode*> &c)
+  TreePatternNode(Record *o, const std::vector<std::pair<TreePatternNode*,
+                                                         std::string> > &c)
     : Operator(o), Type(MVT::Other), Children(c), Value(0) {}
   TreePatternNode(Init *V) : Operator(0), Type(MVT::Other), Value(V) {}
 
@@ -76,14 +77,16 @@ public:
 
   bool isLeaf() const { return Operator == 0; }
 
-  const std::vector<TreePatternNode*> &getChildren() const {
-    assert(Operator != 0 && "This is a leaf node!");
-    return Children;
-  }
   unsigned getNumChildren() const { return Children.size(); }
   TreePatternNode *getChild(unsigned c) const {
+    assert(Operator != 0 && "This is a leaf node!");
     assert(c < Children.size() && "Child access out of range!");
-    return getChildren()[c];
+    return Children[c].first;
+  }
+  const std::string &getChildName(unsigned c) const {
+    assert(Operator != 0 && "This is a leaf node!");
+    assert(c < Children.size() && "Child access out of range!");
+    return Children[c].second;
   }
 
   Init *getValue() const {
@@ -151,6 +154,10 @@ private:
   ///
   bool Resolved;
 
+  /// Args - This is a list of all of the arguments to this pattern, which are
+  /// the non-void leaf nodes in this pattern.
+  std::vector<std::pair<TreePatternNode*, std::string> > Args;
+
   /// ISE - the instruction selector emitter coordinating this madness.
   ///
   InstrSelectorEmitter &ISE;
@@ -164,7 +171,9 @@ public:
   /// Pattern - Constructor used for cloning nonterminal patterns
   Pattern(TreePatternNode *tree, Record *rec, bool res,
           InstrSelectorEmitter &ise) : PTy(Nonterminal), Tree(tree), Result(0),
-                                       TheRecord(rec), Resolved(res), ISE(ise){}
+                                       TheRecord(rec), Resolved(res), ISE(ise) {
+    calculateArgs(Tree, "");
+  }
 
   /// getPatternType - Return what flavor of Record this pattern originated from
   ///
@@ -181,6 +190,19 @@ public:
   ///
   Record *getRecord() const { return TheRecord; }
 
+  unsigned getNumArgs() const { return Args.size(); }
+  TreePatternNode *getArg(unsigned i) const {
+    assert(i < Args.size() && "Argument reference out of range!");
+    return Args[i].first;
+  }
+  Record *getArgRec(unsigned i) const {
+    return getArg(i)->getValueRecord();
+  }
+  const std::string &getArgName(unsigned i) const {
+    assert(i < Args.size() && "Argument reference out of range!");
+    return Args[i].second;
+  }
+
   bool isResolved() const { return Resolved; }
 
   /// InferAllTypes - Runs the type inference engine on the current pattern,
@@ -211,6 +233,7 @@ public:
   void dump() const;
 
 private:
+  void calculateArgs(TreePatternNode *N, const std::string &Name);
   MVT::ValueType getIntrinsicType(Record *R) const;
   TreePatternNode *ParseTreePattern(DagInit *DI);
   bool InferTypes(TreePatternNode *N, bool &MadeChange);
@@ -338,6 +361,16 @@ private:
   void EmitMatchCosters(std::ostream &OS,
             const std::vector<std::pair<Pattern*, TreePatternNode*> > &Patterns,
                         const std::string &VarPrefix, unsigned Indent);
+  
+  /// PrintExpanderOperand - Print out Arg as part of the instruction emission
+  /// process for the expander pattern P.  This argument may be referencing some
+  /// values defined in P, or may just be physical register references or
+  /// something like that.  If PrintArg is true, we are printing out arguments
+  /// to the BuildMI call.  If it is false, we are printing the result register
+  /// name.
+  void PrintExpanderOperand(Init *Arg, const std::string &NameVar,
+                            Record *ArgDecl, Pattern *P,
+                            bool PrintArg, std::ostream &OS);
 };
 
 #endif