diff options
author | Reid Kleckner <reid@kleckner.net> | 2009-09-30 20:15:38 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2009-09-30 20:15:38 +0000 |
commit | e9b95fd1ebb1f046d17afd0123d7c3afcd4ddef0 (patch) | |
tree | 961f33a75eced084518a387d00095b6a98782d25 | |
parent | 5a8c00d3394922bbc310fdd6ffb829939de37cd1 (diff) | |
download | external_llvm-e9b95fd1ebb1f046d17afd0123d7c3afcd4ddef0.zip external_llvm-e9b95fd1ebb1f046d17afd0123d7c3afcd4ddef0.tar.gz external_llvm-e9b95fd1ebb1f046d17afd0123d7c3afcd4ddef0.tar.bz2 |
Fix integer overflow in instruction scheduling. This can happen if we have
basic blocks that are so long that their size overflows a short.
Also assert that overflow does not happen in the future, as requested by Evan.
This fixes PR4401.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83159 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/CodeGen/ScheduleDAG.h | 8 | ||||
-rw-r--r-- | lib/CodeGen/PostRASchedulerList.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/ScheduleDAG.cpp | 20 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp | 9 |
6 files changed, 37 insertions, 24 deletions
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index c5e12a6..2de095b 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -243,10 +243,10 @@ namespace llvm { unsigned NodeNum; // Entry # of node in the node vector. unsigned NodeQueueId; // Queue id of node. unsigned short Latency; // Node latency. - short NumPreds; // # of SDep::Data preds. - short NumSuccs; // # of SDep::Data sucss. - short NumPredsLeft; // # of preds not scheduled. - short NumSuccsLeft; // # of succs not scheduled. + unsigned NumPreds; // # of SDep::Data preds. + unsigned NumSuccs; // # of SDep::Data sucss. + unsigned NumPredsLeft; // # of preds not scheduled. + unsigned NumSuccsLeft; // # of succs not scheduled. bool isTwoAddress : 1; // Is a two-address instruction. bool isCommutable : 1; // Is a commutable instruction. bool hasPhysRegDefs : 1; // Has physreg defs that are being used. diff --git a/lib/CodeGen/PostRASchedulerList.cpp b/lib/CodeGen/PostRASchedulerList.cpp index 42954ea..5fa598d 100644 --- a/lib/CodeGen/PostRASchedulerList.cpp +++ b/lib/CodeGen/PostRASchedulerList.cpp @@ -972,17 +972,17 @@ void SchedulePostRATDList::FixupKills(MachineBasicBlock *MBB) { /// the PendingQueue if the count reaches zero. Also update its cycle bound. void SchedulePostRATDList::ReleaseSucc(SUnit *SU, SDep *SuccEdge) { SUnit *SuccSU = SuccEdge->getSUnit(); - --SuccSU->NumPredsLeft; - + #ifndef NDEBUG - if (SuccSU->NumPredsLeft < 0) { + if (SuccSU->NumPredsLeft == 0) { errs() << "*** Scheduling failed! ***\n"; SuccSU->dump(this); errs() << " has been released too many times!\n"; llvm_unreachable(0); } #endif - + --SuccSU->NumPredsLeft; + // 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. diff --git a/lib/CodeGen/ScheduleDAG.cpp b/lib/CodeGen/ScheduleDAG.cpp index ff5c236..5a59862 100644 --- a/lib/CodeGen/ScheduleDAG.cpp +++ b/lib/CodeGen/ScheduleDAG.cpp @@ -82,13 +82,19 @@ void SUnit::addPred(const SDep &D) { SUnit *N = D.getSUnit(); // Update the bookkeeping. if (D.getKind() == SDep::Data) { + assert(NumPreds < UINT_MAX && "NumPreds will overflow!"); + assert(N->NumSuccs < UINT_MAX && "NumSuccs will overflow!"); ++NumPreds; ++N->NumSuccs; } - if (!N->isScheduled) + if (!N->isScheduled) { + assert(NumPredsLeft < UINT_MAX && "NumPredsLeft will overflow!"); ++NumPredsLeft; - if (!isScheduled) + } + if (!isScheduled) { + assert(N->NumSuccsLeft < UINT_MAX && "NumSuccsLeft will overflow!"); ++N->NumSuccsLeft; + } Preds.push_back(D); N->Succs.push_back(P); if (P.getLatency() != 0) { @@ -121,13 +127,19 @@ void SUnit::removePred(const SDep &D) { Preds.erase(I); // Update the bookkeeping. if (P.getKind() == SDep::Data) { + assert(NumPreds > 0 && "NumPreds will underflow!"); + assert(N->NumSuccs > 0 && "NumSuccs will underflow!"); --NumPreds; --N->NumSuccs; } - if (!N->isScheduled) + if (!N->isScheduled) { + assert(NumPredsLeft > 0 && "NumPredsLeft will underflow!"); --NumPredsLeft; - if (!isScheduled) + } + if (!isScheduled) { + assert(N->NumSuccsLeft > 0 && "NumSuccsLeft will underflow!"); --N->NumSuccsLeft; + } if (P.getLatency() != 0) { this->setDepthDirty(); N->setHeightDirty(); diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp index d1930b1..7eac4d8 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp @@ -134,17 +134,17 @@ void ScheduleDAGFast::Schedule() { /// the AvailableQueue if the count reaches zero. Also update its cycle bound. void ScheduleDAGFast::ReleasePred(SUnit *SU, SDep *PredEdge) { SUnit *PredSU = PredEdge->getSUnit(); - --PredSU->NumSuccsLeft; - + #ifndef NDEBUG - if (PredSU->NumSuccsLeft < 0) { + if (PredSU->NumSuccsLeft == 0) { errs() << "*** Scheduling failed! ***\n"; PredSU->dump(this); errs() << " has been released too many times!\n"; llvm_unreachable(0); } #endif - + --PredSU->NumSuccsLeft; + // If all the node's successors are scheduled, this node is ready // to be scheduled. Ignore the special EntrySU node. if (PredSU->NumSuccsLeft == 0 && PredSU != &EntrySU) { diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp index 628a2a87..f17fe23 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp @@ -108,17 +108,17 @@ void ScheduleDAGList::Schedule() { /// the PendingQueue if the count reaches zero. Also update its cycle bound. void ScheduleDAGList::ReleaseSucc(SUnit *SU, const SDep &D) { SUnit *SuccSU = D.getSUnit(); - --SuccSU->NumPredsLeft; - + #ifndef NDEBUG - if (SuccSU->NumPredsLeft < 0) { + if (SuccSU->NumPredsLeft == 0) { errs() << "*** Scheduling failed! ***\n"; SuccSU->dump(this); errs() << " has been released too many times!\n"; llvm_unreachable(0); } #endif - + --SuccSU->NumPredsLeft; + SuccSU->setDepthToAtLeast(SU->getDepth() + D.getLatency()); // If all the node's predecessors are scheduled, this node is ready diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index a9d1878..bd6e048 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -278,6 +278,7 @@ void ScheduleDAGRRList::CapturePred(SDep *PredEdge) { AvailableQueue->remove(PredSU); } + assert(PredSU->NumSuccsLeft < UINT_MAX && "NumSuccsLeft will overflow!"); ++PredSU->NumSuccsLeft; } @@ -824,17 +825,17 @@ void ScheduleDAGRRList::ListScheduleBottomUp() { /// the AvailableQueue if the count reaches zero. Also update its cycle bound. void ScheduleDAGRRList::ReleaseSucc(SUnit *SU, const SDep *SuccEdge) { SUnit *SuccSU = SuccEdge->getSUnit(); - --SuccSU->NumPredsLeft; - + #ifndef NDEBUG - if (SuccSU->NumPredsLeft < 0) { + if (SuccSU->NumPredsLeft == 0) { errs() << "*** Scheduling failed! ***\n"; SuccSU->dump(this); errs() << " has been released too many times!\n"; llvm_unreachable(0); } #endif - + --SuccSU->NumPredsLeft; + // If all the node's predecessors are scheduled, this node is ready // to be scheduled. Ignore the special ExitSU node. if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU) { |