aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2009-02-05 05:58:41 +0000
committerOwen Anderson <resistor@mac.com>2009-02-05 05:58:41 +0000
commit5734c94ec24a6f4ee940e0b146df48c647c7a4dc (patch)
tree5c1a6c6675202cb975014670e095373e18cfd3f6
parentce459b1e28713dd85632388598eb6a29255811cd (diff)
downloadexternal_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.cpp94
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;