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

Chris Lattner lattner at cs.uiuc.edu
Thu Sep 15 15:24:01 PDT 2005



Changes in directory llvm/utils/TableGen:

DAGISelEmitter.cpp updated: 1.31 -> 1.32
DAGISelEmitter.h updated: 1.19 -> 1.20
---
Log message:

teach the type inference code how to infer types for instructions and node
xforms.  Run type inference on result patterns, so we always have fully typed
results (and to catch errors in .td files).


---
Diffs of the changes:  (+66 -33)

 DAGISelEmitter.cpp |   86 +++++++++++++++++++++++++++++++++++------------------
 DAGISelEmitter.h   |   13 ++++----
 2 files changed, 66 insertions(+), 33 deletions(-)


Index: llvm/utils/TableGen/DAGISelEmitter.cpp
diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.31 llvm/utils/TableGen/DAGISelEmitter.cpp:1.32
--- llvm/utils/TableGen/DAGISelEmitter.cpp:1.31	Thu Sep 15 16:57:35 2005
+++ llvm/utils/TableGen/DAGISelEmitter.cpp	Thu Sep 15 17:23:50 2005
@@ -324,14 +324,34 @@
     for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
       MadeChange |= getChild(i)->ApplyTypeConstraints(TP);
     return MadeChange;  
-  } else {
-    assert(getOperator()->isSubClassOf("Instruction") && "Unknown node type!");
-    
+  } else if (getOperator()->isSubClassOf("Instruction")) {
     const DAGInstruction &Inst =
       TP.getDAGISelEmitter().getInstruction(getOperator());
     
-    // TODO: type inference for instructions.
-    return false;
+    assert(Inst.getNumResults() == 1 && "Only supports one result instrs!");
+    // Apply the result type to the node
+    bool MadeChange = UpdateNodeType(Inst.getResultType(0), TP);
+
+    if (getNumChildren() != Inst.getNumOperands())
+      TP.error("Instruction '" + getOperator()->getName() + " expects " +
+               utostr(Inst.getNumOperands()) + " operands, not " +
+               utostr(getNumChildren()) + " operands!");
+    for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
+      MadeChange |= getChild(i)->UpdateNodeType(Inst.getOperandType(i), TP);
+      MadeChange |= getChild(i)->ApplyTypeConstraints(TP);
+    }
+    return MadeChange;
+  } else {
+    assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!");
+    
+    // Node transforms always take one operand, and take and return the same
+    // type.
+    if (getNumChildren() != 1)
+      TP.error("Node transform '" + getOperator()->getName() +
+               "' requires one operand!");
+    bool MadeChange = UpdateNodeType(getChild(0)->getType(), TP);
+    MadeChange |= getChild(0)->UpdateNodeType(getType(), TP);
+    return MadeChange;
   }
 }
 
@@ -340,13 +360,24 @@
 // TreePattern implementation
 //
 
