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

Chris Lattner lattner at cs.uiuc.edu
Thu Oct 13 23:12:15 PDT 2005



Changes in directory llvm/utils/TableGen:

DAGISelEmitter.cpp updated: 1.54 -> 1.55
DAGISelEmitter.h updated: 1.31 -> 1.32
---
Log message:

Fairly serious rework of the typing code to add new int/fp lattice values.
Overall, no functionality change yet though.


---
Diffs of the changes:  (+109 -60)

 DAGISelEmitter.cpp |  136 ++++++++++++++++++++++++++++++++---------------------
 DAGISelEmitter.h   |   33 +++++++++---
 2 files changed, 109 insertions(+), 60 deletions(-)


Index: llvm/utils/TableGen/DAGISelEmitter.cpp
diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.54 llvm/utils/TableGen/DAGISelEmitter.cpp:1.55
--- llvm/utils/TableGen/DAGISelEmitter.cpp:1.54	Fri Oct 14 00:08:37 2005
+++ llvm/utils/TableGen/DAGISelEmitter.cpp	Fri Oct 14 01:12:03 2005
@@ -20,6 +20,35 @@
 using namespace llvm;
 
 //===----------------------------------------------------------------------===//
+// Helpers for working with extended types.
+
+/// FilterVTs - Filter a list of VT's according to a predicate.
+///
+template<typename T>
+static std::vector<MVT::ValueType> 
+FilterVTs(const std::vector<MVT::ValueType> &InVTs, T Filter) {
+  std::vector<MVT::ValueType> Result;
+  for (unsigned i = 0, e = InVTs.size(); i != e; ++i)
+    if (Filter(InVTs[i]))
+      Result.push_back(InVTs[i]);
+  return Result;
+}
+
+/// isExtIntegerVT - Return true if the specified extended value type is
+/// integer, or isInt.
+static bool isExtIntegerVT(unsigned char VT) {
+  return VT == MVT::isInt ||
+        (VT < MVT::LAST_VALUETYPE && MVT::isInteger((MVT::ValueType)VT));
+}
+
+/// isExtFloatingPointVT - Return true if the specified extended value type is
+/// floating point, or isFP.
+static bool isExtFloatingPointVT(unsigned char VT) {
+  return VT == MVT::isFP ||
+        (VT < MVT::LAST_VALUETYPE && MVT::isFloatingPoint((MVT::ValueType)VT));
+}
+
+//===----------------------------------------------------------------------===//
 // SDTypeConstraint implementation
 //
 
@@ -63,16 +92,6 @@
     return N->getChild(OpNo-NumResults);
 }
 
-template<typename T>
-static std::vector<MVT::ValueType> 
-FilterVTs(const std::vector<MVT::ValueType> &InVTs, T Filter) {
-  std::vector<MVT::ValueType> Result;
-  for (unsigned i = 0, e = InVTs.size(); i != e; ++i)
-    if (Filter(InVTs[i]))
-      Result.push_back(InVTs[i]);
-  return Result;
-}
-
 /// ApplyTypeConstraint - Given a node in a pattern, apply this type
 /// constraint to the nodes operands.  This returns true if it makes a
 /// change, false otherwise.  If a type contradiction is found, throw an
