Add CheckChildInteger to ISelMatcher operations. Removes nearly 2000 bytes from X86...
authorCraig Topper <craig.topper@gmail.com>
Wed, 5 Feb 2014 05:44:28 +0000 (05:44 +0000)
committerCraig Topper <craig.topper@gmail.com>
Wed, 5 Feb 2014 05:44:28 +0000 (05:44 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200821 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAGISel.h
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
utils/TableGen/DAGISelMatcher.cpp
utils/TableGen/DAGISelMatcher.h
utils/TableGen/DAGISelMatcherEmitter.cpp
utils/TableGen/DAGISelMatcherOpt.cpp

index 5f1c636dc6e6c4eaf9144d2da203cb105cbab52c..3d626e1edfe7980e2c1406825496502ff08435a8 100644 (file)
@@ -123,6 +123,8 @@ public:
     OPC_CheckChild3Type, OPC_CheckChild4Type, OPC_CheckChild5Type,
     OPC_CheckChild6Type, OPC_CheckChild7Type,
     OPC_CheckInteger,
+    OPC_CheckChild0Integer, OPC_CheckChild1Integer, OPC_CheckChild2Integer,
+    OPC_CheckChild3Integer, OPC_CheckChild4Integer,
     OPC_CheckCondCode,
     OPC_CheckValueType,
     OPC_CheckComplexPat,
index 8a455d9dca69dc25491805df8b98639a08e4832b..5534354ab0099d88e07b14ce1a1015a4a19e465b 100644 (file)
@@ -2198,8 +2198,7 @@ CheckType(const unsigned char *MatcherTable, unsigned &MatcherIndex,
 
 LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
 CheckChildType(const unsigned char *MatcherTable, unsigned &MatcherIndex,
-               SDValue N, const TargetLowering *TLI,
-               unsigned ChildNo) {
+               SDValue N, const TargetLowering *TLI, unsigned ChildNo) {
   if (ChildNo >= N.getNumOperands())
     return false;  // Match fails if out of range child #.
   return ::CheckType(MatcherTable, MatcherIndex, N.getOperand(ChildNo), TLI);
@@ -2234,6 +2233,14 @@ CheckInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex,
   return C != 0 && C->getSExtValue() == Val;
 }
 
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
+CheckChildInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex,
+                  SDValue N, unsigned ChildNo) {
+  if (ChildNo >= N.getNumOperands())
+    return false;  // Match fails if out of range child #.
+  return ::CheckInteger(MatcherTable, MatcherIndex, N.getOperand(ChildNo));
+}
+
 LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
 CheckAndImm(const unsigned char *MatcherTable, unsigned &MatcherIndex,
             SDValue N, const SelectionDAGISel &SDISel) {
@@ -2317,6 +2324,14 @@ static unsigned IsPredicateKnownToFail(const unsigned char *Table,
   case SelectionDAGISel::OPC_CheckInteger:
     Result = !::CheckInteger(Table, Index, N);
     return Index;
+  case SelectionDAGISel::OPC_CheckChild0Integer:
+  case SelectionDAGISel::OPC_CheckChild1Integer:
+  case SelectionDAGISel::OPC_CheckChild2Integer:
+  case SelectionDAGISel::OPC_CheckChild3Integer:
+  case SelectionDAGISel::OPC_CheckChild4Integer:
+    Result = !::CheckChildInteger(Table, Index, N,
+                     Table[Index-1] - SelectionDAGISel::OPC_CheckChild0Integer);
+    return Index;
   case SelectionDAGISel::OPC_CheckAndImm:
     Result = !::CheckAndImm(Table, Index, N, SDISel);
     return Index;
@@ -2697,6 +2712,12 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
     case OPC_CheckInteger:
       if (!::CheckInteger(MatcherTable, MatcherIndex, N)) break;
       continue;
+    case OPC_CheckChild0Integer: case OPC_CheckChild1Integer:
+    case OPC_CheckChild2Integer: case OPC_CheckChild3Integer:
+    case OPC_CheckChild4Integer:
+      if (!::CheckChildInteger(MatcherTable, MatcherIndex, N,
+                               Opcode-OPC_CheckChild0Integer)) break;
+      continue;
     case OPC_CheckAndImm:
       if (!::CheckAndImm(MatcherTable, MatcherIndex, N, *this)) break;
       continue;
index 64764bdb92e68707229d1442f7925da855ef135a..2557bb6eea54e1011c384b96c230b3b976c3c4b5 100644 (file)
@@ -194,6 +194,11 @@ void CheckIntegerMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
   OS.indent(indent) << "CheckInteger " << Value << '\n';
 }
 
+void CheckChildIntegerMatcher::printImpl(raw_ostream &OS,
+                                         unsigned indent) const {
+  OS.indent(indent) << "CheckChildInteger " << ChildNo << " " << Value << '\n';
+}
+
 void CheckCondCodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
   OS.indent(indent) << "CheckCondCode ISD::" << CondCodeName << '\n';
 }
@@ -420,6 +425,18 @@ bool CheckIntegerMatcher::isContradictoryImpl(const Matcher *M) const {
   return false;
 }
 
+bool CheckChildIntegerMatcher::isContradictoryImpl(const Matcher *M) const {
+  if (const CheckChildIntegerMatcher *CCIM = dyn_cast<CheckChildIntegerMatcher>(M)) {
+    // If the two checks are about different nodes, we don't know if they
+    // conflict!
+    if (CCIM->getChildNo() != getChildNo())
+      return false;
+
+    return CCIM->getValue() != getValue();
+  }
+  return false;
+}
+
 bool CheckValueTypeMatcher::isContradictoryImpl(const Matcher *M) const {
   if (const CheckValueTypeMatcher *CVT = dyn_cast<CheckValueTypeMatcher>(M))
     return CVT->getTypeName() != getTypeName();
index 4a07df8f9d4f87aeeac3b5d1ebcbf12ae6a825b3..97b81e54bef13a7c7467844a132ea641c3154e24 100644 (file)
@@ -65,6 +65,7 @@ public:
     SwitchType,           // Dispatch based on type.
     CheckChildType,       // Fail if child has wrong type.
     CheckInteger,         // Fail if wrong val.
+    CheckChildInteger,    // Fail if child is wrong val.
     CheckCondCode,        // Fail if not condcode.
     CheckValueType,
     CheckComplexPat,
@@ -131,6 +132,7 @@ public:
     case CheckType:
     case CheckChildType:
     case CheckInteger:
+    case CheckChildInteger:
     case CheckCondCode:
     case CheckValueType:
     case CheckAndImm:
@@ -632,6 +634,34 @@ private:
   virtual bool isContradictoryImpl(const Matcher *M) const;
 };
 
+/// CheckChildIntegerMatcher - This checks to see if the child node is a
+/// ConstantSDNode with a specified integer value, if not it fails to match.
+class CheckChildIntegerMatcher : public Matcher {
+  unsigned ChildNo;
+  int64_t Value;
+public:
+  CheckChildIntegerMatcher(unsigned childno, int64_t value)
+    : Matcher(CheckChildInteger), ChildNo(childno), Value(value) {}
+
+  unsigned getChildNo() const { return ChildNo; }
+  int64_t getValue() const { return Value; }
+
+  static inline bool classof(const Matcher *N) {
+    return N->getKind() == CheckChildInteger;
+  }
+
+  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+  virtual bool isEqualImpl(const Matcher *M) const {
+    return cast<CheckChildIntegerMatcher>(M)->ChildNo == ChildNo &&
+           cast<CheckChildIntegerMatcher>(M)->Value == Value;
+  }
+  virtual unsigned getHashImpl() const { return (Value << 3) | ChildNo; }
+  virtual bool isContradictoryImpl(const Matcher *M) const;
+};
+
 /// CheckCondCodeMatcher - This checks to see if the current node is a
 /// CondCodeSDNode with the specified condition, if not it fails to match.
 class CheckCondCodeMatcher : public Matcher {
index cceec9f691d19aa684d2bd3aa7737a8a823d990b..41db5c56e93524c8134eaa8b92949b8310d49857 100644 (file)
@@ -378,6 +378,14 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
     OS << '\n';
     return Bytes;
   }
+  case Matcher::CheckChildInteger: {
+    OS << "OPC_CheckChild" << cast<CheckChildIntegerMatcher>(N)->getChildNo()
+       << "Integer, ";
+    unsigned Bytes=1+EmitVBRValue(cast<CheckChildIntegerMatcher>(N)->getValue(),
+                                  OS);
+    OS << '\n';
+    return Bytes;
+  }
   case Matcher::CheckCondCode:
     OS << "OPC_CheckCondCode, ISD::"
        << cast<CheckCondCodeMatcher>(N)->getCondCodeName() << ",\n";
@@ -768,6 +776,7 @@ void MatcherTableEmitter::EmitHistogram(const Matcher *M,
     case Matcher::SwitchType: OS << "OPC_SwitchType"; break;
     case Matcher::CheckChildType: OS << "OPC_CheckChildType"; break;
     case Matcher::CheckInteger: OS << "OPC_CheckInteger"; break;
+    case Matcher::CheckChildInteger: OS << "OPC_CheckChildInteger"; break;
     case Matcher::CheckCondCode: OS << "OPC_CheckCondCode"; break;
     case Matcher::CheckValueType: OS << "OPC_CheckValueType"; break;
     case Matcher::CheckComplexPat: OS << "OPC_CheckComplexPat"; break;
index 8fde8ce5bc0fcfd81154a43c90959d3fb0abde85..682b27c097a4689327101162e9b6de7e24dd641e 100644 (file)
@@ -46,7 +46,7 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
       if (MC->getChildNo() < 8)  // Only have RecordChild0...7
         New = new RecordChildMatcher(MC->getChildNo(), RM->getWhatFor(),
                                      RM->getResultNo());
-    
+
     if (CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(MC->getNext()))
       if (MC->getChildNo() < 8 &&  // Only have CheckChildType0...7
           CT->getResNo() == 0)     // CheckChildType checks res #0
@@ -56,6 +56,10 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
       if (MC->getChildNo() < 4)  // Only have CheckChildSame0...3
         New = new CheckChildSameMatcher(MC->getChildNo(), CS->getMatchNumber());
 
+    if (CheckIntegerMatcher *CS = dyn_cast<CheckIntegerMatcher>(MC->getNext()))
+      if (MC->getChildNo() < 5)  // Only have CheckChildInteger0...4
+        New = new CheckChildIntegerMatcher(MC->getChildNo(), CS->getValue());
+
     if (New) {
       // Insert the new node.
       New->setNext(MatcherPtr.take());