-TreePattern::TreePattern(Record *TheRec, const std::vector<DagInit *> &RawPat,
+TreePattern::TreePattern(Record *TheRec, ListInit *RawPat,
+                         DAGISelEmitter &ise) : TheRecord(TheRec), ISE(ise) {
+   for (unsigned i = 0, e = RawPat->getSize(); i != e; ++i)
+     Trees.push_back(ParseTreePattern((DagInit*)RawPat->getElement(i)));
+}
+
+TreePattern::TreePattern(Record *TheRec, DagInit *Pat,
                          DAGISelEmitter &ise) : TheRecord(TheRec), ISE(ise) {
+  Trees.push_back(ParseTreePattern(Pat));
+}
 
-  for (unsigned i = 0, e = RawPat.size(); i != e; ++i)
-    Trees.push_back(ParseTreePattern(RawPat[i]));
+TreePattern::TreePattern(Record *TheRec, TreePatternNode *Pat, 
+                         DAGISelEmitter &ise) : TheRecord(TheRec), ISE(ise) {
+  Trees.push_back(Pat);
 }
 
+
+
 void TreePattern::error(const std::string &Msg) const {
   dump();
   throw "In " + TheRecord->getName() + ": " + Msg;
@@ -550,9 +581,8 @@
   // 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(Fragments[i], Trees, *this);
+    DagInit *Tree = Fragments[i]->getValueAsDag("Fragment");
+    TreePattern *P = new TreePattern(Fragments[i], Tree, *this);
     PatternFragments[Fragments[i]] = P;
     
     // Validate the argument list, converting it to map, to discard duplicates.
@@ -762,12 +792,8 @@
     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.
-    TreePattern *I = new TreePattern(Instrs[i], Trees, *this);
+    TreePattern *I = new TreePattern(Instrs[i], LI, *this);
     // Inline pattern fragments into it.
     I->InlinePatternFragments();
     
@@ -876,11 +902,21 @@
 
     TreePatternNode *ResultPattern =
       new TreePatternNode(I->getRecord(), ResultNodeOperands);
+
+    // Create and insert the instruction.
+    DAGInstruction TheInst(I, ResultTypes, OperandTypes);
+    Instructions.insert(std::make_pair(I->getRecord(), TheInst));
+
+    // 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);
+    Temp.InferAllTypes();
+
+    DAGInstruction &TheInsertedInst = Instructions.find(I->getRecord())->second;
+    TheInsertedInst.setResultPattern(Temp.getOnlyTree());
     
     DEBUG(I->dump());
-    Instructions.insert(std::make_pair(I->getRecord(),
-                                       DAGInstruction(I, ResultTypes,
-                                                OperandTypes, ResultPattern)));
   }
    
   // If we can, convert the instructions to be patterns that are matched!
@@ -909,10 +945,8 @@
   std::vector<Record*> Patterns = Records.getAllDerivedDefinitions("Pattern");
 
   for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
-    std::vector<DagInit*> Trees;
-    Trees.push_back(Patterns[i]->getValueAsDag("PatternToMatch"));
-    TreePattern *Pattern = new TreePattern(Patterns[i], Trees, *this);
-    Trees.clear();
+    DagInit *Tree = Patterns[i]->getValueAsDag("PatternToMatch");
+    TreePattern *Pattern = new TreePattern(Patterns[i], Tree, *this);
 
     // Inline pattern fragments into it.
     Pattern->InlinePatternFragments();
@@ -924,21 +958,17 @@
     
     ListInit *LI = Patterns[i]->getValueAsListInit("ResultInstrs");
     if (LI->getSize() == 0) continue;  // no pattern.
-    for (unsigned j = 0, e = LI->getSize(); j != e; ++j)
-      Trees.push_back((DagInit*)LI->getElement(j));
     
     // Parse the instruction.
-    TreePattern *Result = new TreePattern(Patterns[i], Trees, *this);
+    TreePattern *Result = new TreePattern(Patterns[i], LI, *this);
     
     // Inline pattern fragments into it.
     Result->InlinePatternFragments();
     
     // Infer as many types as possible.  If we cannot infer all of them, we can
     // never do anything with this pattern: report it to the user.
-#if 0  // FIXME: ENABLE when we can infer though instructions!
     if (!Result->InferAllTypes())
       Result->error("Could not infer all types in pattern result!");
-#endif
    
     if (Result->getNumTrees() != 1)
       Result->error("Cannot handle instructions producing instructions "


Index: llvm/utils/TableGen/DAGISelEmitter.h
diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.19 llvm/utils/TableGen/DAGISelEmitter.h:1.20
--- llvm/utils/TableGen/DAGISelEmitter.h:1.19	Thu Sep 15 16:57:35 2005
+++ llvm/utils/TableGen/DAGISelEmitter.h	Thu Sep 15 17:23:50 2005
@@ -20,6 +20,7 @@
 namespace llvm {
   class Record;
   struct Init;
+  class ListInit;
   class DagInit;
   class SDNodeInfo;
   class TreePattern;
@@ -222,8 +223,9 @@
       
     /// TreePattern constructor - Parse the specified DagInits into the
     /// current record.
-    TreePattern(Record *TheRec,
-                const std::vector<DagInit *> &RawPat, DAGISelEmitter &ise);
+    TreePattern(Record *TheRec, ListInit *RawPat, DAGISelEmitter &ise);
+    TreePattern(Record *TheRec, DagInit *Pat, DAGISelEmitter &ise);
+    TreePattern(Record *TheRec, TreePatternNode *Pat, DAGISelEmitter &ise);
         
     /// getTrees - Return the tree patterns which corresponds to this pattern.
     ///
@@ -285,15 +287,16 @@
   public:
     DAGInstruction(TreePattern *TP,
                    const std::vector<MVT::ValueType> &resultTypes,
-                   const std::vector<MVT::ValueType> &operandTypes,
-                   TreePatternNode *resultPattern)
+                   const std::vector<MVT::ValueType> &operandTypes)
       : Pattern(TP), ResultTypes(resultTypes), OperandTypes(operandTypes), 
-        ResultPattern(resultPattern) {}
+        ResultPattern(0) {}
 
     TreePattern *getPattern() const { return Pattern; }
     unsigned getNumResults() const { return ResultTypes.size(); }
     unsigned getNumOperands() const { return OperandTypes.size(); }
     
+    void setResultPattern(TreePatternNode *R) { ResultPattern = R; }
+    
     MVT::ValueType getResultType(unsigned RN) const {
       assert(RN < ResultTypes.size());
       return ResultTypes[RN];






More information about the llvm-commits mailing list