Skip to content

Commit 64613ac

Browse files
author
Dan Gohman
committed
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. llvm-svn: 66558
1 parent 4ea568f commit 64613ac

File tree

1 file changed

+22
-9
lines changed

1 file changed

+22
-9
lines changed

llvm/lib/CodeGen/PostRASchedulerList.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -258,22 +258,19 @@ bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
258258
for (MachineBasicBlock::iterator I = Current; I != MBB->begin(); ) {
259259
MachineInstr *MI = prior(I);
260260
if (isSchedulingBoundary(MI, Fn)) {
261-
if (I != Current) {
262-
Scheduler.Run(MBB, I, Current, CurrentCount);
263-
Scheduler.EmitSchedule();
264-
}
265-
Scheduler.Observe(MI, Count);
261+
Scheduler.Run(MBB, I, Current, CurrentCount);
262+
Scheduler.EmitSchedule();
266263
Current = MI;
267264
CurrentCount = Count - 1;
265+
Scheduler.Observe(MI, CurrentCount);
268266
}
269267
I = MI;
270268
--Count;
271269
}
272270
assert(Count == 0 && "Instruction count mismatch!");
273-
if (MBB->begin() != Current) {
274-
assert(CurrentCount != 0 && "Instruction count mismatch!");
275-
Scheduler.Run(MBB, MBB->begin(), Current, CurrentCount);
276-
}
271+
assert(MBB->begin() == Current || CurrentCount != 0 &&
272+
"Instruction count mismatch!");
273+
Scheduler.Run(MBB, MBB->begin(), Current, CurrentCount);
277274
Scheduler.EmitSchedule();
278275

279276
// Clean up register live-range state.
@@ -392,6 +389,22 @@ void SchedulePostRATDList::Schedule() {
392389
/// instruction, which will not be scheduled.
393390
///
394391
void SchedulePostRATDList::Observe(MachineInstr *MI, unsigned Count) {
392+
assert(Count < InsertPosIndex && "Instruction index out of expected range!");
393+
394+
// Any register which was defined within the previous scheduling region
395+
// may have been rescheduled and its lifetime may overlap with registers
396+
// in ways not reflected in our current liveness state. For each such
397+
// register, adjust the liveness state to be conservatively correct.
398+
for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg)
399+
if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) {
400+
assert(KillIndices[Reg] == ~0u && "Clobbered register is live!");
401+
// Mark this register to be non-renamable.
402+
Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);
403+
// Move the def index to the end of the previous region, to reflect
404+
// that the def could theoretically have been scheduled at the end.
405+
DefIndices[Reg] = InsertPosIndex;
406+
}
407+
395408
PrescanInstruction(MI);
396409
ScanInstruction(MI, Count);
397410
}

0 commit comments

Comments
 (0)