@@ -100,9 +119,6 @@
     // Operand must be a particular type.
     return NodeToApply->UpdateNodeType(x.SDTCisVT_Info.VT, TP);
   case SDTCisInt: {
-    if (NodeToApply->hasTypeSet() && !MVT::isInteger(NodeToApply->getType()))
-      NodeToApply->UpdateNodeType(MVT::i1, TP);  // throw an error.
-
     // If there is only one integer type supported, this must be it.
     std::vector<MVT::ValueType> IntVTs =
       FilterVTs(CGT.getLegalValueTypes(), MVT::isInteger);
@@ -110,13 +126,9 @@
     // If we found exactly one supported integer type, apply it.
     if (IntVTs.size() == 1)
       return NodeToApply->UpdateNodeType(IntVTs[0], TP);
-    return false;
+    return NodeToApply->UpdateNodeType(MVT::isInt, TP);
   }
   case SDTCisFP: {
-    if (NodeToApply->hasTypeSet() &&
-        !MVT::isFloatingPoint(NodeToApply->getType()))
-      NodeToApply->UpdateNodeType(MVT::f32, TP);  // throw an error.
-
     // If there is only one FP type supported, this must be it.
     std::vector<MVT::ValueType> FPVTs =
       FilterVTs(CGT.getLegalValueTypes(), MVT::isFloatingPoint);
@@ -124,13 +136,13 @@
     // If we found exactly one supported FP type, apply it.
     if (FPVTs.size() == 1)
       return NodeToApply->UpdateNodeType(FPVTs[0], TP);
-    return false;
+    return NodeToApply->UpdateNodeType(MVT::isFP, TP);
   }
   case SDTCisSameAs: {
     TreePatternNode *OtherNode =
       getOperandNum(x.SDTCisSameAs_Info.OtherOperandNum, N, NumResults);
-    return NodeToApply->UpdateNodeType(OtherNode->getType(), TP) |
-           OtherNode->UpdateNodeType(NodeToApply->getType(), TP);
+    return NodeToApply->UpdateNodeType(OtherNode->getExtType(), TP) |
+           OtherNode->UpdateNodeType(NodeToApply->getExtType(), TP);
   }
   case SDTCisVTSmallerThanOp: {
     // The NodeToApply must be a leaf node that is a VT.  OtherOperandNum must
@@ -147,9 +159,12 @@
     
     TreePatternNode *OtherNode =
       getOperandNum(x.SDTCisVTSmallerThanOp_Info.OtherOperandNum, N,NumResults);
-    if (OtherNode->hasTypeSet() &&
-        (!MVT::isInteger(OtherNode->getType()) ||
-         OtherNode->getType() <= VT))
+    
+    // It must be integer.
+    bool MadeChange = false;
+    MadeChange |= OtherNode->UpdateNodeType(MVT::isInt, TP);
+    
+    if (OtherNode->hasTypeSet() && OtherNode->getType() <= VT)
       OtherNode->UpdateNodeType(MVT::Other, TP);  // Throw an error.
     return false;
   }
@@ -216,13 +231,27 @@
 /// information.  If N already contains a conflicting type, then throw an
 /// exception.  This returns true if any information was updated.
 ///
