mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 16:33:28 +00:00
significantly simplify the VirtRegMap code by pulling the SpillSlotsAvailable
and PhysRegsAvailable maps out into a new AvailableSpills struct. No functionality change. This paves the way for a bugfix, coming up next. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25947 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
244d1dccd1
commit
66cf80f226
@ -231,38 +231,92 @@ namespace {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalSpiller::ClobberPhysRegOnly(unsigned PhysReg,
|
/// AvailableSpills - As the local spiller is scanning and rewriting an MBB from
|
||||||
std::map<int, unsigned> &SpillSlots,
|
/// top down, keep track of which spills slots are available in each register.
|
||||||
std::multimap<unsigned, int> &PhysRegsAvailable) {
|
class AvailableSpills {
|
||||||
std::multimap<unsigned, int>::iterator I = PhysRegsAvailable.lower_bound(PhysReg);
|
const MRegisterInfo *MRI;
|
||||||
|
const TargetInstrInfo *TII;
|
||||||
|
|
||||||
|
// SpillSlotsAvailable - This map keeps track of all of the spilled virtual
|
||||||
|
// register values that are still available, due to being loaded or stored to,
|
||||||
|
// but not invalidated yet.
|
||||||
|
std::map<int, unsigned> SpillSlotsAvailable;
|
||||||
|
|
||||||
|
// PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating
|
||||||
|
// which stack slot values are currently held by a physreg. This is used to
|
||||||
|
// invalidate entries in SpillSlotsAvailable when a physreg is modified.
|
||||||
|
std::multimap<unsigned, int> PhysRegsAvailable;
|
||||||
|
|
||||||
|
void ClobberPhysRegOnly(unsigned PhysReg);
|
||||||
|
public:
|
||||||
|
AvailableSpills(const MRegisterInfo *mri, const TargetInstrInfo *tii)
|
||||||
|
: MRI(mri), TII(tii) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// getSpillSlotPhysReg - If the specified stack slot is available in a
|
||||||
|
/// physical register, return that PhysReg, otherwise return 0.
|
||||||
|
unsigned getSpillSlotPhysReg(int Slot) const {
|
||||||
|
std::map<int, unsigned>::const_iterator I = SpillSlotsAvailable.find(Slot);
|
||||||
|
if (I != SpillSlotsAvailable.end())
|
||||||
|
return I->second;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// addAvailable - Mark that the specified stack slot is available in the
|
||||||
|
/// specified physreg.
|
||||||
|
void addAvailable(int Slot, unsigned Reg) {
|
||||||
|
PhysRegsAvailable.insert(std::make_pair(Reg, Slot));
|
||||||
|
SpillSlotsAvailable[Slot] = Reg;
|
||||||
|
|
||||||
|
DEBUG(std::cerr << "Remembering SS#" << Slot << " in physreg "
|
||||||
|
<< MRI->getName(Reg) << "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// ClobberPhysReg - This is called when the specified physreg changes
|
||||||
|
/// value. We use this to invalidate any info about stuff we thing lives in
|
||||||
|
/// it and any of its aliases.
|
||||||
|
void ClobberPhysReg(unsigned PhysReg);
|
||||||
|
|
||||||
|
/// ModifyStackSlot - This method is called when the value in a stack slot
|
||||||
|
/// changes. This removes information about which register the previous value
|
||||||
|
/// for this slot lives in (as the previous value is dead now).
|
||||||
|
void ModifyStackSlot(int Slot);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// ClobberPhysRegOnly - This is called when the specified physreg changes
|
||||||
|
/// value. We use this to invalidate any info about stuff we thing lives in it.
|
||||||
|
void AvailableSpills::ClobberPhysRegOnly(unsigned PhysReg) {
|
||||||
|
std::multimap<unsigned, int>::iterator I =
|
||||||
|
PhysRegsAvailable.lower_bound(PhysReg);
|
||||||
while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
|
while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
|
||||||
int Slot = I->second;
|
int Slot = I->second;
|
||||||
PhysRegsAvailable.erase(I++);
|
PhysRegsAvailable.erase(I++);
|
||||||
assert(SpillSlots[Slot] == PhysReg && "Bidirectional map mismatch!");
|
assert(SpillSlotsAvailable[Slot] == PhysReg &&
|
||||||
SpillSlots.erase(Slot);
|
"Bidirectional map mismatch!");
|
||||||
|
SpillSlotsAvailable.erase(Slot);
|
||||||
DEBUG(std::cerr << "PhysReg " << MRI->getName(PhysReg)
|
DEBUG(std::cerr << "PhysReg " << MRI->getName(PhysReg)
|
||||||
<< " clobbered, invalidating SS#" << Slot << "\n");
|
<< " clobbered, invalidating SS#" << Slot << "\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalSpiller::ClobberPhysReg(unsigned PhysReg,
|
/// ClobberPhysReg - This is called when the specified physreg changes
|
||||||
std::map<int, unsigned> &SpillSlots,
|
/// value. We use this to invalidate any info about stuff we thing lives in
|
||||||
std::multimap<unsigned, int> &PhysRegsAvailable) {
|
/// it and any of its aliases.
|
||||||
|
void AvailableSpills::ClobberPhysReg(unsigned PhysReg) {
|
||||||
for (const unsigned *AS = MRI->getAliasSet(PhysReg); *AS; ++AS)
|
for (const unsigned *AS = MRI->getAliasSet(PhysReg); *AS; ++AS)
|
||||||
ClobberPhysRegOnly(*AS, SpillSlots, PhysRegsAvailable);
|
ClobberPhysRegOnly(*AS);
|
||||||
ClobberPhysRegOnly(PhysReg, SpillSlots, PhysRegsAvailable);
|
ClobberPhysRegOnly(PhysReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ModifyStackSlot - This method is called when the value in a stack slot
|
/// ModifyStackSlot - This method is called when the value in a stack slot
|
||||||
/// changes. This removes information about which register the previous value
|
/// changes. This removes information about which register the previous value
|
||||||
/// for this slot lives in (as the previous value is dead now).
|
/// for this slot lives in (as the previous value is dead now).
|
||||||
void LocalSpiller::ModifyStackSlot(int Slot, std::map<int,unsigned> &SpillSlots,
|
void AvailableSpills::ModifyStackSlot(int Slot) {
|
||||||
std::multimap<unsigned, int> &PhysRegsAvailable) {
|
std::map<int, unsigned>::iterator It = SpillSlotsAvailable.find(Slot);
|
||||||
std::map<int, unsigned>::iterator It = SpillSlots.find(Slot);
|
if (It == SpillSlotsAvailable.end()) return;
|
||||||
if (It == SpillSlots.end()) return;
|
|
||||||
unsigned Reg = It->second;
|
unsigned Reg = It->second;
|
||||||
SpillSlots.erase(It);
|
SpillSlotsAvailable.erase(It);
|
||||||
|
|
||||||
// This register may hold the value of multiple stack slots, only remove this
|
// This register may hold the value of multiple stack slots, only remove this
|
||||||
// stack slot from the set of values the register contains.
|
// stack slot from the set of values the register contains.
|
||||||
@ -308,18 +362,12 @@ namespace {
|
|||||||
/// register allocator is done with them. If possible, avoid reloading vregs.
|
/// register allocator is done with them. If possible, avoid reloading vregs.
|
||||||
void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
|
void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
|
||||||
|
|
||||||
// SpillSlotsAvailable - This map keeps track of all of the spilled virtual
|
|
||||||
// register values that are still available, due to being loaded or stored to,
|
|
||||||
// but not invalidated yet.
|
|
||||||
std::map<int, unsigned> SpillSlotsAvailable;
|
|
||||||
|
|
||||||
// PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating
|
|
||||||
// which stack slot values are currently held by a physreg. This is used to
|
|
||||||
// invalidate entries in SpillSlotsAvailable when a physreg is modified.
|
|
||||||
std::multimap<unsigned, int> PhysRegsAvailable;
|
|
||||||
|
|
||||||
DEBUG(std::cerr << MBB.getBasicBlock()->getName() << ":\n");
|
DEBUG(std::cerr << MBB.getBasicBlock()->getName() << ":\n");
|
||||||
|
|
||||||
|
// Spills - Keep track of which spilled values are available in physregs so
|
||||||
|
// that we can choose to reuse the physregs instead of emitting reloads.
|
||||||
|
AvailableSpills Spills(MRI, TII);
|
||||||
|
|
||||||
std::vector<ReusedOp> ReusedOperands;
|
std::vector<ReusedOp> ReusedOperands;
|
||||||
|
|
||||||
// DefAndUseVReg - When we see a def&use operand that is spilled, keep track
|
// DefAndUseVReg - When we see a def&use operand that is spilled, keep track
|
||||||
@ -387,15 +435,12 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
|
|||||||
unsigned PhysReg;
|
unsigned PhysReg;
|
||||||
|
|
||||||
// Check to see if this stack slot is available.
|
// Check to see if this stack slot is available.
|
||||||
std::map<int, unsigned>::iterator SSI =
|
if ((PhysReg = Spills.getSpillSlotPhysReg(StackSlot))) {
|
||||||
SpillSlotsAvailable.find(StackSlot);
|
// If this stack slot value is already available, reuse it!
|
||||||
if (SSI != SpillSlotsAvailable.end()) {
|
|
||||||
DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg "
|
DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg "
|
||||||
<< MRI->getName(SSI->second) << " for vreg"
|
<< MRI->getName(PhysReg) << " for vreg"
|
||||||
<< VirtReg <<" instead of reloading into physreg "
|
<< VirtReg <<" instead of reloading into physreg "
|
||||||
<< MRI->getName(VRM.getPhys(VirtReg)) << "\n");
|
<< MRI->getName(VRM.getPhys(VirtReg)) << "\n");
|
||||||
// If this stack slot value is already available, reuse it!
|
|
||||||
PhysReg = SSI->second;
|
|
||||||
MI.SetMachineOperandReg(i, PhysReg);
|
MI.SetMachineOperandReg(i, PhysReg);
|
||||||
|
|
||||||
// The only technical detail we have is that we don't know that
|
// The only technical detail we have is that we don't know that
|
||||||
@ -446,20 +491,15 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
|
|||||||
MBB.getParent()->getSSARegMap()->getRegClass(Op.VirtReg);
|
MBB.getParent()->getSSARegMap()->getRegClass(Op.VirtReg);
|
||||||
MRI->loadRegFromStackSlot(MBB, &MI, Op.AssignedPhysReg,
|
MRI->loadRegFromStackSlot(MBB, &MI, Op.AssignedPhysReg,
|
||||||
Op.StackSlot, AliasRC);
|
Op.StackSlot, AliasRC);
|
||||||
ClobberPhysReg(Op.AssignedPhysReg, SpillSlotsAvailable,
|
Spills.ClobberPhysReg(Op.AssignedPhysReg);
|
||||||
PhysRegsAvailable);
|
Spills.ClobberPhysReg(Op.PhysRegReused);
|
||||||
|
|
||||||
// Any stores to this stack slot are not dead anymore.
|
// Any stores to this stack slot are not dead anymore.
|
||||||
MaybeDeadStores.erase(Op.StackSlot);
|
MaybeDeadStores.erase(Op.StackSlot);
|
||||||
|
|
||||||
MI.SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg);
|
MI.SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg);
|
||||||
PhysRegsAvailable.insert(std::make_pair(Op.AssignedPhysReg,
|
|
||||||
Op.StackSlot));
|
Spills.addAvailable(Op.StackSlot, Op.AssignedPhysReg);
|
||||||
SpillSlotsAvailable[Op.StackSlot] = Op.AssignedPhysReg;
|
|
||||||
PhysRegsAvailable.erase(Op.PhysRegReused);
|
|
||||||
DEBUG(std::cerr << "Remembering SS#" << Op.StackSlot
|
|
||||||
<< " in physreg "
|
|
||||||
<< MRI->getName(Op.AssignedPhysReg) << "\n");
|
|
||||||
++NumLoads;
|
++NumLoads;
|
||||||
DEBUG(std::cerr << '\t' << *prior(MII));
|
DEBUG(std::cerr << '\t' << *prior(MII));
|
||||||
|
|
||||||
@ -473,17 +513,13 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
|
|||||||
PhysRegsUsed[PhysReg] = true;
|
PhysRegsUsed[PhysReg] = true;
|
||||||
MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot, RC);
|
MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot, RC);
|
||||||
// This invalidates PhysReg.
|
// This invalidates PhysReg.
|
||||||
ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable);
|
Spills.ClobberPhysReg(PhysReg);
|
||||||
|
|
||||||
// Any stores to this stack slot are not dead anymore.
|
// Any stores to this stack slot are not dead anymore.
|
||||||
MaybeDeadStores.erase(StackSlot);
|
MaybeDeadStores.erase(StackSlot);
|
||||||
|
Spills.addAvailable(StackSlot, PhysReg);
|
||||||
MI.SetMachineOperandReg(i, PhysReg);
|
|
||||||
PhysRegsAvailable.insert(std::make_pair(PhysReg, StackSlot));
|
|
||||||
SpillSlotsAvailable[StackSlot] = PhysReg;
|
|
||||||
DEBUG(std::cerr << "Remembering SS#" << StackSlot <<" in physreg "
|
|
||||||
<< MRI->getName(PhysReg) << "\n");
|
|
||||||
++NumLoads;
|
++NumLoads;
|
||||||
|
MI.SetMachineOperandReg(i, PhysReg);
|
||||||
DEBUG(std::cerr << '\t' << *prior(MII));
|
DEBUG(std::cerr << '\t' << *prior(MII));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,7 +528,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
|
|||||||
for (const unsigned *ImpDef = TII->getImplicitDefs(MI.getOpcode());
|
for (const unsigned *ImpDef = TII->getImplicitDefs(MI.getOpcode());
|
||||||
*ImpDef; ++ImpDef) {
|
*ImpDef; ++ImpDef) {
|
||||||
PhysRegsUsed[*ImpDef] = true;
|
PhysRegsUsed[*ImpDef] = true;
|
||||||
ClobberPhysReg(*ImpDef, SpillSlotsAvailable, PhysRegsAvailable);
|
Spills.ClobberPhysReg(*ImpDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(std::cerr << '\t' << MI);
|
DEBUG(std::cerr << '\t' << MI);
|
||||||
@ -520,12 +556,12 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
|
|||||||
if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
|
if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
|
||||||
// If this spill slot is available, turn it into a copy (or nothing)
|
// If this spill slot is available, turn it into a copy (or nothing)
|
||||||
// instead of leaving it as a load!
|
// instead of leaving it as a load!
|
||||||
std::map<int, unsigned>::iterator It = SpillSlotsAvailable.find(SS);
|
unsigned InReg;
|
||||||
if (FrameIdx == SS && It != SpillSlotsAvailable.end()) {
|
if (FrameIdx == SS && (InReg = Spills.getSpillSlotPhysReg(SS))) {
|
||||||
DEBUG(std::cerr << "Promoted Load To Copy: " << MI);
|
DEBUG(std::cerr << "Promoted Load To Copy: " << MI);
|
||||||
MachineFunction &MF = *MBB.getParent();
|
MachineFunction &MF = *MBB.getParent();
|
||||||
if (DestReg != It->second) {
|
if (DestReg != InReg) {
|
||||||
MRI->copyRegToReg(MBB, &MI, DestReg, It->second,
|
MRI->copyRegToReg(MBB, &MI, DestReg, InReg,
|
||||||
MF.getSSARegMap()->getRegClass(VirtReg));
|
MF.getSSARegMap()->getRegClass(VirtReg));
|
||||||
// Revisit the copy so we make sure to notice the effects of the
|
// Revisit the copy so we make sure to notice the effects of the
|
||||||
// operation on the destreg (either needing to RA it if it's
|
// operation on the destreg (either needing to RA it if it's
|
||||||
@ -558,7 +594,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
|
|||||||
// the value, the value is not available anymore.
|
// the value, the value is not available anymore.
|
||||||
if (MR & VirtRegMap::isMod) {
|
if (MR & VirtRegMap::isMod) {
|
||||||
// Notice that the value in this stack slot has been modified.
|
// Notice that the value in this stack slot has been modified.
|
||||||
ModifyStackSlot(SS, SpillSlotsAvailable, PhysRegsAvailable);
|
Spills.ModifyStackSlot(SS);
|
||||||
|
|
||||||
// If this is *just* a mod of the value, check to see if this is just a
|
// If this is *just* a mod of the value, check to see if this is just a
|
||||||
// store to the spill slot (i.e. the spill got merged into the copy). If
|
// store to the spill slot (i.e. the spill got merged into the copy). If
|
||||||
@ -577,11 +613,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
|
|||||||
// If the stack slot value was previously available in some other
|
// If the stack slot value was previously available in some other
|
||||||
// register, change it now. Otherwise, make the register available,
|
// register, change it now. Otherwise, make the register available,
|
||||||
// in PhysReg.
|
// in PhysReg.
|
||||||
SpillSlotsAvailable[StackSlot] = SrcReg;
|
Spills.addAvailable(StackSlot, SrcReg);
|
||||||
PhysRegsAvailable.insert(std::make_pair(SrcReg, StackSlot));
|
|
||||||
DEBUG(std::cerr << "Updating SS#" << StackSlot << " in physreg "
|
|
||||||
<< MRI->getName(SrcReg) << " for virtreg #"
|
|
||||||
<< VirtReg << "\n" << MI);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -616,7 +648,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
|
|||||||
MBB.erase(&MI);
|
MBB.erase(&MI);
|
||||||
goto ProcessNextInst;
|
goto ProcessNextInst;
|
||||||
}
|
}
|
||||||
ClobberPhysReg(VirtReg, SpillSlotsAvailable, PhysRegsAvailable);
|
Spills.ClobberPhysReg(VirtReg);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -664,14 +696,10 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
|
|||||||
// If the stack slot value was previously available in some other
|
// If the stack slot value was previously available in some other
|
||||||
// register, change it now. Otherwise, make the register available,
|
// register, change it now. Otherwise, make the register available,
|
||||||
// in PhysReg.
|
// in PhysReg.
|
||||||
ModifyStackSlot(StackSlot, SpillSlotsAvailable, PhysRegsAvailable);
|
Spills.ModifyStackSlot(StackSlot);
|
||||||
ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable);
|
Spills.ClobberPhysReg(PhysReg);
|
||||||
|
|
||||||
PhysRegsAvailable.insert(std::make_pair(PhysReg, StackSlot));
|
Spills.addAvailable(StackSlot, PhysReg);
|
||||||
SpillSlotsAvailable[StackSlot] = PhysReg;
|
|
||||||
DEBUG(std::cerr << "Updating SS#" << StackSlot <<" in physreg "
|
|
||||||
<< MRI->getName(PhysReg) << " for virtreg #"
|
|
||||||
<< VirtReg << "\n");
|
|
||||||
++NumStores;
|
++NumStores;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user