mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-05 13:26:55 +00:00
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
This commit is contained in:
@@ -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();
|
||||
|
@@ -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,6 +908,50 @@ void InlineSpiller::spillAroundUses(unsigned Reg) {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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);
|
||||
StackInt = &LSS.getOrCreateInterval(StackSlot, MRI.getRegClass(Original));
|
||||
StackInt->getNextValue(SlotIndex(), 0, LSS.getVNInfoAllocator());
|
||||
} else
|
||||
StackInt = &LSS.getInterval(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)
|
||||
StackInt->MergeRangesInAsValue(LIS.getInterval(RegsToSpill[i]),
|
||||
StackInt->getValNumInfo(0));
|
||||
DEBUG(dbgs() << "Merged spilled regs: " << *StackInt << '\n');
|
||||
|
||||
// Spill around uses of all RegsToSpill.
|
||||
for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
|
||||
spillAroundUses(RegsToSpill[i]);
|
||||
|
||||
// Hoisted spills may cause dead code.
|
||||
if (!DeadDefs.empty()) {
|
||||
DEBUG(dbgs() << "Eliminating " << DeadDefs.size() << " dead defs\n");
|
||||
Edit->eliminateDeadDefs(DeadDefs, LIS, VRM, TII);
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// Delete all spilled registers.
|
||||
for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
|
||||
Edit->eraseVirtReg(RegsToSpill[i], LIS);
|
||||
}
|
||||
|
||||
void InlineSpiller::spill(LiveRangeEdit &edit) {
|
||||
Edit = &edit;
|
||||
assert(!TargetRegisterInfo::isStackSlot(edit.getReg())
|
||||
@@ -928,46 +974,8 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
|
||||
reMaterializeAll();
|
||||
|
||||
// Remat may handle everything.
|
||||
if (RegsToSpill.empty())
|
||||
return;
|
||||
if (!RegsToSpill.empty())
|
||||
spillAll();
|
||||
|
||||
// Update LiveStacks now that we are committed to spilling.
|
||||
if (StackSlot == VirtRegMap::NO_STACK_SLOT) {
|
||||
StackSlot = VRM.assignVirt2StackSlot(Original);
|
||||
StackInt = &LSS.getOrCreateInterval(StackSlot, MRI.getRegClass(Original));
|
||||
StackInt->getNextValue(SlotIndex(), 0, LSS.getVNInfoAllocator());
|
||||
} else
|
||||
StackInt = &LSS.getInterval(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)
|
||||
StackInt->MergeRangesInAsValue(LIS.getInterval(RegsToSpill[i]),
|
||||
StackInt->getValNumInfo(0));
|
||||
DEBUG(dbgs() << "Merged spilled regs: " << *StackInt << '\n');
|
||||
|
||||
// Spill around uses of all RegsToSpill.
|
||||
for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
|
||||
spillAroundUses(RegsToSpill[i]);
|
||||
|
||||
// Hoisted spills may cause dead code.
|
||||
if (!DeadDefs.empty()) {
|
||||
DEBUG(dbgs() << "Eliminating " << DeadDefs.size() << " dead defs\n");
|
||||
Edit->eliminateDeadDefs(DeadDefs, LIS, VRM, TII);
|
||||
}
|
||||
|
||||
// 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)
|
||||
edit.eraseVirtReg(RegsToSpill[i], LIS);
|
||||
Edit->calculateRegClassAndHint(MF, LIS, Loops);
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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&);
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -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");
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user