[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