diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp index 5037f67c5e7..c839eeb2c72 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp @@ -88,7 +88,7 @@ public: bool RemovePred(SUnit *M, SUnit *N, bool isCtrl, bool isSpecial); private: - void ReleasePred(SUnit*, bool, unsigned); + void ReleasePred(SUnit *SU, SUnit *PredSU, bool isChain); void ScheduleNodeBottomUp(SUnit*, unsigned); SUnit *CopyAndMoveSuccessors(SUnit*); void InsertCCCopiesAndMoveSuccs(SUnit*, unsigned, @@ -137,13 +137,12 @@ void ScheduleDAGFast::Schedule() { /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to /// the AvailableQueue if the count reaches zero. Also update its cycle bound. -void ScheduleDAGFast::ReleasePred(SUnit *PredSU, bool isChain, - unsigned CurCycle) { +void ScheduleDAGFast::ReleasePred(SUnit *SU, SUnit *PredSU, bool isChain) { --PredSU->NumSuccsLeft; #ifndef NDEBUG if (PredSU->NumSuccsLeft < 0) { - cerr << "*** List scheduling failed! ***\n"; + cerr << "*** Scheduling failed! ***\n"; PredSU->dump(DAG); cerr << " has been released too many times!\n"; assert(0); @@ -167,7 +166,7 @@ void ScheduleDAGFast::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) { // Bottom up: release predecessors for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { - ReleasePred(I->Dep, I->isCtrl, CurCycle); + ReleasePred(SU, I->Dep, I->isCtrl); if (I->Cost < 0) { // This is a physical register dependency and it's impossible or // expensive to copy the register. Make sure nothing that can diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp index 4611ec1c597..1bce96727dd 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp @@ -78,7 +78,7 @@ public: void Schedule(); private: - void ReleaseSucc(SUnit *SuccSU, bool isChain); + void ReleaseSucc(SUnit *SU, SUnit *SuccSU, bool isChain); void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); void ListScheduleTopDown(); }; @@ -106,35 +106,33 @@ void ScheduleDAGList::Schedule() { //===----------------------------------------------------------------------===// /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to -/// the PendingQueue if the count reaches zero. -void ScheduleDAGList::ReleaseSucc(SUnit *SuccSU, bool isChain) { - SuccSU->NumPredsLeft--; +/// the PendingQueue if the count reaches zero. Also update its cycle bound. +void ScheduleDAGList::ReleaseSucc(SUnit *SU, SUnit *SuccSU, bool isChain) { + --SuccSU->NumPredsLeft; - assert(SuccSU->NumPredsLeft >= 0 && - "List scheduling internal error"); +#ifndef NDEBUG + if (SuccSU->NumPredsLeft < 0) { + cerr << "*** Scheduling failed! ***\n"; + SuccSU->dump(DAG); + cerr << " has been released too many times!\n"; + assert(0); + } +#endif + + // Compute how many cycles it will be before this actually becomes + // available. This is the max of the start time of all predecessors plus + // their latencies. + // If this is a token edge, we don't need to wait for the latency of the + // preceeding instruction (e.g. a long-latency load) unless there is also + // some other data dependence. + unsigned PredDoneCycle = SU->Cycle; + if (!isChain) + PredDoneCycle += SU->Latency; + else if (SU->Latency) + PredDoneCycle += 1; + SuccSU->CycleBound = std::max(SuccSU->CycleBound, PredDoneCycle); if (SuccSU->NumPredsLeft == 0) { - // Compute how many cycles it will be before this actually becomes - // available. This is the max of the start time of all predecessors plus - // their latencies. - unsigned AvailableCycle = 0; - for (SUnit::pred_iterator I = SuccSU->Preds.begin(), - E = SuccSU->Preds.end(); I != E; ++I) { - // If this is a token edge, we don't need to wait for the latency of the - // preceeding instruction (e.g. a long-latency load) unless there is also - // some other data dependence. - SUnit &Pred = *I->Dep; - unsigned PredDoneCycle = Pred.Cycle; - if (!I->isCtrl) - PredDoneCycle += Pred.Latency; - else if (Pred.Latency) - PredDoneCycle += 1; - - AvailableCycle = std::max(AvailableCycle, PredDoneCycle); - } - - assert(SuccSU->CycleBound == 0 && "CycleBound already assigned!"); - SuccSU->CycleBound = AvailableCycle; PendingQueue.push_back(SuccSU); } } @@ -152,7 +150,7 @@ void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { // Top down: release successors. for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) - ReleaseSucc(I->Dep, I->isCtrl); + ReleaseSucc(SU, I->Dep, I->isCtrl); SU->isScheduled = true; AvailableQueue->ScheduledNode(SU); diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index 616a28d8b9a..77ee6bd7e1e 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -106,8 +106,8 @@ public: bool RemovePred(SUnit *M, SUnit *N, bool isCtrl, bool isSpecial); private: - void ReleasePred(SUnit*, bool, unsigned); - void ReleaseSucc(SUnit*, bool isChain, unsigned); + void ReleasePred(SUnit *SU, SUnit *PredSU, bool isChain); + void ReleaseSucc(SUnit *SU, SUnit *SuccSU, bool isChain); void CapturePred(SUnit*, SUnit*, bool); void ScheduleNodeBottomUp(SUnit*, unsigned); void ScheduleNodeTopDown(SUnit*, unsigned); @@ -265,25 +265,31 @@ void ScheduleDAGRRList::CommuteNodesToReducePressure() { /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to /// the AvailableQueue if the count reaches zero. Also update its cycle bound. -void ScheduleDAGRRList::ReleasePred(SUnit *PredSU, bool isChain, - unsigned CurCycle) { - // FIXME: the distance between two nodes is not always == the predecessor's - // latency. For example, the reader can very well read the register written - // by the predecessor later than the issue cycle. It also depends on the - // interrupt model (drain vs. freeze). - PredSU->CycleBound = std::max(PredSU->CycleBound, CurCycle + PredSU->Latency); - +void ScheduleDAGRRList::ReleasePred(SUnit *SU, SUnit *PredSU, bool isChain) { --PredSU->NumSuccsLeft; #ifndef NDEBUG if (PredSU->NumSuccsLeft < 0) { - cerr << "*** List scheduling failed! ***\n"; + cerr << "*** Scheduling failed! ***\n"; PredSU->dump(DAG); cerr << " has been released too many times!\n"; assert(0); } #endif + // Compute how many cycles it will be before this actually becomes + // available. This is the max of the start time of all predecessors plus + // their latencies. + // If this is a token edge, we don't need to wait for the latency of the + // preceeding instruction (e.g. a long-latency load) unless there is also + // some other data dependence. + unsigned PredDoneCycle = SU->Cycle; + if (!isChain) + PredDoneCycle += PredSU->Latency; + else if (SU->Latency) + PredDoneCycle += 1; + PredSU->CycleBound = std::max(PredSU->CycleBound, PredDoneCycle); + if (PredSU->NumSuccsLeft == 0) { PredSU->isAvailable = true; AvailableQueue->push(PredSU); @@ -303,7 +309,7 @@ void ScheduleDAGRRList::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) { // Bottom up: release predecessors for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { - ReleasePred(I->Dep, I->isCtrl, CurCycle); + ReleasePred(SU, I->Dep, I->isCtrl); if (I->Cost < 0) { // This is a physical register dependency and it's impossible or // expensive to copy the register. Make sure nothing that can @@ -1105,25 +1111,31 @@ void ScheduleDAGRRList::ListScheduleBottomUp() { /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to /// the AvailableQueue if the count reaches zero. Also update its cycle bound. -void ScheduleDAGRRList::ReleaseSucc(SUnit *SuccSU, bool isChain, - unsigned CurCycle) { - // FIXME: the distance between two nodes is not always == the predecessor's - // latency. For example, the reader can very well read the register written - // by the predecessor later than the issue cycle. It also depends on the - // interrupt model (drain vs. freeze). - SuccSU->CycleBound = std::max(SuccSU->CycleBound, CurCycle + SuccSU->Latency); - +void ScheduleDAGRRList::ReleaseSucc(SUnit *SU, SUnit *SuccSU, bool isChain) { --SuccSU->NumPredsLeft; #ifndef NDEBUG if (SuccSU->NumPredsLeft < 0) { - cerr << "*** List scheduling failed! ***\n"; + cerr << "*** Scheduling failed! ***\n"; SuccSU->dump(DAG); cerr << " has been released too many times!\n"; assert(0); } #endif + // Compute how many cycles it will be before this actually becomes + // available. This is the max of the start time of all predecessors plus + // their latencies. + // If this is a token edge, we don't need to wait for the latency of the + // preceeding instruction (e.g. a long-latency load) unless there is also + // some other data dependence. + unsigned PredDoneCycle = SU->Cycle; + if (!isChain) + PredDoneCycle += SU->Latency; + else if (SU->Latency) + PredDoneCycle += 1; + SuccSU->CycleBound = std::max(SuccSU->CycleBound, PredDoneCycle); + if (SuccSU->NumPredsLeft == 0) { SuccSU->isAvailable = true; AvailableQueue->push(SuccSU); @@ -1144,7 +1156,7 @@ void ScheduleDAGRRList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { // Top down: release successors for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) - ReleaseSucc(I->Dep, I->isCtrl, CurCycle); + ReleaseSucc(SU, I->Dep, I->isCtrl); SU->isScheduled = true; AvailableQueue->ScheduledNode(SU);