]> granicus.if.org Git - llvm/commitdiff
[TableGen] Use less stack in DAGISelMatcherOpt
authorJon Chesterfield <jonathanchesterfield@gmail.com>
Mon, 6 Feb 2017 19:41:44 +0000 (19:41 +0000)
committerJon Chesterfield <jonathanchesterfield@gmail.com>
Mon, 6 Feb 2017 19:41:44 +0000 (19:41 +0000)
Refactor a helper function, FactorNodes, to search for a push node in constant space. This resolves a problem in a not-yet-upstreamed backend where a recursive pattern blew the call stack (at a depth of 255) under a debug build of tablegen. No functional change so no new test coverage. The change is minimal to avoid disturbing existing behaviour.

Differential Revision: https://reviews.llvm.org/D29080

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294230 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/DAGISelMatcherOpt.cpp

index 783b35e745f8f970cab9a491bb140d4a7ecfa856..0bb656826fbdf9f69fcda5ac3a6dc3d55103f42b 100644 (file)
@@ -181,15 +181,21 @@ static Matcher *FindNodeWithKind(Matcher *M, Matcher::KindTy Kind) {
 ///       ABC
 ///       XYZ
 ///
-static void FactorNodes(std::unique_ptr<Matcher> &MatcherPtr) {
-  // If we reached the end of the chain, we're done.
-  Matcher *N = MatcherPtr.get();
-  if (!N) return;
-  
-  // If this is not a push node, just scan for one.
-  ScopeMatcher *Scope = dyn_cast<ScopeMatcher>(N);
-  if (!Scope)
-    return FactorNodes(N->getNextPtr());
+static void FactorNodes(std::unique_ptr<Matcher> &InputMatcherPtr) {
+  // Look for a push node. Iterates instead of recurses to reduce stack usage.
+  ScopeMatcher *Scope = nullptr;
+  std::unique_ptr<Matcher> *RebindableMatcherPtr = &InputMatcherPtr;
+  while (!Scope) {
+    // If we reached the end of the chain, we're done.
+    Matcher *N = RebindableMatcherPtr->get();
+    if (!N) return;
+
+    // If this is not a push node, just scan for one.
+    Scope = dyn_cast<ScopeMatcher>(N);
+    if (!Scope)
+      RebindableMatcherPtr = &(N->getNextPtr());
+  }
+  std::unique_ptr<Matcher> &MatcherPtr = *RebindableMatcherPtr;
   
   // Okay, pull together the children of the scope node into a vector so we can
   // inspect it more easily.