From 696a1307ba5e98fe813d21cecb9dbfd72be8562c Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Tue, 31 Mar 2009 08:27:09 +0000 Subject: Remove the "fast" cases for spill and restore point determination, as these were subtlely wrong in obscure cases. Patch the testcase to account for this change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68093 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/PreAllocSplitting.cpp | 185 ++++++++++++-------------------------- test/CodeGen/X86/pre-split4.ll | 2 +- 2 files changed, 60 insertions(+), 127 deletions(-) diff --git a/lib/CodeGen/PreAllocSplitting.cpp b/lib/CodeGen/PreAllocSplitting.cpp index f5e540d..d9775f9 100644 --- a/lib/CodeGen/PreAllocSplitting.cpp +++ b/lib/CodeGen/PreAllocSplitting.cpp @@ -232,68 +232,38 @@ PreAllocSplitting::findSpillPoint(MachineBasicBlock *MBB, MachineInstr *MI, unsigned &SpillIndex) { MachineBasicBlock::iterator Pt = MBB->begin(); - // Go top down if RefsInMBB is empty. - if (RefsInMBB.empty() && !DefMI) { - MachineBasicBlock::iterator MII = MBB->begin(); - MachineBasicBlock::iterator EndPt = MI; + MachineBasicBlock::iterator MII = MI; + MachineBasicBlock::iterator EndPt = DefMI + ? MachineBasicBlock::iterator(DefMI) : MBB->begin(); - if (MII == EndPt) return Pt; + while (MII != EndPt && !RefsInMBB.count(MII) && + MII->getOpcode() != TRI->getCallFrameSetupOpcode()) + --MII; + if (MII == EndPt || RefsInMBB.count(MII)) return Pt; - do { - ++MII; - unsigned Index = LIs->getInstructionIndex(MII); - unsigned Gap = LIs->findGapBeforeInstr(Index); - - // We can't insert the spill between the barrier (a call), and its - // corresponding call frame setup/teardown. - if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode()) { - bool reachedBarrier = false; - do { - if (MII == EndPt) { - reachedBarrier = true; - break; - } - ++MII; - } while (MII->getOpcode() != TRI->getCallFrameDestroyOpcode()); - - if (reachedBarrier) break; - } else if (Gap) { - Pt = MII; - SpillIndex = Gap; - break; - } - } while (MII != EndPt); - } else { - MachineBasicBlock::iterator MII = MI; - MachineBasicBlock::iterator EndPt = DefMI - ? MachineBasicBlock::iterator(DefMI) : MBB->begin(); + while (MII != EndPt && !RefsInMBB.count(MII)) { + unsigned Index = LIs->getInstructionIndex(MII); - while (MII != EndPt && !RefsInMBB.count(MII)) { - unsigned Index = LIs->getInstructionIndex(MII); - - // We can't insert the spill between the barrier (a call), and its - // corresponding call frame setup. - if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode()) { + // We can't insert the spill between the barrier (a call), and its + // corresponding call frame setup. + if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode()) { + while (MII->getOpcode() != TRI->getCallFrameSetupOpcode()) { --MII; - continue; - } if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode()) { - bool reachedBarrier = false; - while (MII->getOpcode() != TRI->getCallFrameSetupOpcode()) { - --MII; - if (MII == EndPt) { - reachedBarrier = true; - break; - } + if (MII == EndPt) { + return Pt; } - - if (reachedBarrier) break; - else continue; - } else if (LIs->hasGapBeforeInstr(Index)) { - Pt = MII; - SpillIndex = LIs->findGapBeforeInstr(Index, true); } - --MII; + continue; + } else if (LIs->hasGapBeforeInstr(Index)) { + Pt = MII; + SpillIndex = LIs->findGapBeforeInstr(Index, true); } + + if (RefsInMBB.count(MII)) + return Pt; + + + --MII; } return Pt; @@ -311,81 +281,44 @@ PreAllocSplitting::findRestorePoint(MachineBasicBlock *MBB, MachineInstr *MI, // FIXME: Allow spill to be inserted to the beginning of the mbb. Update mbb // begin index accordingly. MachineBasicBlock::iterator Pt = MBB->end(); - unsigned EndIdx = LIs->getMBBEndIdx(MBB); + MachineBasicBlock::iterator EndPt = MBB->getFirstTerminator(); - // Go bottom up if RefsInMBB is empty and the end of the mbb isn't beyond - // the last index in the live range. - if (RefsInMBB.empty() && LastIdx >= EndIdx) { - MachineBasicBlock::iterator MII = MBB->getFirstTerminator(); - MachineBasicBlock::iterator EndPt = MI; - - if (MII == EndPt) return Pt; - - --MII; - do { - unsigned Index = LIs->getInstructionIndex(MII); - unsigned Gap = LIs->findGapBeforeInstr(Index); - - // We can't insert a restore between the barrier (a call) and its - // corresponding call frame teardown. - if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode()) { - bool reachedBarrier = false; - while (MII->getOpcode() != TRI->getCallFrameSetupOpcode()) { - --MII; - if (MII == EndPt) { - reachedBarrier = true; - break; - } - } - - if (reachedBarrier) break; - else continue; - } else if (Gap) { - Pt = MII; - RestoreIndex = Gap; - break; - } - - --MII; - } while (MII != EndPt); - } else { - MachineBasicBlock::iterator MII = MI; - MII = ++MII; - - // FIXME: Limit the number of instructions to examine to reduce - // compile time? - while (MII != MBB->getFirstTerminator()) { - unsigned Index = LIs->getInstructionIndex(MII); - if (Index > LastIdx) - break; - unsigned Gap = LIs->findGapBeforeInstr(Index); + // We start at the call, so walk forward until we find the call frame teardown + // since we can't insert restores before that. Bail if we encounter a use + // during this time. + MachineBasicBlock::iterator MII = MI; + if (MII == EndPt) return Pt; + + while (MII != EndPt && !RefsInMBB.count(MII) && + MII->getOpcode() != TRI->getCallFrameDestroyOpcode()) + ++MII; + if (MII == EndPt || RefsInMBB.count(MII)) return Pt; + ++MII; + + // FIXME: Limit the number of instructions to examine to reduce + // compile time? + while (MII != EndPt) { + unsigned Index = LIs->getInstructionIndex(MII); + if (Index > LastIdx) + break; + unsigned Gap = LIs->findGapBeforeInstr(Index); - // We can't insert a restore between the barrier (a call) and its - // corresponding call frame teardown. - if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode()) { + // We can't insert a restore between the barrier (a call) and its + // corresponding call frame teardown. + if (MII->getOpcode() == TRI->getCallFrameSetupOpcode()) { + do { + if (MII == EndPt || RefsInMBB.count(MII)) return Pt; ++MII; - continue; - } else if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode()) { - bool reachedBarrier = false; - do { - if (MII == MBB->getFirstTerminator() || RefsInMBB.count(MII)) { - reachedBarrier = true; - break; - } - - ++MII; - } while (MII->getOpcode() != TRI->getCallFrameDestroyOpcode()); - - if (reachedBarrier) break; - } else if (Gap) { - Pt = MII; - RestoreIndex = Gap; - } - - if (RefsInMBB.count(MII)) - break; - ++MII; + } while (MII->getOpcode() != TRI->getCallFrameDestroyOpcode()); + } else if (Gap) { + Pt = MII; + RestoreIndex = Gap; } + + if (RefsInMBB.count(MII)) + return Pt; + + ++MII; } return Pt; diff --git a/test/CodeGen/X86/pre-split4.ll b/test/CodeGen/X86/pre-split4.ll index 44ea375..013402d 100644 --- a/test/CodeGen/X86/pre-split4.ll +++ b/test/CodeGen/X86/pre-split4.ll @@ -1,5 +1,5 @@ ; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -pre-alloc-split -stats |& \ -; RUN: grep {pre-alloc-split} | grep {Number of intervals split} | grep 4 +; RUN: grep {pre-alloc-split} | grep {Number of intervals split} | grep 2 define i32 @main(i32 %argc, i8** %argv) nounwind { entry: -- cgit v1.1