[llvm-commits] [llvm] r97130 - /llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp

Chris Lattner sabre at nondot.org
Wed Feb 24 23:45:24 PST 2010


Author: lattner
Date: Thu Feb 25 01:45:24 2010
New Revision: 97130

URL: http://llvm.org/viewvc/llvm-project?rev=97130&view=rev
Log:
Implement the first half of redundancy factoring: efficiently 
splitting all the patterns under scope nodes into equality sets
based on their first node.  The second step is to rewrite the
graph info a form that exposes the sharing.  Before I do this, 
I want to redesign the Scope node.


Modified:
    llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp

Modified: llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp?rev=97130&r1=97129&r2=97130&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelMatcherOpt.cpp Thu Feb 25 01:45:24 2010
@@ -12,6 +12,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "DAGISelMatcher.h"
+#include "llvm/ADT/DenseMap.h"
+#include <vector>
 using namespace llvm;
 
 static void ContractNodes(OwningPtr<Matcher> &MatcherPtr) {
@@ -63,15 +65,98 @@
     return FactorNodes(N->getNextPtr());
   
   // Okay, pull together the series of linear push nodes into a vector so we can
-  // inspect it more easily.
+  // inspect it more easily.  While we're at it, bucket them up by the hash
+  // code of their first predicate.
   SmallVector<Matcher*, 32> OptionsToMatch;
+  typedef DenseMap<unsigned, std::vector<Matcher*> > HashTableTy;
+  HashTableTy MatchersByHash;
   
   Matcher *CurNode = N;
   for (; ScopeMatcher *PMN = dyn_cast<ScopeMatcher>(CurNode);
-       CurNode = PMN->getNext())
-    OptionsToMatch.push_back(PMN->getCheck());
-  OptionsToMatch.push_back(CurNode);
+       CurNode = PMN->getNext()) {
+    // Factor the subexpression.
+    FactorNodes(PMN->getCheckPtr());
+    if (Matcher *Check = PMN->getCheck()) {
+      OptionsToMatch.push_back(Check);
+      MatchersByHash[Check->getHash()].push_back(Check);
+    }
+  }
+  
+  if (CurNode) {
+    OptionsToMatch.push_back(CurNode);
+    MatchersByHash[CurNode->getHash()].push_back(CurNode);
+  }
+  
   
+  SmallVector<Matcher*, 32> NewOptionsToMatch;
+
+  // Now that we have bucketed up things by hash code, iterate over sets of
+  // matchers that all start with the same node.  We would like to iterate over
+  // the hash table, but it isn't in deterministic order, emulate this by going
+  // about this slightly backwards.  After each set of nodes is processed, we
+  // remove them from MatchersByHash.
+  for (unsigned i = 0, e = OptionsToMatch.size();
+       i != e && !MatchersByHash.empty(); ++i) {
+    // Find the set of matchers that start with this node.
+    Matcher *Optn = OptionsToMatch[i];
+    
+    // Find all nodes that hash to the same value.  If there is no entry in the
+    // hash table, then we must have previously processed a node equal to this
+    // one.
+    HashTableTy::iterator DMI = MatchersByHash.find(Optn->getHash());
+    if (DMI == MatchersByHash.end()) continue;
+
+    std::vector<Matcher*> &HashMembers = DMI->second;
+    assert(!HashMembers.empty() && "Should be removed if empty");
+
+    // Check to see if this node is in HashMembers, if not it was equal to a
+    // previous node and removed.
+    std::vector<Matcher*>::iterator MemberSlot =
+      std::find(HashMembers.begin(), HashMembers.end(), Optn);
+    if (MemberSlot == HashMembers.end()) continue;
+    
+    // If the node *does* exist in HashMembers, then we've confirmed that it
+    // hasn't been processed as equal to a previous node.  Process it now, start
+    // by removing it from the list of hash-equal nodes.
+    HashMembers.erase(MemberSlot);
+    
+    // Scan all of the hash members looking for ones that are equal, removing
+    // them from HashMembers, adding them to EqualMatchers.
+    SmallVector<Matcher*, 8> EqualMatchers;
+    
+    // Scan the vector backwards so we're generally removing from the end to
+    // avoid pointless data copying.
+    for (unsigned i = HashMembers.size(); i != 0; --i) {
+      if (!HashMembers[i-1]->isEqual(Optn)) continue;
+      
+      EqualMatchers.push_back(HashMembers[i-1]);
+      HashMembers.erase(HashMembers.begin()+i-1);  
+    }
+    EqualMatchers.push_back(Optn);
+    
+    // Reverse the vector so that we preserve the match ordering.
+    std::reverse(EqualMatchers.begin(), EqualMatchers.end());
+    
+    // If HashMembers is empty at this point, then we've gotten all nodes with
+    // the same hash, nuke the entry in the hash table.
+    if (HashMembers.empty())
+      MatchersByHash.erase(Optn->getHash());
+    
+    // Okay, we have the list of all matchers that start with the same node as
+    // Optn.  If there is more than one in the set, we want to factor them.
+    if (EqualMatchers.size() == 1) {
+      NewOptionsToMatch.push_back(Optn);
+      continue;
+    }
+    
+    // Factor these checks by pulling the first node off each entry and
+    // discarding it, replacing it with...
+    // something amazing??
+    
+    // FIXME: Need to change the Scope model.
+  }
+
+  // Reassemble a new Scope node.
   
 }
 





More information about the llvm-commits mailing list