aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-03-10 18:10:43 +0000
committerDan Gohman <gohman@apple.com>2009-03-10 18:10:43 +0000
commit1274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90 (patch)
treedf7d0960d110b797bd8707ac74ceafc0e7df0864
parent9200c89968e52a590ee0b96092a0a589aa138a6f (diff)
downloadexternal_llvm-1274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90.zip
external_llvm-1274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90.tar.gz
external_llvm-1274ced8a3f0fd1e9a6f7c7e17d69368c4f78b90.tar.bz2
Fix a post-RA scheduling liveness bug. When a basic block is being
scheduled in multiple regions, liveness data used by the anti-dependence breaker is carried from one region to the next, however the information reflects the state of the instructions before scheduling. After scheduling, there may be new live range overlaps. Handle this by pessimizing the liveness data carried between regions to the point where it will be conservatively correct now matter how the earlier region is scheduled. This fixes a miscompilation in 176.gcc with the post-RA scheduler enabled. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66558 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/PostRASchedulerList.cpp31
1 files changed, 22 insertions, 9 deletions
diff --git a/lib/CodeGen/PostRASchedulerList.cpp b/lib/CodeGen/PostRASchedulerList.cpp
index b6521e1..e742e3a 100644
--- a/lib/CodeGen/PostRASchedulerList.cpp
+++ b/lib/CodeGen/PostRASchedulerList.cpp
@@ -258,22 +258,19 @@ bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
for (MachineBasicBlock::iterator I = Current; I != MBB->begin(); ) {
MachineInstr *MI = prior(I);
if (isSchedulingBoundary(MI, Fn)) {
- if (I != Current) {
- Scheduler.Run(MBB, I, Current, CurrentCount);
- Scheduler.EmitSchedule();
- }
- Scheduler.Observe(MI, Count);
+ Scheduler.Run(MBB, I, Current, CurrentCount);
+ Scheduler.EmitSchedule();
Current = MI;
CurrentCount = Count - 1;
+ Scheduler.Observe(MI, CurrentCount);
}
I = MI;
--Count;
}
assert(Count == 0 && "Instruction count mismatch!");
- if (MBB->begin() != Current) {
- assert(CurrentCount != 0 && "Instruction count mismatch!");
- Scheduler.Run(MBB, MBB->begin(), Current, CurrentCount);
- }
+ assert(MBB->begin() == Current || CurrentCount != 0 &&
+ "Instruction count mismatch!");
+ Scheduler.Run(MBB, MBB->begin(), Current, CurrentCount);
Scheduler.EmitSchedule();
// Clean up register live-range state.
@@ -392,6 +389,22 @@ void SchedulePostRATDList::Schedule() {
/// instruction, which will not be scheduled.
///
void SchedulePostRATDList::Observe(MachineInstr *MI, unsigned Count) {
+ assert(Count < InsertPosIndex && "Instruction index out of expected range!");
+
+ // Any register which was defined within the previous scheduling region
+ // may have been rescheduled and its lifetime may overlap with registers
+ // in ways not reflected in our current liveness state. For each such
+ // register, adjust the liveness state to be conservatively correct.
+ for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg)
+ if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) {
+ assert(KillIndices[Reg] == ~0u && "Clobbered register is live!");
+ // Mark this register to be non-renamable.
+ Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);
+ // Move the def index to the end of the previous region, to reflect
+ // that the def could theoretically have been scheduled at the end.
+ DefIndices[Reg] = InsertPosIndex;
+ }
+
PrescanInstruction(MI);
ScanInstruction(MI, Count);
}