diff options
-rw-r--r-- | lib/CodeGen/InlineSpiller.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/LiveRangeEdit.cpp | 18 | ||||
-rw-r--r-- | lib/CodeGen/LiveRangeEdit.h | 7 |
3 files changed, 25 insertions, 4 deletions
diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp index 8f38887..9bf810e 100644 --- a/lib/CodeGen/InlineSpiller.cpp +++ b/lib/CodeGen/InlineSpiller.cpp @@ -957,7 +957,7 @@ void InlineSpiller::reMaterializeAll() { if (DeadDefs.empty()) return; DEBUG(dbgs() << "Remat created " << DeadDefs.size() << " dead defs.\n"); - Edit->eliminateDeadDefs(DeadDefs, LIS, VRM, TII); + Edit->eliminateDeadDefs(DeadDefs, LIS, VRM, TII, RegsToSpill); // Get rid of deleted and empty intervals. for (unsigned i = RegsToSpill.size(); i != 0; --i) { @@ -1240,7 +1240,7 @@ void InlineSpiller::spillAll() { // Hoisted spills may cause dead code. if (!DeadDefs.empty()) { DEBUG(dbgs() << "Eliminating " << DeadDefs.size() << " dead defs\n"); - Edit->eliminateDeadDefs(DeadDefs, LIS, VRM, TII); + Edit->eliminateDeadDefs(DeadDefs, LIS, VRM, TII, RegsToSpill); } // Finally delete the SnippetCopies. diff --git a/lib/CodeGen/LiveRangeEdit.cpp b/lib/CodeGen/LiveRangeEdit.cpp index 428b252..a470877 100644 --- a/lib/CodeGen/LiveRangeEdit.cpp +++ b/lib/CodeGen/LiveRangeEdit.cpp @@ -210,7 +210,8 @@ bool LiveRangeEdit::foldAsLoad(LiveInterval *LI, void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead, LiveIntervals &LIS, VirtRegMap &VRM, - const TargetInstrInfo &TII) { + const TargetInstrInfo &TII, + ArrayRef<unsigned> RegsBeingSpilled) { SetVector<LiveInterval*, SmallVector<LiveInterval*, 8>, SmallPtrSet<LiveInterval*, 8> > ToShrink; @@ -290,6 +291,21 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead, delegate_->LRE_WillShrinkVirtReg(LI->reg); if (!LIS.shrinkToUses(LI, &Dead)) continue; + + // Don't create new intervals for a register being spilled. + // The new intervals would have to be spilled anyway so its not worth it. + // Also they currently aren't spilled so creating them and not spilling + // them results in incorrect code. + bool BeingSpilled = false; + for (unsigned i = 0, e = RegsBeingSpilled.size(); i != e; ++i) { + if (LI->reg == RegsBeingSpilled[i]) { + BeingSpilled = true; + break; + } + } + + if (BeingSpilled) continue; + // LI may have been separated, create new intervals. LI->RenumberValues(LIS); diff --git a/lib/CodeGen/LiveRangeEdit.h b/lib/CodeGen/LiveRangeEdit.h index 9b0a671..057d9bb 100644 --- a/lib/CodeGen/LiveRangeEdit.h +++ b/lib/CodeGen/LiveRangeEdit.h @@ -191,9 +191,14 @@ public: /// eliminateDeadDefs - Try to delete machine instructions that are now dead /// (allDefsAreDead returns true). This may cause live intervals to be trimmed /// and further dead efs to be eliminated. + /// RegsBeingSpilled lists registers currently being spilled by the register + /// allocator. These registers should not be split into new intervals + /// as currently those new intervals are not guaranteed to spill. void eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead, LiveIntervals&, VirtRegMap&, - const TargetInstrInfo&); + const TargetInstrInfo&, + ArrayRef<unsigned> RegsBeingSpilled + = ArrayRef<unsigned>()); /// calculateRegClassAndHint - Recompute register class and hint for each new /// register. |