diff options
author | Andrew Trick <atrick@apple.com> | 2012-06-29 03:23:24 +0000 |
---|---|---|
committer | Andrew Trick <atrick@apple.com> | 2012-06-29 03:23:24 +0000 |
commit | 5559ffae2beb0adc868a0839a3bb560a063cc3e1 (patch) | |
tree | b0a9502c7ecce108406e6a94325cc2cef8184385 /lib/CodeGen/MachineScheduler.cpp | |
parent | 7f8c74cfaebb4b58b283a1875d3205704ce5be07 (diff) |
misched: avoid scheduling instructions that can't be dispatched.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159408 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineScheduler.cpp')
-rw-r--r-- | lib/CodeGen/MachineScheduler.cpp | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index 8040c3def2..18e61e0a78 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -824,6 +824,8 @@ class ConvergingScheduler : public MachineSchedStrategy { return Available.getID() == ConvergingScheduler::TopQID; } + bool checkHazard(SUnit *SU); + void releaseNode(SUnit *SU, unsigned ReadyCycle); void bumpCycle(); @@ -932,6 +934,29 @@ void ConvergingScheduler::releaseBottomNode(SUnit *SU) { Bot.releaseNode(SU, SU->BotReadyCycle); } +/// Does this SU have a hazard within the current instruction group. +/// +/// The scheduler supports two modes of hazard recognition. The first is the +/// ScheduleHazardRecognizer API. It is a fully general hazard recognizer that +/// supports highly complicated in-order reservation tables +/// (ScoreboardHazardRecognizer) and arbitraty target-specific logic. +/// +/// The second is a streamlined mechanism that checks for hazards based on +/// simple counters that the scheduler itself maintains. It explicitly checks +/// for instruction dispatch limitations, including the number of micro-ops that +/// can dispatch per cycle. +/// +/// TODO: Also check whether the SU must start a new group. +bool ConvergingScheduler::SchedBoundary::checkHazard(SUnit *SU) { + if (HazardRec->isEnabled()) + return HazardRec->getHazardType(SU) != ScheduleHazardRecognizer::NoHazard; + + if (IssueCount + DAG->getNumMicroOps(SU->getInstr()) > DAG->getIssueWidth()) + return true; + + return false; +} + void ConvergingScheduler::SchedBoundary::releaseNode(SUnit *SU, unsigned ReadyCycle) { if (ReadyCycle < MinReadyCycle) @@ -939,9 +964,7 @@ void ConvergingScheduler::SchedBoundary::releaseNode(SUnit *SU, // Check for interlocks first. For the purpose of other heuristics, an // instruction that cannot issue appears as if it's not in the ReadyQueue. - if (ReadyCycle > CurrCycle - || (HazardRec->isEnabled() && (HazardRec->getHazardType(SU) - != ScheduleHazardRecognizer::NoHazard))) + if (ReadyCycle > CurrCycle || checkHazard(SU)) Pending.push(SU); else Available.push(SU); @@ -985,7 +1008,8 @@ void ConvergingScheduler::SchedBoundary::bumpNode(SUnit *SU) { } HazardRec->EmitInstruction(SU); } - // Check the instruction group size limit. + // Check the instruction group dispatch limit. + // TODO: Check if this SU must end a dispatch group. IssueCount += DAG->getNumMicroOps(SU->getInstr()); if (IssueCount >= DAG->getIssueWidth()) { DEBUG(dbgs() << "*** Max instrs at cycle " << CurrCycle << '\n'); @@ -1012,8 +1036,7 @@ void ConvergingScheduler::SchedBoundary::releasePending() { if (ReadyCycle > CurrCycle) continue; - if (HazardRec->isEnabled() - && HazardRec->getHazardType(SU) != ScheduleHazardRecognizer::NoHazard) + if (checkHazard(SU)) continue; Available.push(SU); |