Add 256-bit vaddsub, vhadd, vhsub, vblend and vdpp instructions!
[oota-llvm.git] / utils / TableGen / DAGISelMatcher.cpp
index c4f1cbfcf058df8742f283f4a20a776e52764d85..9f12a686e4cf874cc198140ae8a35de6dfbe746a 100644 (file)
@@ -29,6 +29,54 @@ void Matcher::printOne(raw_ostream &OS) const {
   printImpl(OS, 0);
 }
 
+/// unlinkNode - Unlink the specified node from this chain.  If Other == this,
+/// we unlink the next pointer and return it.  Otherwise we unlink Other from
+/// the list and return this.
+Matcher *Matcher::unlinkNode(Matcher *Other) {
+  if (this == Other)
+    return takeNext();
+  // Scan until we find the predecessor of Other.
+  Matcher *Cur = this;
+  for (; Cur && Cur->getNext() != Other; Cur = Cur->getNext())
+    /*empty*/;
+
+  if (Cur == 0) return 0;
+  Cur->takeNext();
+  Cur->setNext(Other->takeNext());
+  return this;
+}
+
+/// canMoveBefore - Return true if this matcher is the same as Other, or if
+/// we can move this matcher past all of the nodes in-between Other and this
+/// node.  Other must be equal to or before this.
+bool Matcher::canMoveBefore(const Matcher *Other) const {
+  for (;; Other = Other->getNext()) {
+    assert(Other && "Other didn't come before 'this'?");
+    if (this == Other) return true;
+
+    // We have to be able to move this node across the Other node.
+    if (!canMoveBeforeNode(Other))
+      return false;
+  }
+}
+
+/// canMoveBefore - Return true if it is safe to move the current matcher
+/// across the specified one.
+bool Matcher::canMoveBeforeNode(const Matcher *Other) const {
+  // We can move simple predicates before record nodes.
+  if (isSimplePredicateNode())
+    return Other->isSimplePredicateOrRecordNode();
+  
+  // We can move record nodes across simple predicates.
+  if (isSimplePredicateOrRecordNode())
+    return isSimplePredicateNode();
+  
+  // We can't move record nodes across each other etc.
+  return false;
+}
+
+
 ScopeMatcher::~ScopeMatcher() {
   for (unsigned i = 0, e = Children.size(); i != e; ++i)
     delete Children[i];
@@ -99,7 +147,8 @@ void SwitchOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
 
 
 void CheckTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
-  OS.indent(indent) << "CheckType " << getEnumName(Type) << '\n';
+  OS.indent(indent) << "CheckType " << getEnumName(Type) << ", ResNo="
+    << ResNo << '\n';
 }
 
 void SwitchTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
@@ -308,15 +357,13 @@ bool CheckOpcodeMatcher::isContradictoryImpl(const Matcher *M) const {
   // different, then we know they contradict.  For example, a check for
   // ISD::STORE will never be true at the same time a check for Type i32 is.
   if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M)) {
-    // FIXME: What result is this referring to?
-    unsigned NodeType;
-    if (getOpcode().getNumResults() == 0)
-      NodeType = MVT::isVoid;
-    else
-      NodeType = getOpcode().getKnownType();
-    if (NodeType != EEVT::isUnknown)
-      return TypesAreContradictory((MVT::SimpleValueType)NodeType,
-                                   CT->getType());
+    // If checking for a result the opcode doesn't have, it can't match.
+    if (CT->getResNo() >= getOpcode().getNumResults())
+      return true;
+    
+    MVT::SimpleValueType NodeType = getOpcode().getKnownType(CT->getResNo());
+    if (NodeType != MVT::Other)
+      return TypesAreContradictory(NodeType, CT->getType());
   }
   
   return false;
@@ -345,3 +392,10 @@ bool CheckIntegerMatcher::isContradictoryImpl(const Matcher *M) const {
     return CIM->getValue() != getValue();
   return false;
 }
+
+bool CheckValueTypeMatcher::isContradictoryImpl(const Matcher *M) const {
+  if (const CheckValueTypeMatcher *CVT = dyn_cast<CheckValueTypeMatcher>(M))
+    return CVT->getTypeName() != getTypeName();
+  return false;
+}
+