[llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h

Chris Lattner lattner at cs.uiuc.edu
Wed Sep 7 16:44:54 PDT 2005



Changes in directory llvm/utils/TableGen:

DAGISelEmitter.cpp added (r1.1)
DAGISelEmitter.h updated: 1.1 -> 1.2
---
Log message:

Initial cut of the dag isel generator.  This is still very much a work in
progress.  It correctly parses instructions and pattern fragments and glues
together pattern fragments into instructions.

The only code it generates currently is some boilerplate code for things
like the EntryNode.



---
Diffs of the changes:  (+643 -1)

 DAGISelEmitter.cpp |  475 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 DAGISelEmitter.h   |  169 ++++++++++++++++++
 2 files changed, 643 insertions(+), 1 deletion(-)


Index: llvm/utils/TableGen/DAGISelEmitter.cpp
diff -c /dev/null llvm/utils/TableGen/DAGISelEmitter.cpp:1.1
*** /dev/null	Wed Sep  7 18:44:53 2005
--- llvm/utils/TableGen/DAGISelEmitter.cpp	Wed Sep  7 18:44:43 2005
***************
*** 0 ****
--- 1,475 ----
+ //===- DAGISelEmitter.cpp - Generate an instruction selector --------------===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Chris Lattner and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This tablegen backend emits a DAG instruction selector.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "DAGISelEmitter.h"
+ #include "Record.h"
+ #include "llvm/ADT/StringExtras.h"
+ #include "llvm/Support/Debug.h"
+ #include <set>
+ using namespace llvm;
+ 
+ 
+ //===----------------------------------------------------------------------===//
+ // TreePatternNode implementation
+ //
+ 
+ TreePatternNode::~TreePatternNode() {
+ #if 0 // FIXME: implement refcounted tree nodes!
+   for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+     delete getChild(i);
+ #endif
+ }
+ 
+ void TreePatternNode::print(std::ostream &OS) const {
+   if (isLeaf()) {
+     OS << *getLeafValue();
+   } else {
+     OS << "(" << getOperator()->getName();
+   }
+   
+   if (getType() == MVT::Other)
+     OS << ":Other";
+   else if (getType() == MVT::LAST_VALUETYPE)
+     ;//OS << ":?";
+   else
+     OS << ":" << getType();
+ 
+   if (!isLeaf()) {
+     if (getNumChildren() != 0) {
+       OS << " ";
+       getChild(0)->print(OS);
+       for (unsigned i = 1, e = getNumChildren(); i != e; ++i) {
+         OS << ", ";
+         getChild(i)->print(OS);
+       }
+     }
+     OS << ")";
+   }
+   
+   if (!PredicateFn.empty())
+     OS << "<<" << PredicateFn << ">>";
+   if (!getName().empty())
+     OS << ":$" << getName();
+ 
+ }
+ void TreePatternNode::dump() const {
+   print(std::cerr);
+ }
+ 
+ /// clone - Make a copy of this tree and all of its children.
+ ///
+ TreePatternNode *TreePatternNode::clone() const {
+   TreePatternNode *New;
+   if (isLeaf()) {
+     New = new TreePatternNode(getLeafValue());
+   } else {
+     std::vector<TreePatternNode*> CChildren;
+     CChildren.reserve(Children.size());
+     for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+       CChildren.push_back(getChild(i)->clone());
+     New = new TreePatternNode(getOperator(), CChildren);
+   }
+   New->setName(getName());
+   New->setType(getType());
+   New->setPredicateFn(getPredicateFn());
+   return New;
+ }
+ 
+ void TreePatternNode::
+ SubstituteFormalArguments(std::map<std::string, TreePatternNode*> &ArgMap) {
+   if (isLeaf()) return;
+   
+   for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
+     TreePatternNode *Child = getChild(i);
+     if (Child->isLeaf()) {
+       Init *Val = Child->getLeafValue();
+       if (dynamic_cast<DefInit*>(Val) &&
+           static_cast<DefInit*>(Val)->getDef()->getName() == "node") {
+         // We found a use of a formal argument, replace it with its value.
+         Child = ArgMap[Child->getName()];
+         assert(Child && "Couldn't find formal argument!");
+         setChild(i, Child);
+       }
+     } else {
+       getChild(i)->SubstituteFormalArguments(ArgMap);
+     }
+   }
+ }
+ 
+ 
+ /// InlinePatternFragments - If this pattern refers to any pattern
+ /// fragments, inline them into place, giving us a pattern without any
+ /// PatFrag references.
+ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) {
+   if (isLeaf()) return this;  // nothing to do.
+   Record *Op = getOperator();
+   
+   if (!Op->isSubClassOf("PatFrag")) {
+     // Just recursively inline children nodes.
+     for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+       setChild(i, getChild(i)->InlinePatternFragments(TP));
+     return this;
+   }
+ 
+   // Otherwise, we found a reference to a fragment.  First, look up its
+   // TreePattern record.
+   TreePattern *Frag = TP.getDAGISelEmitter().getPatternFragment(Op);
+   
+   // Verify that we are passing the right number of operands.
+   if (Frag->getNumArgs() != Children.size())
+     TP.error("'" + Op->getName() + "' fragment requires " +
+              utostr(Frag->getNumArgs()) + " operands!");
+ 
+   TreePatternNode *FragTree = Frag->getTrees()[0]->clone();
+ 
+   // Resolve formal arguments to their actual value.
+   if (Frag->getNumArgs()) {
+     // Compute the map of formal to actual arguments.
+     std::map<std::string, TreePatternNode*> ArgMap;
+     for (unsigned i = 0, e = Frag->getNumArgs(); i != e; ++i)
+       ArgMap[Frag->getArgName(i)] = getChild(i)->InlinePatternFragments(TP);
+   
+     FragTree->SubstituteFormalArguments(ArgMap);
+   }
+   
+   // Get a new copy of this fragment to stitch into here.
+   //delete this;    // FIXME: implement refcounting!
+   return FragTree;
+ }
+ 
+ //===----------------------------------------------------------------------===//
+ // TreePattern implementation
+ //
+ 
+ TreePattern::TreePattern(PatternType pty, Record *TheRec,
+                          const std::vector<DagInit *> &RawPat,
+                          DAGISelEmitter &ise)
+   : PTy(pty), TheRecord(TheRec), ISE(ise) {
+ 
+   for (unsigned i = 0, e = RawPat.size(); i != e; ++i)
+     Trees.push_back(ParseTreePattern(RawPat[i]));
+   
+   // Sanity checks and cleanup.
+   switch (PTy) {
+   case PatFrag: {
+     assert(Trees.size() == 1 && "How can we have more than one pattern here?");
+     
+     // Validate arguments list, convert it to map, to discard duplicates.
+     std::set<std::string> OperandsMap(Args.begin(), Args.end());
+ 
+     if (OperandsMap.count(""))
+       error("Cannot have unnamed 'node' values in pattern fragment!");
+       
+     // Parse the operands list.
+     DagInit *OpsList = TheRec->getValueAsDag("Operands");
+     if (OpsList->getNodeType()->getName() != "ops")
+       error("Operands list should start with '(ops ... '!");
+     
+     // Copy over the arguments.       
+     Args.clear();
+     for (unsigned i = 0, e = OpsList->getNumArgs(); i != e; ++i) {
+       if (!dynamic_cast<DefInit*>(OpsList->getArg(i)) ||
+           static_cast<DefInit*>(OpsList->getArg(i))->
+                           getDef()->getName() != "node")
+         error("Operands list should all be 'node' values.");
+       if (OpsList->getArgName(i).empty())
+         error("Operands list should have names for each operand!");
+       if (!OperandsMap.count(OpsList->getArgName(i)))
+         error("'" + OpsList->getArgName(i) +
+               "' does not occur in pattern or was multiply specified!");
+       OperandsMap.erase(OpsList->getArgName(i));
+       Args.push_back(OpsList->getArgName(i));
+     }
+     
+     if (!OperandsMap.empty())
+       error("Operands list does not contain an entry for operand '" +
+             *OperandsMap.begin() + "'!");
+     
+     break;
+   }
+   default:
+     if (!Args.empty())
+       error("Only pattern fragments can have operands (use 'node' values)!");
+     break;
+   }
+ }
+ 
+ void TreePattern::error(const std::string &Msg) const {
+   std::string M = "In ";
+   switch (PTy) {
+     case PatFrag:     M += "patfrag "; break;
+     case Instruction: M += "instruction "; break;
+   }
+   throw M + TheRecord->getName() + ": " + Msg;
+ }
+ 
+ /// 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.
+ ///
+ MVT::ValueType TreePattern::getIntrinsicType(Record *R) const {
+   // Check to see if this is a register or a register class...
+   if (R->isSubClassOf("RegisterClass"))
+     return getValueType(R->getValueAsDef("RegType"));
+   else if (R->isSubClassOf("PatFrag")) {
+     //return ISE.ReadNonterminal(R)->getTree()->getType();
+     return MVT::LAST_VALUETYPE;
+   } else if (R->isSubClassOf("Register")) {
+     assert(0 && "Explicit registers not handled here yet!\n");
+     return MVT::LAST_VALUETYPE;
+   } else if (R->isSubClassOf("ValueType")) {
+     // Using a VTSDNode.
+     return MVT::Other;
+   } else if (R->getName() == "node") {
+     // Placeholder.
+     return MVT::LAST_VALUETYPE;
+   }
+   
+   error("Unknown value used: " + R->getName());
+   return MVT::Other;
+ }
+ 
+ TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) {
+   Record *Operator = Dag->getNodeType();
+   
+   if (Operator->isSubClassOf("ValueType")) {
+     // If the operator is a ValueType, then this must be "type cast" of a leaf
+     // node.
+     if (Dag->getNumArgs() != 1)
+       error("Type cast only valid for a leaf node!");
+     
+     Init *Arg = Dag->getArg(0);
+     TreePatternNode *New;
+     if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
+       New = new TreePatternNode(DI);
+       // If it's a regclass or something else known, set the type.
+       New->setType(getIntrinsicType(DI->getDef()));
+     } else if (DagInit *DI = dynamic_cast<DagInit*>(Arg)) {
+       New = ParseTreePattern(DI);
+     } else {
+       Arg->dump();
+       error("Unknown leaf value for tree pattern!");
+       return 0;
+     }
+     
+     // Apply the type cast...
+     assert(0 && "unimp yet");
+     //New->updateNodeType(getValueType(Operator), TheRecord->getName());
+     return New;
+   }
+   
+   // Verify that this is something that makes sense for an operator.
+   if (!Operator->isSubClassOf("PatFrag") && !Operator->isSubClassOf("SDNode") &&
+       Operator->getName() != "set")
+     error("Unrecognized node '" + Operator->getName() + "'!");
+   
+   std::vector<TreePatternNode*> 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.back()->setName(Dag->getArgName(i));
+     } else if (DefInit *DefI = dynamic_cast<DefInit*>(Arg)) {
+       Record *R = DefI->getDef();
+       // Direct reference to a leaf DagNode or PatFrag?  Turn it into a
+       // TreePatternNode if its own.
+       if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrag")) {
+         Dag->setArg(i, new DagInit(R,
+                               std::vector<std::pair<Init*, std::string> >()));
+         --i;  // Revisit this node...
+       } else {
+         TreePatternNode *Node = new TreePatternNode(DefI);
+         Node->setName(Dag->getArgName(i));
+         Children.push_back(Node);
+         
+         // If it's a regclass or something else known, set the type.
+         Node->setType(getIntrinsicType(R));
+         
+         // Input argument?
+         if (R->getName() == "node") {
+           if (Dag->getArgName(i).empty())
+             error("'node' argument requires a name to match with operand list");
+           Args.push_back(Dag->getArgName(i));
+         }
+       }
+     } else {
+       Arg->dump();
+       error("Unknown leaf value for tree pattern!");
+     }
+   }
+   
+   return new TreePatternNode(Operator, Children);
+ }
+ 
+ void TreePattern::print(std::ostream &OS) const {
+   switch (getPatternType()) {
+   case TreePattern::PatFrag:     OS << "PatFrag pattern "; break;
+   case TreePattern::Instruction: OS << "Inst pattern "; break;
+   }
+   
+   OS << getRecord()->getName();
+   if (!Args.empty()) {
+     OS << "(" << Args[0];
+     for (unsigned i = 1, e = Args.size(); i != e; ++i)
+       OS << ", " << Args[i];
+     OS << ")";
+   }
+   OS << ": ";
+   
+   if (Trees.size() > 1)
+     OS << "[\n";
+   for (unsigned i = 0, e = Trees.size(); i != e; ++i) {
+     OS << "\t";
+     Trees[i]->print(OS);
+     OS << "\n";
+   }
+ 
+   if (Trees.size() > 1)
+     OS << "]\n";
+ }
+ 
+ void TreePattern::dump() const { print(std::cerr); }
+ 
+ 
+ 
+ //===----------------------------------------------------------------------===//
+ // DAGISelEmitter implementation
+ //
+ 
+ /// ParseAndResolvePatternFragments - Parse all of the PatFrag definitions in
+ /// the .td file, building up the PatternFragments map.  After we've collected
+ /// them all, inline fragments together as necessary, so that there are no
+ /// references left inside a pattern fragment to a pattern fragment.
+ ///
+ /// This also emits all of the predicate functions to the output file.
+ ///
+ void DAGISelEmitter::ParseAndResolvePatternFragments(std::ostream &OS) {
+   std::vector<Record*> Fragments = Records.getAllDerivedDefinitions("PatFrag");
+   
+   // First step, parse all of the fragments and emit predicate functions.
+   OS << "\n// Predicate functions.\n";
+   for (unsigned i = 0, e = Fragments.size(); i != e; ++i) {
+     std::vector<DagInit*> Trees;
+     Trees.push_back(Fragments[i]->getValueAsDag("Fragment"));
+     TreePattern *P = new TreePattern(TreePattern::PatFrag, Fragments[i],
+                                      Trees, *this);
+     PatternFragments[Fragments[i]] = P;
+ 
+     // If there is a code init for this fragment, emit the predicate code and
+     // keep track of the fact that this fragment uses it.
+     CodeInit *CI =
+       dynamic_cast<CodeInit*>(Fragments[i]->getValueInit("Predicate"));
+     if (!CI->getValue().empty()) {
+       assert(!P->getTrees()[0]->isLeaf() && "Can't be a leaf!");
+       std::string ClassName =
+           P->getTrees()[0]->getOperator()->getValueAsString("SDClass");
+       const char *C2 = ClassName == "SDNode" ? "N" : "inN";
+       
+       OS << "static inline bool Predicate_" << Fragments[i]->getName()
+          << "(SDNode *" << C2 << ") {\n";
+       if (ClassName != "SDNode")
+         OS << "  " << ClassName << " *N = cast<" << ClassName << ">(inN);\n";
+       OS << CI->getValue() << "\n}\n";
+       P->getTrees()[0]->setPredicateFn("Predicate_"+Fragments[i]->getName());
+     }
+   }
+   
+   OS << "\n\n";
+ 
+   // Now that we've parsed all of the tree fragments, do a closure on them so
+   // that there are not references to PatFrags left inside of them.
+   for (std::map<Record*, TreePattern*>::iterator I = PatternFragments.begin(),
+        E = PatternFragments.end(); I != E; ++I) {
+     I->second->InlinePatternFragments();
+     // If debugging, print out the pattern fragment result.
+     DEBUG(I->second->dump());
+   }
+ }
+ 
+ /// ParseAndResolveInstructions - Parse all of the instructions, inlining and
+ /// resolving any fragments involved.  This populates the Instructions list with
+ /// fully resolved instructions.
+ void DAGISelEmitter::ParseAndResolveInstructions() {
+   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 = Instrs[i]->getValueAsListInit("Pattern");
+     if (LI->getSize() == 0) continue;  // no pattern.
+     
+     std::vector<DagInit*> Trees;
+     for (unsigned j = 0, e = LI->getSize(); j != e; ++j)
+       Trees.push_back((DagInit*)LI->getElement(j));
+ 
+     // Parse the instruction.
+     Instructions.push_back(new TreePattern(TreePattern::Instruction, Instrs[i],
+                                            Trees, *this));
+     // Inline pattern fragments into it.
+     Instructions.back()->InlinePatternFragments();
+     
+     DEBUG(std::cerr << Instrs[i]->getName() << ": ");
+     DEBUG(Instructions.back()->dump());
+   }
+ }
+ 
+ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
+   // Emit boilerplate.
+   OS << "// The main instruction selector code.\n"
+      << "SDOperand " << Target.getName()
+      << "DAGToDAGISel::SelectCode(SDOperand Op) {\n"
+      << "  SDNode *N = Op.Val;\n"
+      << "  if (N->getOpcode() >= ISD::BUILTIN_OP_END &&\n"
+      << "      N->getOpcode() < PPCISD::FIRST_NUMBER)\n"
+      << "    return Op;   // Already selected.\n\n"
+      << "  switch (N->getOpcode()) {\n"
+      << "  default: break;\n"
+      << "  case ISD::EntryToken:       // These leaves remain the same.\n"
+      << "    return Op;\n"
+      << "  case ISD::AssertSext:\n"
+      << "  case ISD::AssertZext:\n"
+      << "    return Select(N->getOperand(0));\n";
+     
+ 
+   
+   OS << "  } // end of big switch.\n\n"
+      << "  std::cerr << \"Cannot yet select: \";\n"
+      << "  N->dump();\n"
+      << "  std::cerr << '\\n';\n"
+      << "  abort();\n"
+      << "}\n";
+ }
+ 
+ 
+ void DAGISelEmitter::run(std::ostream &OS) {
+   EmitSourceFileHeader("DAG Instruction Selector for the " + Target.getName() +
+                        " target", OS);
+   
+   ParseAndResolvePatternFragments(OS);
+   ParseAndResolveInstructions();
+   
+   // TODO: convert some instructions to expanders if needed or something.
+   
+   EmitInstructionSelector(OS);  
+   
+   for (std::map<Record*, TreePattern*>::iterator I = PatternFragments.begin(),
+        E = PatternFragments.end(); I != E; ++I)
+     delete I->second;
+   PatternFragments.clear();
+ 
+   for (unsigned i = 0, e = Instructions.size(); i != e; ++i)
+     delete Instructions[i];
+   Instructions.clear();
+ }


