diff options
author | Owen Anderson <resistor@mac.com> | 2009-02-05 05:58:41 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2009-02-05 05:58:41 +0000 |
commit | 5734c94ec24a6f4ee940e0b146df48c647c7a4dc (patch) | |
tree | 5c1a6c6675202cb975014670e095373e18cfd3f6 | |
parent | ce459b1e28713dd85632388598eb6a29255811cd (diff) | |
download | external_llvm-5734c94ec24a6f4ee940e0b146df48c647c7a4dc.zip external_llvm-5734c94ec24a6f4ee940e0b146df48c647c7a4dc.tar.gz external_llvm-5734c94ec24a6f4ee940e0b146df48c647c7a4dc.tar.bz2 |
Pre-alloc splitting needs to be more careful to avoid inserting spills/restores
between call frame setup/restore points. Unfortunately, this regresses
code size a bit, but at least it's correct now!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63837 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/PreAllocSplitting.cpp | 94 |
1 files changed, 72 insertions, 22 deletions
diff --git a/lib/CodeGen/PreAllocSplitting.cpp b/lib/CodeGen/PreAllocSplitting.cpp index 99fdb84..dfff87a 100644 --- a/lib/CodeGen/PreAllocSplitting.cpp +++ b/lib/CodeGen/PreAllocSplitting.cpp @@ -228,28 +228,52 @@ PreAllocSplitting::findSpillPoint(MachineBasicBlock *MBB, MachineInstr *MI, ++MII; unsigned Index = LIs->getInstructionIndex(MII); unsigned Gap = LIs->findGapBeforeInstr(Index); - if (Gap) { - Pt = MII; - SpillIndex = Gap; - break; // We can't insert the spill between the barrier (a call), and its - // corresponding call frame setup. - } else if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode() && - MII == MachineBasicBlock::iterator(MI)) + // 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(); - // We can't insert the spill between the barrier (a call), and its - // corresponding call frame setup. - if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode()) --MII; while (MII != EndPt && !RefsInMBB.count(MII)) { unsigned Index = LIs->getInstructionIndex(MII); - if (LIs->hasGapBeforeInstr(Index)) { + + // We can't insert the spill between the barrier (a call), and its + // corresponding call frame setup. + if (prior(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 (reachedBarrier) break; + else continue; + } else if (LIs->hasGapBeforeInstr(Index)) { Pt = MII; SpillIndex = LIs->findGapBeforeInstr(Index, true); } @@ -283,25 +307,32 @@ PreAllocSplitting::findRestorePoint(MachineBasicBlock *MBB, MachineInstr *MI, do { unsigned Index = LIs->getInstructionIndex(MII); unsigned Gap = LIs->findGapBeforeInstr(Index); - if (Gap) { - Pt = MII; - RestoreIndex = Gap; - break; // We can't insert a restore between the barrier (a call) and its // corresponding call frame teardown. - } else if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode() && - prior(MII) == MachineBasicBlock::iterator(MI)) + 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; - // We can't insert a restore between the barrier (a call) and its - // corresponding call frame teardown. - if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode()) - ++MII; // FIXME: Limit the number of instructions to examine to reduce // compile time? @@ -310,10 +341,29 @@ PreAllocSplitting::findRestorePoint(MachineBasicBlock *MBB, MachineInstr *MI, if (Index > LastIdx) break; unsigned Gap = LIs->findGapBeforeInstr(Index); - if (Gap) { + + // We can't insert a restore between the barrier (a call) and its + // corresponding call frame teardown. + if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode()) { + ++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; |