-bool TreePatternNode::UpdateNodeType(MVT::ValueType VT, TreePattern &TP) {
-  if (VT == MVT::LAST_VALUETYPE || getType() == VT) return false;
-  if (getType() == MVT::LAST_VALUETYPE) {
+bool TreePatternNode::UpdateNodeType(unsigned char VT, TreePattern &TP) {
+  if (VT == MVT::isUnknown || getExtType() == VT) return false;
+  if (getExtType() == MVT::isUnknown) {
     setType(VT);
     return true;
   }
   
+  // If we are told this is to be an int or FP type, and it already is, ignore
+  // the advice.
+  if ((VT == MVT::isInt && isExtIntegerVT(getExtType())) ||
+      (VT == MVT::isFP  && isExtFloatingPointVT(getExtType())))
+    return false;
+      
+  // If we know this is an int or fp type, and we are told it is a specific one,
+  // take the advice.
+  if ((getExtType() == MVT::isInt && isExtIntegerVT(VT)) ||
+      (getExtType() == MVT::isFP  && isExtFloatingPointVT(VT))) {
+    setType(VT);
+    return true;
+  }      
+
   TP.error("Type inference contradiction found in node " + 
            getOperator()->getName() + "!");
   return true; // unreachable
@@ -236,12 +265,13 @@
     OS << "(" << getOperator()->getName();
   }
   
-  if (getType() == MVT::Other)
-    OS << ":Other";
-  else if (getType() == MVT::LAST_VALUETYPE)
-    ;//OS << ":?";
-  else
-    OS << ":" << getType();
+  switch (getExtType()) {
+  case MVT::Other: OS << ":Other"; break;
+  case MVT::isInt: OS << ":isInt"; break;
+  case MVT::isFP : OS << ":isFP"; break;
+  case MVT::isUnknown: ; /*OS << ":?";*/ break;
+  default:  OS << ":" << getType(); break;
+  }
 
   if (!isLeaf()) {
     if (getNumChildren() != 0) {
@@ -273,7 +303,7 @@
 /// that are otherwise identical are considered isomorphic.
 bool TreePatternNode::isIsomorphicTo(const TreePatternNode *N) const {
   if (N == this) return true;
-  if (N->isLeaf() != isLeaf() || getType() != N->getType() ||
+  if (N->isLeaf() != isLeaf() || getExtType() != N->getExtType() ||
       getPredicateFn() != N->getPredicateFn() ||
       getTransformFn() != N->getTransformFn())
     return false;
@@ -307,7 +337,7 @@
     New = new TreePatternNode(getOperator(), CChildren);
   }
   New->setName(getName());
-  New->setType(getType());
+  New->setType(getExtType());
   New->setPredicateFn(getPredicateFn());
   New->setTransformFn(getTransformFn());
   return New;
@@ -383,23 +413,24 @@
 /// type which should be applied to it.  This infer the type of register
 /// references from the register file information, for example.
 ///
-static MVT::ValueType getIntrinsicType(Record *R, bool NotRegisters, TreePattern &TP) {
+static unsigned char getIntrinsicType(Record *R, bool NotRegisters,
+                                      TreePattern &TP) {
   // Check to see if this is a register or a register class...
   if (R->isSubClassOf("RegisterClass")) {
-    if (NotRegisters) return MVT::LAST_VALUETYPE;
+    if (NotRegisters) return MVT::isUnknown;
     return getValueType(R->getValueAsDef("RegType"));
   } else if (R->isSubClassOf("PatFrag")) {
     // Pattern fragment types will be resolved when they are inlined.
-    return MVT::LAST_VALUETYPE;
+    return MVT::isUnknown;
   } else if (R->isSubClassOf("Register")) {
     assert(0 && "Explicit registers not handled here yet!\n");
-    return MVT::LAST_VALUETYPE;
+    return MVT::isUnknown;
   } else if (R->isSubClassOf("ValueType")) {
     // Using a VTSDNode.
     return MVT::Other;
   } else if (R->getName() == "node") {
     // Placeholder.
-    return MVT::LAST_VALUETYPE;
+    return MVT::isUnknown;
   }
   
   TP.error("Unknown node flavor used in pattern: " + R->getName());
@@ -426,8 +457,8 @@
     MadeChange |= getChild(1)->ApplyTypeConstraints(TP, NotRegisters);
     
     // Types of operands must match.
-    MadeChange |= getChild(0)->UpdateNodeType(getChild(1)->getType(), TP);
-    MadeChange |= getChild(1)->UpdateNodeType(getChild(0)->getType(), TP);
+    MadeChange |= getChild(0)->UpdateNodeType(getChild(1)->getExtType(), TP);
+    MadeChange |= getChild(1)->UpdateNodeType(getChild(0)->getExtType(), TP);
     MadeChange |= UpdateNodeType(MVT::isVoid, TP);
     return MadeChange;
   } else if (getOperator()->isSubClassOf("SDNode")) {
@@ -462,8 +493,8 @@
     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);
+    bool MadeChange = UpdateNodeType(getChild(0)->getExtType(), TP);
+    MadeChange |= getChild(0)->UpdateNodeType(getExtType(), TP);
     return MadeChange;
   }
 }
@@ -825,7 +856,7 @@
     // Ensure that the inputs agree if we've already seen this input.
     if (Rec != SlotRec)
       I->error("All $" + Pat->getName() + " inputs must agree with each other");
-    if (Slot->getType() != Pat->getType())
+    if (Slot->getExtType() != Pat->getExtType())
       I->error("All $" + Pat->getName() + " inputs must agree with each other");
   }
   return true;
@@ -847,7 +878,7 @@
     // If this is not a set, verify that the children nodes are not void typed,
     // and recurse.
     for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
-      if (Pat->getChild(i)->getType() == MVT::isVoid)
+      if (Pat->getChild(i)->getExtType() == MVT::isVoid)
         I->error("Cannot have void nodes inside of patterns!");
       FindPatternInputsAndOutputs(I, Pat->getChild(i), InstInputs, InstResults);
     }
@@ -933,7 +964,7 @@
     // fill in the InstResults map.
     for (unsigned j = 0, e = I->getNumTrees(); j != e; ++j) {
       TreePatternNode *Pat = I->getTree(j);
-      if (Pat->getType() != MVT::isVoid) {
+      if (Pat->getExtType() != MVT::isVoid) {
         I->dump();
         I->error("Top-level forms in instruction pattern should have"
                  " void types");
@@ -993,7 +1024,7 @@
                  " does not appear in the instruction pattern");
       TreePatternNode *InVal = InstInputsCheck[OpName];
       InstInputsCheck.erase(OpName);   // It occurred, remove from map.
-      if (CGI.OperandList[i].Ty != InVal->getType())
+      if (CGI.OperandList[i].Ty != InVal->getExtType())
         I->error("Operand $" + OpName +
                  "'s type disagrees between the operand and pattern");
       OperandTypes.push_back(InVal->getType());
@@ -1133,7 +1164,7 @@
     R->setName(Orig->getName());
     R->setPredicateFn(Orig->getPredicateFn());
     R->setTransformFn(Orig->getTransformFn());
-    R->setType(Orig->getType());
+    R->setType(Orig->getExtType());
     
     // If this pattern cannot every match, do not include it as a variant.
     std::string ErrString;
@@ -1357,14 +1388,15 @@
 /// patterns before small ones.  This is used to determine the size of a
 /// pattern.
 static unsigned getPatternSize(TreePatternNode *P) {
-  assert(MVT::isInteger(P->getType()) || MVT::isFloatingPoint(P->getType()) &&
+  assert(isExtIntegerVT(P->getExtType()) || 
+         isExtFloatingPointVT(P->getExtType()) &&
          "Not a valid pattern node to size!");
   unsigned Size = 1;  // The node itself.
   
   // Count children in the count if they are also nodes.
   for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) {
     TreePatternNode *Child = P->getChild(i);
-    if (!Child->isLeaf() && Child->getType() != MVT::Other)
+    if (!Child->isLeaf() && Child->getExtType() != MVT::Other)
       Size += getPatternSize(Child);
   }
   
@@ -1557,7 +1589,7 @@
 /// RemoveAllTypes - A quick recursive walk over a pattern which removes all
 /// type information from it.
 static void RemoveAllTypes(TreePatternNode *N) {
-  N->setType(MVT::LAST_VALUETYPE);
+  N->setType(MVT::isUnknown);
   if (!N->isLeaf())
     for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
       RemoveAllTypes(N->getChild(i));


Index: llvm/utils/TableGen/DAGISelEmitter.h
diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.31 llvm/utils/TableGen/DAGISelEmitter.h:1.32
--- llvm/utils/TableGen/DAGISelEmitter.h:1.31	Thu Oct 13 23:53:53 2005
+++ llvm/utils/TableGen/DAGISelEmitter.h	Fri Oct 14 01:12:03 2005
@@ -27,6 +27,16 @@
   class TreePatternNode;
   class DAGISelEmitter;
   
+  /// MVT::DAGISelGenValueType - These are some extended forms of MVT::ValueType
+  /// that we use as lattice values during type inferrence.
+  namespace MVT {
+    enum DAGISelGenValueType {
+      isFP  = MVT::LAST_VALUETYPE,
+      isInt,
+      isUnknown
+    };
+  }
+  
   /// SDTypeConstraint - This is a discriminated union of constraints,
   /// corresponding to the SDTypeConstraint tablegen class in Target.td.
   struct SDTypeConstraint {
@@ -115,8 +125,8 @@
   class TreePatternNode {
     /// The inferred type for this node, or MVT::LAST_VALUETYPE if it hasn't
     /// been determined yet.
-    MVT::ValueType Ty;
-
+    unsigned char Ty;
+    
     /// Operator - The Record for the operator if this is an interior node (not
     /// a leaf).
     Record *Operator;
@@ -140,19 +150,26 @@
     std::vector<TreePatternNode*> Children;
   public:
     TreePatternNode(Record *Op, const std::vector<TreePatternNode*> &Ch) 
-      : Ty(MVT::LAST_VALUETYPE), Operator(Op), Val(0), TransformFn(0),
+      : Ty(MVT::isUnknown), Operator(Op), Val(0), TransformFn(0),
         Children(Ch) {}
     TreePatternNode(Init *val)    // leaf ctor
-      : Ty(MVT::LAST_VALUETYPE), Operator(0), Val(val), TransformFn(0) {}
+      : Ty(MVT::isUnknown), Operator(0), Val(val), TransformFn(0) {}
     ~TreePatternNode();
     
     const std::string &getName() const { return Name; }
     void setName(const std::string &N) { Name = N; }
     
     bool isLeaf() const { return Val != 0; }
-    bool hasTypeSet() const { return Ty != MVT::LAST_VALUETYPE; }
-    MVT::ValueType getType() const { return Ty; }
-    void setType(MVT::ValueType VT) { Ty = VT; }
+    bool hasTypeSet() const { return Ty < MVT::LAST_VALUETYPE; }
+    bool isTypeCompletelyUnknown() const {
+      return Ty == MVT::isUnknown;
+    }
+    MVT::ValueType getType() const {
+      assert(hasTypeSet() && "Doesn't have a type yet!");
+      return (MVT::ValueType)Ty;
+    }
+    unsigned char getExtType() const { return Ty; }
+    void setType(unsigned char VT) { Ty = VT; }
     
     Init *getLeafValue() const { assert(isLeaf()); return Val; }
     Record *getOperator() const { assert(!isLeaf()); return Operator; }
@@ -204,7 +221,7 @@
     /// information.  If N already contains a conflicting type, then throw an
     /// exception.  This returns true if any information was updated.
     ///
-    bool UpdateNodeType(MVT::ValueType VT, TreePattern &TP);
+    bool UpdateNodeType(unsigned char EVT, TreePattern &TP);
     
     /// ContainsUnresolvedType - Return true if this tree contains any
     /// unresolved types.






More information about the llvm-commits mailing list