Generalize my hack to use SDNodeInfo to find out when a
node is always guaranteed to have a particular type 
instead of hacking in ISD::STORE explicitly.  This allows
us to use implied types for a broad range of nodes, even
target specific ones.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97355 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index d52038c..8f4788f 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -447,6 +447,30 @@
   TypeConstraints.assign(ConstraintList.begin(), ConstraintList.end());
 }
 
+/// getKnownType - If the type constraints on this node imply a fixed type
+/// (e.g. all stores return void, etc), then return it as an
+/// MVT::SimpleValueType.  Otherwise, return EEVT::isUnknown.
+unsigned SDNodeInfo::getKnownType() const {
+  unsigned NumResults = getNumResults();
+  assert(NumResults <= 1 &&
+         "We only work with nodes with zero or one result so far!");
+  
+  for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i) {
+    // Make sure that this applies to the correct node result.
+    if (TypeConstraints[i].OperandNo >= NumResults)  // FIXME: need value #
+      continue;
+    
+    switch (TypeConstraints[i].ConstraintType) {
+    default: break;
+    case SDTypeConstraint::SDTCisVT:
+      return TypeConstraints[i].x.SDTCisVT_Info.VT;
+    case SDTypeConstraint::SDTCisPtrTy:
+      return MVT::iPTR;
+    }
+  }
+  return EEVT::isUnknown;
+}
+
 //===----------------------------------------------------------------------===//
 // TreePatternNode implementation
 //
diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h
index c246483..60898bc 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -125,6 +125,11 @@
     return TypeConstraints;
   }
   
+  /// getKnownType - If the type constraints on this node imply a fixed type
+  /// (e.g. all stores return void, etc), then return it as an
+  /// MVT::SimpleValueType.  Otherwise, return EEVT::isUnknown.
+  unsigned getKnownType() const;
+  
   /// hasProperty - Return true if this node has the specified property.
   ///
   bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
diff --git a/utils/TableGen/DAGISelMatcher.cpp b/utils/TableGen/DAGISelMatcher.cpp
index ade058e..3ea5b5d 100644
--- a/utils/TableGen/DAGISelMatcher.cpp
+++ b/utils/TableGen/DAGISelMatcher.cpp
@@ -260,25 +260,6 @@
 
 // isContradictoryImpl Implementations.
 
-bool CheckOpcodeMatcher::isContradictoryImpl(const Matcher *M) const {
-  if (const CheckOpcodeMatcher *COM = dyn_cast<CheckOpcodeMatcher>(M)) {
-    // One node can't have two different opcodes!
-    return &COM->getOpcode() != &getOpcode();
-  }
-  
-  // TODO: CheckMultiOpcodeMatcher?
-  
-  // This is a special common case we see a lot in the X86 backend, we know that
-  // ISD::STORE nodes can't have non-void type.
-  if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M))
-    // FIXME: This sucks, get void nodes from type constraints.
-    return (getOpcode().getEnumName() == "ISD::STORE" ||
-            getOpcode().getEnumName() == "ISD::INTRINSIC_VOID") &&
-           CT->getType() != MVT::isVoid;
-  
-  return false;
-}
-
 static bool TypesAreContradictory(MVT::SimpleValueType T1,
                                   MVT::SimpleValueType T2) {
   // If the two types are the same, then they are the same, so they don't
@@ -297,6 +278,32 @@
   return true;
 }
 
+bool CheckOpcodeMatcher::isContradictoryImpl(const Matcher *M) const {
+  if (const CheckOpcodeMatcher *COM = dyn_cast<CheckOpcodeMatcher>(M)) {
+    // One node can't have two different opcodes!
+    return &COM->getOpcode() != &getOpcode();
+  }
+  
+  // TODO: CheckMultiOpcodeMatcher?
+  
+  // If the node has a known type, and if the type we're checking for is
+  // 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());
+  }
+  
+  return false;
+}
+
 bool CheckTypeMatcher::isContradictoryImpl(const Matcher *M) const {
   if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M))
     return TypesAreContradictory(getType(), CT->getType());