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 &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 &SUNumbers) { + // Use WorkList to avoid stack overflow on excessively large IRs. + struct WorkState { + WorkState(const SUnit *SU, std::vector &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::const_iterator CurrentPred; + unsigned Extra = 0; + unsigned PredSethiUllman = 0; + }; + std::vector 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