[PATCH] D33769: [SelectionDAG] Get rid of recursion in CalcNodeSethiUllmanNumber

Max Kazantsev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 1 04:40:58 PDT 2017


mkazantsev created this revision.
Herald added a subscriber: MatzeB.

The recursive implementation of CalcNodeSethiUllmanNumber may
overflow stack on extremely long pred chains. This patch replaces it
with an equivalent iterative implementation.


https://reviews.llvm.org/D33769

Files:
  lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp


Index: lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -1859,30 +1859,67 @@
 
 /// CalcNodeSethiUllmanNumber - Compute Sethi Ullman number.
 /// Smaller number is the higher priority.
-static unsigned
-CalcNodeSethiUllmanNumber(const SUnit *SU, std::vector<unsigned> &SUNumbers) {
-  unsigned &SethiUllmanNumber = SUNumbers[SU->NodeNum];
-  if (SethiUllmanNumber != 0)
-    return SethiUllmanNumber;
-
-  unsigned Extra = 0;
-  for (const SDep &Pred : SU->Preds) {
-    if (Pred.isCtrl()) continue;  // ignore chain preds
-    SUnit *PredSU = Pred.getSUnit();
-    unsigned PredSethiUllman = CalcNodeSethiUllmanNumber(PredSU, SUNumbers);
-    if (PredSethiUllman > SethiUllmanNumber) {
-      SethiUllmanNumber = PredSethiUllman;
-      Extra = 0;
-    } else if (PredSethiUllman == SethiUllmanNumber)
-      ++Extra;
-  }
-
-  SethiUllmanNumber += Extra;
+static unsigned CalcNodeSethiUllmanNumber(const SUnit *SU,
+                                          std::vector<unsigned> &SUNumbers) {
+  // Use WorkList to avoid stack overflow on excessively large IRs.
+  struct WorkState {
+    WorkState(const SUnit *SU, std::vector<unsigned> &SUNumbers)
+        : SU(SU), SethiUllmanNumber(SUNumbers[SU->NodeNum]),
+          AnswerKnown(SethiUllmanNumber != 0), CurrentPred(SU->Preds.begin()) {}
+    bool isDone() const {
+      return AnswerKnown || CurrentPred == SU->Preds.end();
+    }
+    const SDep &nextPred() {
+      return *CurrentPred++;
+    }
+    const SUnit *SU;
+    unsigned &SethiUllmanNumber;
+    const bool AnswerKnown;
+    SmallVectorImpl<SDep>::const_iterator CurrentPred;
+    unsigned Extra = 0;
+    unsigned PredSethiUllman = 0;
+  };
+  std::vector<WorkState> WorkList;
+  WorkList.push_back(std::move(WorkState(SU, SUNumbers)));
 
-  if (SethiUllmanNumber == 0)
-    SethiUllmanNumber = 1;
+  while (true) {
+    assert(!WorkList.empty() &&
+           "We should have returned after the worklist was emptied!");
+    WorkState &Curr = WorkList.back();
+
+    // Process answer received from a predecessor.
+    if (Curr.PredSethiUllman != 0) {
+      if (Curr.PredSethiUllman > Curr.SethiUllmanNumber) {
+        Curr.SethiUllmanNumber = Curr.PredSethiUllman;
+        Curr.Extra = 0;
+      } else if (Curr.PredSethiUllman == Curr.SethiUllmanNumber)
+        ++Curr.Extra;
+      Curr.PredSethiUllman = 0;
+    }
+
+    // Continue processing predecessors.
+    bool ProcessingPred = false;
+    while (!Curr.isDone()) {
+      const SDep &Pred = Curr.nextPred();
+      if (Pred.isCtrl())
+        continue; // Ignore chain preds.
+      WorkList.push_back(std::move(WorkState(Pred.getSUnit(), SUNumbers)));
+      ProcessingPred = true;
+      break;
+    }
 
-  return SethiUllmanNumber;
+    if (!ProcessingPred) {
+      assert(Curr.isDone() && "Not done and not processing a predecessor?");
+      // Calculate and memorize the answer.
+      unsigned Answer = std::max(Curr.SethiUllmanNumber + Curr.Extra, 1u);
+      Curr.SethiUllmanNumber = Answer;
+      WorkList.pop_back();
+      // If we are done, return. Otherwise, propagate the answer to the parent.
+      if (WorkList.empty())
+        return Answer;
+      WorkList.back().PredSethiUllman = Answer;
+    }
+  }
 }
 
 /// CalculateSethiUllmanNumbers - Calculate Sethi-Ullman numbers of all


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33769.101004.patch
Type: text/x-patch
Size: 3465 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170601/e3ce818b/attachment.bin>


More information about the llvm-commits mailing list