summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-05-11 18:25:10 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-05-11 18:25:10 +0000
commit443443cc8399d6753cac828516ea27531e296769 (patch)
treee8669a8989b387960be3c07d97791365c010b9f8 /lib
parente8b9f16a4c2db968db9d3d147b95ab1293d3383c (diff)
downloadllvm-443443cc8399d6753cac828516ea27531e296769.tar.gz
llvm-443443cc8399d6753cac828516ea27531e296769.tar.bz2
llvm-443443cc8399d6753cac828516ea27531e296769.tar.xz
Avoid hoisting spills when looking at a copy from another register that is also
about to be spilled. This can only happen when two extra snippet registers are included in the spill, and there is a copy between them. Hoisting the spill creates problems because the hoist will mark the copy for later dead code elimination, and spilling the second register will turn the copy into a spill. <rdar://problem/9420853> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131192 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/InlineSpiller.cpp23
1 files changed, 16 insertions, 7 deletions
diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp
index c3663d3651..19ae333115 100644
--- a/lib/CodeGen/InlineSpiller.cpp
+++ b/lib/CodeGen/InlineSpiller.cpp
@@ -855,6 +855,7 @@ void InlineSpiller::insertSpill(LiveInterval &NewLI, const LiveInterval &OldLI,
/// spillAroundUses - insert spill code around each use of Reg.
void InlineSpiller::spillAroundUses(unsigned Reg) {
+ DEBUG(dbgs() << "spillAroundUses " << PrintReg(Reg) << '\n');
LiveInterval &OldLI = LIS.getInterval(Reg);
// Iterate over instructions using Reg.
@@ -902,6 +903,12 @@ void InlineSpiller::spillAroundUses(unsigned Reg) {
// Check for a sibling copy.
unsigned SibReg = isFullCopyOf(MI, Reg);
if (SibReg && isSibling(SibReg)) {
+ // This may actually be a copy between snippets.
+ if (isRegToSpill(SibReg)) {
+ DEBUG(dbgs() << "Found new snippet copy: " << *MI);
+ SnippetCopies.insert(MI);
+ continue;
+ }
if (Writes) {
// Hoist the spill of a sib-reg copy.
if (hoistSpill(OldLI, MI)) {
@@ -983,13 +990,15 @@ void InlineSpiller::spillAll() {
}
// Finally delete the SnippetCopies.
- for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Edit->getReg());
- MachineInstr *MI = RI.skipInstruction();) {
- assert(SnippetCopies.count(MI) && "Remaining use wasn't a snippet copy");
- // FIXME: Do this with a LiveRangeEdit callback.
- VRM.RemoveMachineInstrFromMaps(MI);
- LIS.RemoveMachineInstrFromMaps(MI);
- MI->eraseFromParent();
+ for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) {
+ for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(RegsToSpill[i]);
+ MachineInstr *MI = RI.skipInstruction();) {
+ assert(SnippetCopies.count(MI) && "Remaining use wasn't a snippet copy");
+ // FIXME: Do this with a LiveRangeEdit callback.
+ VRM.RemoveMachineInstrFromMaps(MI);
+ LIS.RemoveMachineInstrFromMaps(MI);
+ MI->eraseFromParent();
+ }
}
// Delete all spilled registers.