aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-12-20 00:55:43 +0000
committerChris Lattner <sabre@nondot.org>2010-12-20 00:55:43 +0000
commit37944985a569f8c2b0d75dafd9e2739a9887ac5d (patch)
tree3bdd110097a8ef325d2fc11058d28061be809b7c /lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
parente273690d7a52d2ab809e948ef93685885dde66bb (diff)
downloadexternal_llvm-37944985a569f8c2b0d75dafd9e2739a9887ac5d.zip
external_llvm-37944985a569f8c2b0d75dafd9e2739a9887ac5d.tar.gz
external_llvm-37944985a569f8c2b0d75dafd9e2739a9887ac5d.tar.bz2
Fix a bug in the scheduler's handling of "unspillable" vregs.
Imagine we see: EFLAGS = inst1 EFLAGS = inst2 FLAGS gpr = inst3 EFLAGS Previously, we would refuse to schedule inst2 because it clobbers the EFLAGS of the predecessor. However, it also uses the EFLAGS of the predecessor, so it is safe to emit. SDep edges ensure that the right order happens already anyway. This fixes 2 testsuite crashes with the X86 patch I'm going to commit next. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122211 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp15
1 files changed, 14 insertions, 1 deletions
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index 0f4d9c8..72bfe71 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -283,7 +283,7 @@ void ScheduleDAGRRList::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) {
Sequence.push_back(SU);
AvailableQueue->ScheduledNode(SU);
-
+
ReleasePredecessors(SU, CurCycle);
// Release all the implicit physical register defs that are live.
@@ -704,6 +704,19 @@ DelayForLiveRegsBottomUp(SUnit *SU, SmallVector<unsigned, 4> &LRegs) {
}
+ // Okay, we now know all of the live registers that are defined by an
+ // immediate predecessor. It is ok to kill these registers if we are also
+ // using it.
+ for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
+ I != E; ++I) {
+ if (I->isAssignedRegDep() &&
+ LiveRegCycles[I->getReg()] == I->getSUnit()->getHeight()) {
+ unsigned Reg = I->getReg();
+ if (RegAdded.erase(Reg))
+ LRegs.erase(std::find(LRegs.begin(), LRegs.end(), Reg));
+ }
+ }
+
return !LRegs.empty();
}