mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-17 23:44:43 +00:00
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
This commit is contained in:
parent
69cc57c325
commit
c277ab08a2
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user