mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 16:33:28 +00:00
A couple of more places where a register liveness has been extended and its last kill should be updated accordingly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34597 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0badfea274
commit
de4e942faa
@ -254,7 +254,8 @@ class VISIBILITY_HIDDEN AvailableSpills {
|
||||
|
||||
// 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.
|
||||
// but not invalidated yet. It also tracks the instruction that last defined
|
||||
// or used the register.
|
||||
typedef std::pair<unsigned, MachineInstr*> SSInfo;
|
||||
std::map<int, SSInfo> SpillSlotsAvailable;
|
||||
|
||||
@ -286,6 +287,24 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// UpdateLastUses - Update the last use information of all stack slots whose
|
||||
/// values are available in the specific register.
|
||||
void UpdateLastUse(unsigned PhysReg, MachineInstr *Use) {
|
||||
std::multimap<unsigned, int>::iterator I =
|
||||
PhysRegsAvailable.lower_bound(PhysReg);
|
||||
while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
|
||||
int Slot = I->second;
|
||||
I++;
|
||||
|
||||
std::map<int, SSInfo>::iterator II = SpillSlotsAvailable.find(Slot);
|
||||
assert(II != SpillSlotsAvailable.end() && "Slot not available!");
|
||||
unsigned Val = II->second.first;
|
||||
assert((Val >> 1) == PhysReg && "Bidirectional map mismatch!");
|
||||
SpillSlotsAvailable.erase(Slot);
|
||||
SpillSlotsAvailable[Slot] = std::make_pair(Val, Use);
|
||||
}
|
||||
}
|
||||
|
||||
/// addAvailable - Mark that the specified stack slot is available in the
|
||||
/// specified physreg. If CanClobber is true, the physreg can be modified at
|
||||
/// any time without changing the semantics of the program.
|
||||
@ -667,10 +686,12 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
|
||||
MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true);
|
||||
if (MOK) {
|
||||
MOK->unsetIsKill();
|
||||
if (ti == -1)
|
||||
if (ti == -1) {
|
||||
// Unless it's the use of a two-address code, transfer the kill
|
||||
// of the reused register to this use.
|
||||
MI.getOperand(i).setIsKill();
|
||||
Spills.UpdateLastUse(PhysReg, &MI);
|
||||
}
|
||||
}
|
||||
|
||||
// The only technical detail we have is that we don't know that
|
||||
@ -738,6 +759,19 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
|
||||
ReusedOperands.markClobbered(DesignatedReg);
|
||||
MRI->copyRegToReg(MBB, &MI, DesignatedReg, PhysReg, RC);
|
||||
|
||||
// Extend the live range of the MI that last kill the register if
|
||||
// necessary.
|
||||
if (SSMI) {
|
||||
MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true);
|
||||
if (MOK) {
|
||||
MachineInstr *CopyMI = prior(MII);
|
||||
MachineOperand *MOU = CopyMI->findRegisterUseOperand(PhysReg);
|
||||
MOU->setIsKill();
|
||||
MOK->unsetIsKill();
|
||||
Spills.UpdateLastUse(PhysReg, &MI);
|
||||
}
|
||||
}
|
||||
|
||||
// This invalidates DesignatedReg.
|
||||
Spills.ClobberPhysReg(DesignatedReg);
|
||||
|
||||
@ -771,6 +805,10 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
|
||||
// Any stores to this stack slot are not dead anymore.
|
||||
MaybeDeadStores.erase(StackSlot);
|
||||
Spills.addAvailable(StackSlot, &MI, PhysReg);
|
||||
// Assumes this is the last use. IsKill will be unset if reg is reused
|
||||
// unless it's a two-address operand.
|
||||
if (TID->getOperandConstraint(i, TOI::TIED_TO) == -1)
|
||||
MI.getOperand(i).setIsKill();
|
||||
++NumLoads;
|
||||
MI.getOperand(i).setReg(PhysReg);
|
||||
DOUT << '\t' << *prior(MII);
|
||||
@ -802,8 +840,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
|
||||
if (FrameIdx == SS) {
|
||||
// If this spill slot is available, turn it into a copy (or nothing)
|
||||
// instead of leaving it as a load!
|
||||
MachineInstr *Dummy = NULL;
|
||||
if (unsigned InReg = Spills.getSpillSlotPhysReg(SS, Dummy)) {
|
||||
MachineInstr *SSMI = NULL;
|
||||
if (unsigned InReg = Spills.getSpillSlotPhysReg(SS, SSMI)) {
|
||||
DOUT << "Promoted Load To Copy: " << MI;
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
if (DestReg != InReg) {
|
||||
@ -814,7 +852,21 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
|
||||
// virtual or needing to clobber any values if it's physical).
|
||||
NextMII = &MI;
|
||||
--NextMII; // backtrack to the copy.
|
||||
} else
|
||||
DOUT << "Removing now-noop copy: " << MI;
|
||||
|
||||
// Extend the live range of the MI that last kill the register if
|
||||
// the next MI reuse it.
|
||||
MachineOperand *MOK = SSMI->findRegisterUseOperand(InReg, true);
|
||||
if (MOK && NextMII != MBB.end()) {
|
||||
MachineOperand *MOU = NextMII->findRegisterUseOperand(InReg);
|
||||
if (MOU) {
|
||||
MOU->setIsKill();
|
||||
MOK->unsetIsKill();
|
||||
Spills.UpdateLastUse(InReg, &(*NextMII));
|
||||
}
|
||||
}
|
||||
|
||||
VRM.RemoveFromFoldedVirtMap(&MI);
|
||||
MBB.erase(&MI);
|
||||
goto ProcessNextInst;
|
||||
|
Loading…
x
Reference in New Issue
Block a user