mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-21 02:24:22 +00:00
Don't advance the hazard recognizer when there are no hazards and no instructions
to be emitted. Don't add one to the latency of a completed instruction if the latency of the op is 0. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26718 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -357,6 +357,8 @@ void ScheduleDAGList::BuildSchedUnits() {
|
|||||||
// Remove MainNode from FlaggedNodes again.
|
// Remove MainNode from FlaggedNodes again.
|
||||||
SU->FlaggedNodes.pop_back();
|
SU->FlaggedNodes.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
|
DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
|
||||||
SUnits[su].dumpAll(&DAG));
|
SUnits[su].dumpAll(&DAG));
|
||||||
}
|
}
|
||||||
@ -550,13 +552,13 @@ void ScheduleDAGList::ReleaseSucc(SUnit *SuccSU, bool isChain) {
|
|||||||
unsigned AvailableCycle = 0;
|
unsigned AvailableCycle = 0;
|
||||||
for (std::set<std::pair<SUnit*, bool> >::iterator I = SuccSU->Preds.begin(),
|
for (std::set<std::pair<SUnit*, bool> >::iterator I = SuccSU->Preds.begin(),
|
||||||
E = SuccSU->Preds.end(); I != E; ++I) {
|
E = SuccSU->Preds.end(); I != E; ++I) {
|
||||||
// If this is a token edge, we don't need to wait for the full latency of
|
// If this is a token edge, we don't need to wait for the latency of the
|
||||||
// the preceeding instruction (e.g. a long-latency load) unless there is
|
// preceeding instruction (e.g. a long-latency load) unless there is also
|
||||||
// also some other data dependence.
|
// some other data dependence.
|
||||||
unsigned PredDoneCycle = I->first->Cycle;
|
unsigned PredDoneCycle = I->first->Cycle;
|
||||||
if (!I->second)
|
if (!I->second)
|
||||||
PredDoneCycle += I->first->Latency;
|
PredDoneCycle += I->first->Latency;
|
||||||
else
|
else if (I->first->Latency)
|
||||||
PredDoneCycle += 1;
|
PredDoneCycle += 1;
|
||||||
|
|
||||||
AvailableCycle = std::max(AvailableCycle, PredDoneCycle);
|
AvailableCycle = std::max(AvailableCycle, PredDoneCycle);
|
||||||
@ -608,7 +610,7 @@ void ScheduleDAGList::ListScheduleTopDown() {
|
|||||||
while (!AvailableQueue->empty() || !PendingQueue.empty()) {
|
while (!AvailableQueue->empty() || !PendingQueue.empty()) {
|
||||||
// Check to see if any of the pending instructions are ready to issue. If
|
// Check to see if any of the pending instructions are ready to issue. If
|
||||||
// so, add them to the available queue.
|
// so, add them to the available queue.
|
||||||
for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i)
|
for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) {
|
||||||
if (PendingQueue[i].first == CurCycle) {
|
if (PendingQueue[i].first == CurCycle) {
|
||||||
AvailableQueue->push(PendingQueue[i].second);
|
AvailableQueue->push(PendingQueue[i].second);
|
||||||
PendingQueue[i].second->isAvailable = true;
|
PendingQueue[i].second->isAvailable = true;
|
||||||
@ -618,54 +620,67 @@ void ScheduleDAGList::ListScheduleTopDown() {
|
|||||||
} else {
|
} else {
|
||||||
assert(PendingQueue[i].first > CurCycle && "Negative latency?");
|
assert(PendingQueue[i].first > CurCycle && "Negative latency?");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SUnit *FoundNode = 0;
|
// If there are no instructions available, don't try to issue anything, and
|
||||||
|
// don't advance the hazard recognizer.
|
||||||
|
if (AvailableQueue->empty()) {
|
||||||
|
++CurCycle;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SUnit *FoundSUnit = 0;
|
||||||
|
SDNode *FoundNode = 0;
|
||||||
|
|
||||||
bool HasNoopHazards = false;
|
bool HasNoopHazards = false;
|
||||||
while (!AvailableQueue->empty()) {
|
while (!AvailableQueue->empty()) {
|
||||||
SUnit *CurNode = AvailableQueue->pop();
|
SUnit *CurSUnit = AvailableQueue->pop();
|
||||||
|
|
||||||
// Get the node represented by this SUnit.
|
// Get the node represented by this SUnit.
|
||||||
SDNode *N = CurNode->Node;
|
FoundNode = CurSUnit->Node;
|
||||||
|
|
||||||
// If this is a pseudo op, like copyfromreg, look to see if there is a
|
// If this is a pseudo op, like copyfromreg, look to see if there is a
|
||||||
// real target node flagged to it. If so, use the target node.
|
// real target node flagged to it. If so, use the target node.
|
||||||
for (unsigned i = 0, e = CurNode->FlaggedNodes.size();
|
for (unsigned i = 0, e = CurSUnit->FlaggedNodes.size();
|
||||||
N->getOpcode() < ISD::BUILTIN_OP_END && i != e; ++i)
|
FoundNode->getOpcode() < ISD::BUILTIN_OP_END && i != e; ++i)
|
||||||
N = CurNode->FlaggedNodes[i];
|
FoundNode = CurSUnit->FlaggedNodes[i];
|
||||||
|
|
||||||
HazardRecognizer::HazardType HT = HazardRec->getHazardType(N);
|
HazardRecognizer::HazardType HT = HazardRec->getHazardType(FoundNode);
|
||||||
if (HT == HazardRecognizer::NoHazard) {
|
if (HT == HazardRecognizer::NoHazard) {
|
||||||
FoundNode = CurNode;
|
FoundSUnit = CurSUnit;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember if this is a noop hazard.
|
// Remember if this is a noop hazard.
|
||||||
HasNoopHazards |= HT == HazardRecognizer::NoopHazard;
|
HasNoopHazards |= HT == HazardRecognizer::NoopHazard;
|
||||||
|
|
||||||
NotReady.push_back(CurNode);
|
NotReady.push_back(CurSUnit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the nodes that aren't ready back onto the available list.
|
// Add the nodes that aren't ready back onto the available list.
|
||||||
|
if (!NotReady.empty()) {
|
||||||
AvailableQueue->push_all(NotReady);
|
AvailableQueue->push_all(NotReady);
|
||||||
NotReady.clear();
|
NotReady.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// If we found a node to schedule, do it now.
|
// If we found a node to schedule, do it now.
|
||||||
if (FoundNode) {
|
if (FoundSUnit) {
|
||||||
ScheduleNodeTopDown(FoundNode, CurCycle);
|
ScheduleNodeTopDown(FoundSUnit, CurCycle);
|
||||||
HazardRec->EmitInstruction(FoundNode->Node);
|
HazardRec->EmitInstruction(FoundNode);
|
||||||
FoundNode->isScheduled = true;
|
FoundSUnit->isScheduled = true;
|
||||||
AvailableQueue->ScheduledNode(FoundNode);
|
AvailableQueue->ScheduledNode(FoundSUnit);
|
||||||
|
|
||||||
// If this is a pseudo-op node, we don't want to increment the current
|
// If this is a pseudo-op node, we don't want to increment the current
|
||||||
// cycle.
|
// cycle.
|
||||||
if (FoundNode->Latency == 0)
|
if (FoundSUnit->Latency) // Don't increment CurCycle for pseudo-ops!
|
||||||
continue; // Don't increment for pseudo-ops!
|
++CurCycle;
|
||||||
} else if (!HasNoopHazards) {
|
} else if (!HasNoopHazards) {
|
||||||
// Otherwise, we have a pipeline stall, but no other problem, just advance
|
// Otherwise, we have a pipeline stall, but no other problem, just advance
|
||||||
// the current cycle and try again.
|
// the current cycle and try again.
|
||||||
DEBUG(std::cerr << "*** Advancing cycle, no work to do\n");
|
DEBUG(std::cerr << "*** Advancing cycle, no work to do\n");
|
||||||
HazardRec->AdvanceCycle();
|
HazardRec->AdvanceCycle();
|
||||||
++NumStalls;
|
++NumStalls;
|
||||||
|
++CurCycle;
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, we have no instructions to issue and we have instructions
|
// Otherwise, we have no instructions to issue and we have instructions
|
||||||
// that will fault if we don't do this right. This is the case for
|
// that will fault if we don't do this right. This is the case for
|
||||||
@ -674,9 +689,9 @@ void ScheduleDAGList::ListScheduleTopDown() {
|
|||||||
HazardRec->EmitNoop();
|
HazardRec->EmitNoop();
|
||||||
Sequence.push_back(0); // NULL SUnit* -> noop
|
Sequence.push_back(0); // NULL SUnit* -> noop
|
||||||
++NumNoops;
|
++NumNoops;
|
||||||
}
|
|
||||||
++CurCycle;
|
++CurCycle;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// Verify that all SUnits were scheduled.
|
// Verify that all SUnits were scheduled.
|
||||||
|
Reference in New Issue
Block a user