Generalize my hack to use SDNodeInfo to find out when a
authorChris Lattner <sabre@nondot.org>
Sun, 28 Feb 2010 00:22:30 +0000 (00:22 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 28 Feb 2010 00:22:30 +0000 (00:22 +0000)
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

utils/TableGen/CodeGenDAGPatterns.cpp
utils/TableGen/CodeGenDAGPatterns.h
utils/TableGen/DAGISelMatcher.cpp

index d52038ce5219980dec677a48389607bd360f0b00..8f4788f872d6e7183330c2dbae3a801ceb26df78 100644 (file)
@@ -447,6 +447,30 @@ SDNodeInfo::SDNodeInfo(Record *R) : Def(R) {
   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
 //
index c246483acffc001b9bf178a33c174358303bfa76..60898bc04ce58cbeb6baff18024306fcabbf303e 100644 (file)
@@ -125,6 +125,11 @@ public:
     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); }
index ade058ef5f9295f7dc64fd7df0a7de7e688f6bf5..3ea5b5d7fbfcc9c064bb5c0ff7d9d8f26f2694eb 100644 (file)
@@ -260,25 +260,6 @@ unsigned CompleteMatchMatcher::getHashImpl() const {
 
 // 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 @@ static bool TypesAreContradictory(MVT::SimpleValueType T1,
   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());