Index: llvm/utils/TableGen/DAGISelEmitter.h
diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.1 llvm/utils/TableGen/DAGISelEmitter.h:1.2
--- llvm/utils/TableGen/DAGISelEmitter.h:1.1	Fri Sep  2 20:14:03 2005
+++ llvm/utils/TableGen/DAGISelEmitter.h	Wed Sep  7 18:44:43 2005
@@ -18,7 +18,162 @@
 #include "CodeGenTarget.h"
 
 namespace llvm {
+  class Record;
+  class Init;
+  class DagInit;
+  class TreePattern;
+  class DAGISelEmitter;
 
+  /// FIXME: TreePatternNode's can be shared in some cases (due to dag-shaped
+  /// patterns), and as such should be ref counted.  We currently just leak all
+  /// TreePatternNode objects!
+  class TreePatternNode {
+    /// The inferred type for this node, or MVT::LAST_VALUETYPE if it hasn't
+    /// been determined yet.
+    MVT::ValueType Ty;
+
+    /// Operator - The Record for the operator if this is an interior node (not
+    /// a leaf).
+    Record *Operator;
+    
+    /// Val - The init value (e.g. the "GPRC" record, or "7") for a leaf.
+    ///
+    Init *Val;
+    
+    /// Name - The name given to this node with the :$foo notation.
+    ///
+    std::string Name;
+    
+    /// PredicateFn - The predicate function to execute on this node to check
+    /// for a match.  If this string is empty, no predicate is involved.
+    std::string PredicateFn;
+    
+    std::vector<TreePatternNode*> Children;
+  public:
+    TreePatternNode(Record *Op, const std::vector<TreePatternNode*> &Ch) 
+      : Ty(MVT::LAST_VALUETYPE), Operator(Op), Val(0), Children(Ch) {}
+    TreePatternNode(Init *val)    // leaf ctor
+      : Ty(MVT::LAST_VALUETYPE), Operator(0), Val(val) {}
+    ~TreePatternNode();
+    
+    const std::string &getName() const { return Name; }
+    void setName(const std::string &N) { Name = N; }
+    
+    bool isLeaf() const { return Val != 0; }
+    MVT::ValueType getType() const { return Ty; }
+    void setType(MVT::ValueType VT) { Ty = VT; }
+    
+    Init *getLeafValue() const { assert(isLeaf()); return Val; }
+    Record *getOperator() const { assert(!isLeaf()); return Operator; }
+    
+    unsigned getNumChildren() const { return Children.size(); }
+    TreePatternNode *getChild(unsigned N) const { return Children[N]; }
+    void setChild(unsigned i, TreePatternNode *N) {
+      Children[i] = N;
+    }
+    
+    const std::string &getPredicateFn() const { return PredicateFn; }
+    void setPredicateFn(const std::string &Fn) { PredicateFn = Fn; }
+    
+    void print(std::ostream &OS) const;
+    void dump() const;
+    
+  public:   // Higher level manipulation routines.
+
+    /// clone - Return a new copy of this tree.
+    ///
+    TreePatternNode *clone() const;
+    
+    void SubstituteFormalArguments(std::map<std::string,
+                                            TreePatternNode*> &ArgMap);
+
+    /// InlinePatternFragments - If this pattern refers to any pattern
+    /// fragments, inline them into place, giving us a pattern without any
+    /// PatFrag references.
+    TreePatternNode *InlinePatternFragments(TreePattern &TP);
+        
+  };
+  
+  
+  /// TreePattern - Represent a pattern of one form or another.  Currently, two
+  /// types of patterns are possible: Instructions and PatFrags.
+  ///
+  class TreePattern {
+  public:
+    enum PatternType {
+      PatFrag, Instruction
+    };
+  private:
+    /// PTy - The type of pattern this is.
+    ///
+    PatternType PTy;
+    
+    /// Trees - The list of pattern trees which corresponds to this pattern.
+    /// Note that PatFrag's only have a single tree.
+    ///
+    std::vector<TreePatternNode*> Trees;
+    
+    /// TheRecord - The actual TableGen record corresponding to this pattern.
+    ///
+    Record *TheRecord;
+      
+    /// Args - This is a list of all of the arguments to this pattern (for
+    /// PatFrag patterns), which are the 'node' markers in this pattern.
+    std::vector<std::string> Args;
+    
+    /// ISE - the DAG isel emitter coordinating this madness.
+    ///
+    DAGISelEmitter &ISE;
+  public:
+      
+    /// TreePattern constructor - Parse the specified DagInits into the
+    /// current record.
+    TreePattern(PatternType pty, Record *TheRec,
+                const std::vector<DagInit *> &RawPat, DAGISelEmitter &ise);
+        
+    /// getPatternType - Return what flavor of Record this pattern originated from
+    ///
+    PatternType getPatternType() const { return PTy; }
+    
+    /// getTrees - Return the tree patterns which corresponds to this pattern.
+    ///
+    const std::vector<TreePatternNode*> &getTrees() const { return Trees; }
+        
+    /// getRecord - Return the actual TableGen record corresponding to this
+    /// pattern.
+    ///
+    Record *getRecord() const { return TheRecord; }
+    
+    unsigned getNumArgs() const { return Args.size(); }
+    const std::string &getArgName(unsigned i) const {
+      assert(i < Args.size() && "Argument reference out of range!");
+      return Args[i];
+    }
+    
+    DAGISelEmitter &getDAGISelEmitter() const { return ISE; }
+
+    /// InlinePatternFragments - If this pattern refers to any pattern
+    /// fragments, inline them into place, giving us a pattern without any
+    /// PatFrag references.
+    void InlinePatternFragments() {
+      for (unsigned i = 0, e = Trees.size(); i != e; ++i)
+        Trees[i] = Trees[i]->InlinePatternFragments(*this);
+    }
+    
+    /// error - Throw an exception, prefixing it with information about this
+    /// pattern.
+    void error(const std::string &Msg) const;
+    
+    void print(std::ostream &OS) const;
+    void dump() const;
+    
+  private:
+    MVT::ValueType getIntrinsicType(Record *R) const;
+    TreePatternNode *ParseTreePattern(DagInit *DI);
+  };
+  
+  
+  
 /// InstrSelectorEmitter - The top-level class which coordinates construction
 /// and emission of the instruction selector.
 ///
@@ -26,11 +181,23 @@
   RecordKeeper &Records;
   CodeGenTarget Target;
 
+  std::map<Record*, TreePattern*> PatternFragments;
+  std::vector<TreePattern*> Instructions;
 public:
   DAGISelEmitter(RecordKeeper &R) : Records(R) {}
 
   // run - Output the isel, returning true on failure.
-  void run(std::ostream &OS) {}
+  void run(std::ostream &OS);
+
+  TreePattern *getPatternFragment(Record *R) const {
+    assert(PatternFragments.count(R) && "Invalid pattern fragment request!");
+    return PatternFragments.find(R)->second;
+  }
+  
+private:
+  void ParseAndResolvePatternFragments(std::ostream &OS);
+  void ParseAndResolveInstructions();
+  void EmitInstructionSelector(std::ostream &OS);
 };
 
 } // End llvm namespace






More information about the llvm-commits mailing list