diff options
| author | Dan Gohman <gohman@apple.com> | 2009-01-16 22:10:20 +0000 |
|---|---|---|
| committer | Dan Gohman <gohman@apple.com> | 2009-01-16 22:10:20 +0000 |
| commit | f7119393a97c2a10757084b6bc186380f8c19a73 (patch) | |
| tree | 7824f429705e746de59c9c813df694fd3f19fab0 /lib/CodeGen/ScheduleDAGInstrs.cpp | |
| parent | 49bb50e0b65d4646a1d44eec3196c003c13caa96 (diff) | |
Instead of adding dependence edges between terminator instructions
and every other instruction in their blocks to keep the terminator
instructions at the end, teach the post-RA scheduler how to operate
on ranges of instructions, and exclude terminators from the range
of instructions that get scheduled.
Also, exclude mid-block labels, such as EH_LABEL instructions, and
schedule code before them separately from code after them. This
fixes problems with the post-RA scheduler moving code past
EH_LABELs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62366 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/ScheduleDAGInstrs.cpp')
| -rw-r--r-- | lib/CodeGen/ScheduleDAGInstrs.cpp | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp index 7b5690c07b..0ffdd05c2e 100644 --- a/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -112,10 +112,16 @@ void ScheduleDAGInstrs::BuildSchedGraph() { std::map<const Value *, SUnit *> MemDefs; std::map<const Value *, std::vector<SUnit *> > MemUses; - // Terminators can perform control transfers, we we need to make sure that - // all the work of the block is done before the terminator. + // If we have an SUnit which is representing a terminator instruction, we + // can use it as a place-holder successor for inter-block dependencies. SUnit *Terminator = 0; + // Terminators can perform control transfers, we we need to make sure that + // all the work of the block is done before the terminator. Labels can + // mark points of interest for various types of meta-data (eg. EH data), + // and we need to make sure nothing is scheduled around them. + SUnit *SchedulingBarrier = 0; + LoopDependencies LoopRegs(MLI, MDT); // Track which regs are live into a loop, to help guide back-edge-aware @@ -137,7 +143,7 @@ void ScheduleDAGInstrs::BuildSchedGraph() { unsigned SpecialAddressLatency = TM.getSubtarget<TargetSubtarget>().getSpecialAddressLatency(); - for (MachineBasicBlock::iterator MII = BB->end(), MIE = BB->begin(); + for (MachineBasicBlock::iterator MII = End, MIE = Begin; MII != MIE; --MII) { MachineInstr *MI = prior(MII); const TargetInstrDesc &TID = MI->getDesc(); @@ -368,11 +374,26 @@ void ScheduleDAGInstrs::BuildSchedGraph() { } } - // Add chain edges from the terminator to ensure that all the work of the - // block is completed before any control transfers. - if (Terminator && SU->Succs.empty()) - Terminator->addPred(SDep(SU, SDep::Order, SU->Latency)); + // Add chain edges from terminators and labels to ensure that no + // instructions are scheduled past them. + if (SchedulingBarrier && SU->Succs.empty()) + SchedulingBarrier->addPred(SDep(SU, SDep::Order, SU->Latency)); + // If we encounter a mid-block label, we need to go back and add + // dependencies on SUnits we've already processed to prevent the + // label from moving downward. + if (MI->isLabel()) + for (SUnit *I = SU; I != &SUnits[0]; --I) { + SUnit *SuccSU = SU-1; + SuccSU->addPred(SDep(SU, SDep::Order, SU->Latency)); + MachineInstr *SuccMI = SuccSU->getInstr(); + if (SuccMI->getDesc().isTerminator() || SuccMI->isLabel()) + break; + } + // If this instruction obstructs all scheduling, remember it. if (TID.isTerminator() || MI->isLabel()) + SchedulingBarrier = SU; + // If this instruction is a terminator, remember it. + if (TID.isTerminator()) Terminator = SU; } @@ -413,8 +434,11 @@ std::string ScheduleDAGInstrs::getGraphNodeLabel(const SUnit *SU) const { MachineBasicBlock *ScheduleDAGInstrs::EmitSchedule() { // For MachineInstr-based scheduling, we're rescheduling the instructions in // the block, so start by removing them from the block. - while (!BB->empty()) - BB->remove(BB->begin()); + while (Begin != End) { + MachineBasicBlock::iterator I = Begin; + ++Begin; + BB->remove(I); + } // Then re-insert them according to the given schedule. for (unsigned i = 0, e = Sequence.size(); i != e; i++) { @@ -425,7 +449,7 @@ MachineBasicBlock *ScheduleDAGInstrs::EmitSchedule() { continue; } - BB->push_back(SU->getInstr()); + BB->insert(End, SU->getInstr()); } return BB; |
