summaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-03-29 21:20:19 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-03-29 21:20:19 +0000
commit6094bd87d845afabba5b99ec4848fa6116bac682 (patch)
tree16e0d4e352d6c8446a6e31a831d3740fd0570808 /lib/CodeGen
parent3d090558510de9a3601965630c5c82d663c346ce (diff)
downloadllvm-6094bd87d845afabba5b99ec4848fa6116bac682.tar.gz
llvm-6094bd87d845afabba5b99ec4848fa6116bac682.tar.bz2
llvm-6094bd87d845afabba5b99ec4848fa6116bac682.tar.xz
Recompute register class and hint for registers created during spilling.
The spill weight is not recomputed for an unspillable register - it stays infinite. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128490 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CalcSpillWeights.cpp46
-rw-r--r--lib/CodeGen/InlineSpiller.cpp74
-rw-r--r--lib/CodeGen/LiveRangeEdit.cpp11
-rw-r--r--lib/CodeGen/LiveRangeEdit.h5
-rw-r--r--lib/CodeGen/RegAllocGreedy.cpp1
-rw-r--r--lib/CodeGen/SplitKit.cpp10
6 files changed, 87 insertions, 60 deletions
diff --git a/lib/CodeGen/CalcSpillWeights.cpp b/lib/CodeGen/CalcSpillWeights.cpp
index 5637f4e024..86ab2b6f27 100644
--- a/lib/CodeGen/CalcSpillWeights.cpp
+++ b/lib/CodeGen/CalcSpillWeights.cpp
@@ -103,6 +103,9 @@ void VirtRegAuxInfo::CalculateWeightAndHint(LiveInterval &li) {
// Don't recompute a target specific hint.
bool noHint = mri.getRegAllocationHint(li.reg).first != 0;
+ // Don't recompute spill weight for an unspillable register.
+ bool Spillable = li.isSpillable();
+
for (MachineRegisterInfo::reg_iterator I = mri.reg_begin(li.reg);
MachineInstr *mi = I.skipInstruction();) {
if (mi->isIdentityCopy() || mi->isImplicitDef() || mi->isDebugValue())
@@ -110,25 +113,28 @@ void VirtRegAuxInfo::CalculateWeightAndHint(LiveInterval &li) {
if (!visited.insert(mi))
continue;
- // Get loop info for mi.
- if (mi->getParent() != mbb) {
- mbb = mi->getParent();
- loop = loops_.getLoopFor(mbb);
- loopDepth = loop ? loop->getLoopDepth() : 0;
- isExiting = loop ? loop->isLoopExiting(mbb) : false;
+ float weight = 1.0f;
+ if (Spillable) {
+ // Get loop info for mi.
+ if (mi->getParent() != mbb) {
+ mbb = mi->getParent();
+ loop = loops_.getLoopFor(mbb);
+ loopDepth = loop ? loop->getLoopDepth() : 0;
+ isExiting = loop ? loop->isLoopExiting(mbb) : false;
+ }
+
+ // Calculate instr weight.
+ bool reads, writes;
+ tie(reads, writes) = mi->readsWritesVirtualRegister(li.reg);
+ weight = LiveIntervals::getSpillWeight(writes, reads, loopDepth);
+
+ // Give extra weight to what looks like a loop induction variable update.
+ if (writes && isExiting && lis_.isLiveOutOfMBB(li, mbb))
+ weight *= 3;
+
+ totalWeight += weight;
}
- // Calculate instr weight.
- bool reads, writes;
- tie(reads, writes) = mi->readsWritesVirtualRegister(li.reg);
- float weight = LiveIntervals::getSpillWeight(writes, reads, loopDepth);
-
- // Give extra weight to what looks like a loop induction variable update.
- if (writes && isExiting && lis_.isLiveOutOfMBB(li, mbb))
- weight *= 3;
-
- totalWeight += weight;
-
// Get allocation hints from copies.
if (noHint || !mi->isCopy())
continue;
@@ -150,10 +156,14 @@ void VirtRegAuxInfo::CalculateWeightAndHint(LiveInterval &li) {
// Always prefer the physreg hint.
if (unsigned hint = hintPhys ? hintPhys : hintVirt) {
mri.setRegAllocationHint(li.reg, 0, hint);
- // Weakly boost the spill weifght of hinted registers.
+ // Weakly boost the spill weight of hinted registers.
totalWeight *= 1.01F;
}
+ // If the live interval was already unspillable, leave it that way.
+ if (!Spillable)
+ return;
+
// Mark li as unspillable if all live ranges are tiny.
if (li.isZeroLength()) {
li.markNotSpillable();
diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp
index 397943bf3c..d0c750777f 100644
--- a/lib/CodeGen/InlineSpiller.cpp
+++ b/lib/CodeGen/InlineSpiller.cpp
@@ -139,6 +139,7 @@ private:
MachineBasicBlock::iterator MI);
void spillAroundUses(unsigned Reg);
+ void spillAll();
};
}
@@ -629,10 +630,6 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg,
LiveInterval &NewLI = Edit->createFrom(VirtReg.reg, LIS, VRM);
NewLI.markNotSpillable();
- // Rematting for a copy: Set allocation hint to be the destination register.
- if (MI->isCopy())
- MRI.setRegAllocationHint(NewLI.reg, 0, MI->getOperand(0).getReg());
-
// Finally we can rematerialize OrigMI before MI.
SlotIndex DefIdx = Edit->rematerializeAt(*MI->getParent(), MI, NewLI.reg, RM,
LIS, TII, TRI);
@@ -718,6 +715,11 @@ void InlineSpiller::reMaterializeAll() {
DEBUG(dbgs() << RegsToSpill.size() << " registers to spill after remat.\n");
}
+
+//===----------------------------------------------------------------------===//
+// Spilling
+//===----------------------------------------------------------------------===//
+
/// If MI is a load or store of StackSlot, it can be removed.
bool InlineSpiller::coalesceStackAccess(MachineInstr *MI, unsigned Reg) {
int FI = 0;
@@ -906,31 +908,8 @@ void InlineSpiller::spillAroundUses(unsigned Reg) {
}
}
-void InlineSpiller::spill(LiveRangeEdit &edit) {
- Edit = &edit;
- assert(!TargetRegisterInfo::isStackSlot(edit.getReg())
- && "Trying to spill a stack slot.");
- // Share a stack slot among all descendants of Original.
- Original = VRM.getOriginal(edit.getReg());
- StackSlot = VRM.getStackSlot(Original);
- StackInt = 0;
-
- DEBUG(dbgs() << "Inline spilling "
- << MRI.getRegClass(edit.getReg())->getName()
- << ':' << edit.getParent() << "\nFrom original "
- << LIS.getInterval(Original) << '\n');
- assert(edit.getParent().isSpillable() &&
- "Attempting to spill already spilled value.");
- assert(DeadDefs.empty() && "Previous spill didn't remove dead defs");
-
- collectRegsToSpill();
- analyzeSiblingValues();
- reMaterializeAll();
-
- // Remat may handle everything.
- if (RegsToSpill.empty())
- return;
-
+/// spillAll - Spill all registers remaining after rematerialization.
+void InlineSpiller::spillAll() {
// Update LiveStacks now that we are committed to spilling.
if (StackSlot == VirtRegMap::NO_STACK_SLOT) {
StackSlot = VRM.assignVirt2StackSlot(Original);
@@ -939,8 +918,8 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
} else
StackInt = &LSS.getInterval(StackSlot);
- if (Original != edit.getReg())
- VRM.assignVirt2StackSlot(edit.getReg(), StackSlot);
+ if (Original != Edit->getReg())
+ VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot);
assert(StackInt->getNumValNums() == 1 && "Bad stack interval values");
for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
@@ -959,7 +938,7 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
}
// Finally delete the SnippetCopies.
- for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(edit.getReg());
+ 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.
@@ -968,6 +947,35 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
MI->eraseFromParent();
}
+ // Delete all spilled registers.
for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
- edit.eraseVirtReg(RegsToSpill[i], LIS);
+ Edit->eraseVirtReg(RegsToSpill[i], LIS);
+}
+
+void InlineSpiller::spill(LiveRangeEdit &edit) {
+ Edit = &edit;
+ assert(!TargetRegisterInfo::isStackSlot(edit.getReg())
+ && "Trying to spill a stack slot.");
+ // Share a stack slot among all descendants of Original.
+ Original = VRM.getOriginal(edit.getReg());
+ StackSlot = VRM.getStackSlot(Original);
+ StackInt = 0;
+
+ DEBUG(dbgs() << "Inline spilling "
+ << MRI.getRegClass(edit.getReg())->getName()
+ << ':' << edit.getParent() << "\nFrom original "
+ << LIS.getInterval(Original) << '\n');
+ assert(edit.getParent().isSpillable() &&
+ "Attempting to spill already spilled value.");
+ assert(DeadDefs.empty() && "Previous spill didn't remove dead defs");
+
+ collectRegsToSpill();
+ analyzeSiblingValues();
+ reMaterializeAll();
+
+ // Remat may handle everything.
+ if (!RegsToSpill.empty())
+ spillAll();
+
+ Edit->calculateRegClassAndHint(MF, LIS, Loops);
}
diff --git a/lib/CodeGen/LiveRangeEdit.cpp b/lib/CodeGen/LiveRangeEdit.cpp
index 94a3fc1ed0..6b8a533b66 100644
--- a/lib/CodeGen/LiveRangeEdit.cpp
+++ b/lib/CodeGen/LiveRangeEdit.cpp
@@ -15,6 +15,7 @@
#include "LiveRangeEdit.h"
#include "VirtRegMap.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/CodeGen/CalcSpillWeights.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
@@ -236,3 +237,13 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
}
}
+void LiveRangeEdit::calculateRegClassAndHint(MachineFunction &MF,
+ LiveIntervals &LIS,
+ const MachineLoopInfo &Loops) {
+ VirtRegAuxInfo VRAI(MF, LIS, Loops);
+ for (iterator I = begin(), E = end(); I != E; ++I) {
+ LiveInterval &LI = **I;
+ VRAI.CalculateRegClass(LI.reg);
+ VRAI.CalculateWeightAndHint(LI);
+ }
+}
diff --git a/lib/CodeGen/LiveRangeEdit.h b/lib/CodeGen/LiveRangeEdit.h
index 04eced6d79..e02e0a872d 100644
--- a/lib/CodeGen/LiveRangeEdit.h
+++ b/lib/CodeGen/LiveRangeEdit.h
@@ -25,6 +25,7 @@ namespace llvm {
class AliasAnalysis;
class LiveIntervals;
+class MachineLoopInfo;
class MachineRegisterInfo;
class VirtRegMap;
@@ -179,6 +180,10 @@ public:
LiveIntervals&, VirtRegMap&,
const TargetInstrInfo&);
+ /// calculateRegClassAndHint - Recompute register class and hint for each new
+ /// register.
+ void calculateRegClassAndHint(MachineFunction&, LiveIntervals&,
+ const MachineLoopInfo&);
};
}
diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp
index 77a172870a..098df59beb 100644
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -1164,6 +1164,7 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg,
NamedRegionTimer T("Spiller", TimerGroupName, TimePassesIsEnabled);
LiveRangeEdit LRE(VirtReg, NewVRegs, this);
spiller().spill(LRE);
+ setStage(NewVRegs.begin(), NewVRegs.end(), RS_Spill);
if (VerifyEnabled)
MF->verify(this, "After spilling");
diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp
index b89ff0c4fc..2c8066fb63 100644
--- a/lib/CodeGen/SplitKit.cpp
+++ b/lib/CodeGen/SplitKit.cpp
@@ -17,7 +17,6 @@
#include "LiveRangeEdit.h"
#include "VirtRegMap.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/CalcSpillWeights.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -881,14 +880,7 @@ void SplitEditor::finish() {
}
// Calculate spill weight and allocation hints for new intervals.
- VirtRegAuxInfo vrai(VRM.getMachineFunction(), LIS, SA.Loops);
- for (LiveRangeEdit::iterator I = Edit->begin(), E = Edit->end(); I != E; ++I){
- LiveInterval &li = **I;
- vrai.CalculateRegClass(li.reg);
- vrai.CalculateWeightAndHint(li);
- DEBUG(dbgs() << " new interval " << MRI.getRegClass(li.reg)->getName()
- << ":" << li << '\n');
- }
+ Edit->calculateRegClassAndHint(VRM.getMachineFunction(), LIS, SA.Loops);
}