[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.107 -> 1.108 --- Log message: Don't add the same MI to register reuse "last def/use" twice if it reads the register more than once. --- Diffs of the changes: (+4 -1) VirtRegMap.cpp |5 - 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.107 llvm/lib/CodeGen/VirtRegMap.cpp:1.108 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.107 Mon Mar 26 19:48:28 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Mar 30 15:21:35 2007 @@ -316,7 +316,9 @@ assert(II != SpillSlotsAvailable.end() && "Slot not available!"); unsigned Val = II->second.first; assert((Val >> 1) == PhysReg && "Bidirectional map mismatch!"); - II->second.second.push_back(Use); + // This can be true if there are multiple uses of the same register. + if (II->second.second.back() != Use) +II->second.second.push_back(Use); } } @@ -1117,6 +1119,7 @@ if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) { ++NumDCE; DOUT << "Removing now-noop copy: " << MI; +Spills.removeLastUse(Src, &MI); MBB.erase(&MI); VRM.RemoveFromFoldedVirtMap(&MI); goto ProcessNextInst; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.106 -> 1.107 --- Log message: Don't call getOperandConstraint() if operand index is greater than TID->numOperands. --- Diffs of the changes: (+2 -1) VirtRegMap.cpp |3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.106 llvm/lib/CodeGen/VirtRegMap.cpp:1.107 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.106 Mon Mar 26 17:40:42 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Mon Mar 26 19:48:28 2007 @@ -965,7 +965,8 @@ if (WasKill) { const TargetInstrDescriptor *NTID = NextMII->getInstrDescriptor(); -if (NTID->getOperandConstraint(UIdx, TOI::TIED_TO) == -1) +if (UIdx >= NTID->numOperands || +NTID->getOperandConstraint(UIdx, TOI::TIED_TO) == -1) MOU.setIsKill(); } Spills.addLastUse(InReg, &(*NextMII)); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp LiveIntervalAnalysis.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.105 -> 1.106 LiveIntervalAnalysis.cpp updated: 1.227 -> 1.228 --- Log message: Fix for PR1266: http://llvm.org/PR1266 . Don't mark a two address operand IsKill. --- Diffs of the changes: (+33 -22) LiveIntervalAnalysis.cpp |6 ++--- VirtRegMap.cpp | 49 --- 2 files changed, 33 insertions(+), 22 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.105 llvm/lib/CodeGen/VirtRegMap.cpp:1.106 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.105 Tue Mar 20 03:13:50 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Mon Mar 26 17:40:42 2007 @@ -754,10 +754,11 @@ // necessary. bool WasKill = false; if (SSMI) { -MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true); -if (MOK) { - WasKill = MOK->isKill(); - MOK->unsetIsKill(); +int UIdx = SSMI->findRegisterUseOperand(PhysReg, true); +if (UIdx != -1) { + MachineOperand &MOK = SSMI->getOperand(UIdx); + WasKill = MOK.isKill(); + MOK.unsetIsKill(); } } if (ti == -1) { @@ -840,17 +841,20 @@ // necessary. bool WasKill = false; if (SSMI) { - MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true); - if (MOK) { -WasKill = MOK->isKill(); -MOK->unsetIsKill(); + int UIdx = SSMI->findRegisterUseOperand(PhysReg, true); + if (UIdx != -1) { +MachineOperand &MOK = SSMI->getOperand(UIdx); +WasKill = MOK.isKill(); +MOK.unsetIsKill(); } } MachineInstr *CopyMI = prior(MII); if (WasKill) { // Transfer kill to the next use. - MachineOperand *MOU = CopyMI->findRegisterUseOperand(PhysReg); - MOU->setIsKill(); + int UIdx = CopyMI->findRegisterUseOperand(PhysReg); + assert(UIdx != -1); + MachineOperand &MOU = CopyMI->getOperand(UIdx); + MOU.setIsKill(); } Spills.addLastUse(PhysReg, CopyMI); @@ -945,18 +949,25 @@ // extended. Remove its kill. bool WasKill = false; if (SSMI) { -MachineOperand *MOK = SSMI->findRegisterUseOperand(InReg, true); -if (MOK) { - WasKill = MOK->isKill(); - MOK->unsetIsKill(); +int UIdx = SSMI->findRegisterUseOperand(InReg, true); +if (UIdx != -1) { + MachineOperand &MOK = SSMI->getOperand(UIdx); + WasKill = MOK.isKill(); + MOK.unsetIsKill(); } } if (NextMII != MBB.end()) { -// If NextMII uses InReg (must be the copy?), mark it killed. -MachineOperand *MOU = NextMII->findRegisterUseOperand(InReg); -if (MOU) { - if (WasKill) -MOU->setIsKill(); +// If NextMII uses InReg and the use is not a two address +// operand, mark it killed. +int UIdx = NextMII->findRegisterUseOperand(InReg); +if (UIdx != -1) { + MachineOperand &MOU = NextMII->getOperand(UIdx); + if (WasKill) { +const TargetInstrDescriptor *NTID = + NextMII->getInstrDescriptor(); +if (NTID->getOperandConstraint(UIdx, TOI::TIED_TO) == -1) + MOU.setIsKill(); + } Spills.addLastUse(InReg, &(*NextMII)); } } Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.227 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.228 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.227 Wed Mar 21 20:26:05 2007 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Mon Mar 26 17:40:42 2007 @@ -854,9 +854,9 @@ // If the source instruction was killing the source register before the // merge, unset the isKill marker given the live range has been extended. - MachineOperand *MOK = ValLREndInst->findRegisterUseOperand(IntB.reg, true); - if (MOK) -MOK->unsetIsKill(); + int UIdx = ValLREndInst->findRegisterUseOperand(IntB.reg, true); + if (UIdx != -1) +ValLREndInst->getOperand(UIdx).unsetIsKill(); // Finally, delete the copy instruction. RemoveMachineInstrFromMaps(CopyMI); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.103 -> 1.104 --- Log message: Only propagate IsKill if the last use is a kill. --- Diffs of the changes: (+22 -8) VirtRegMap.cpp | 30 ++ 1 files changed, 22 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.103 llvm/lib/CodeGen/VirtRegMap.cpp:1.104 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.103 Fri Mar 2 02:52:00 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Sat Mar 3 00:32:37 2007 @@ -703,15 +703,19 @@ // Extend the live range of the MI that last kill the register if // necessary. + bool WasKill = false; if (SSMI) { MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true); -if (MOK) +if (MOK) { + WasKill = MOK->isKill(); MOK->unsetIsKill(); +} } 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(); +if (WasKill) + MI.getOperand(i).setIsKill(); Spills.addLastUse(PhysReg, &MI); } @@ -782,15 +786,21 @@ // Extend the live range of the MI that last kill the register if // necessary. +bool WasKill = false; if (SSMI) { MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true); - if (MOK) + if (MOK) { +WasKill = MOK->isKill(); MOK->unsetIsKill(); + } } MachineInstr *CopyMI = prior(MII); -MachineOperand *MOU = CopyMI->findRegisterUseOperand(PhysReg); -MOU->setIsKill(); -Spills.addLastUse(PhysReg, &MI); +if (WasKill) { + // Transfer kill to the next use. + MachineOperand *MOU = CopyMI->findRegisterUseOperand(PhysReg); + MOU->setIsKill(); +} +Spills.addLastUse(PhysReg, CopyMI); // This invalidates DesignatedReg. Spills.ClobberPhysReg(DesignatedReg); @@ -877,16 +887,20 @@ // Either way, the live range of the last kill of InReg has been // extended. Remove its kill. + bool WasKill = false; if (SSMI) { MachineOperand *MOK = SSMI->findRegisterUseOperand(InReg, true); -if (MOK) +if (MOK) { + WasKill = MOK->isKill(); MOK->unsetIsKill(); +} } if (NextMII != MBB.end()) { // If NextMII uses InReg (must be the copy?), mark it killed. MachineOperand *MOU = NextMII->findRegisterUseOperand(InReg); if (MOU) { - MOU->setIsKill(); + if (WasKill) +MOU->setIsKill(); Spills.addLastUse(InReg, &(*NextMII)); } } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.102 -> 1.103 --- Log message: - Keep track all def and uses of stack slot available in register. - Available value use may be deleted (e.g. noop move). --- Diffs of the changes: (+51 -28) VirtRegMap.cpp | 79 - 1 files changed, 51 insertions(+), 28 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.102 llvm/lib/CodeGen/VirtRegMap.cpp:1.103 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.102 Thu Mar 1 23:41:42 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Mar 2 02:52:00 2007 @@ -254,9 +254,9 @@ // 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. It also tracks the instruction that last defined + // but not invalidated yet. It also tracks the instructions that defined // or used the register. - typedef std::pair SSInfo; + typedef std::pair > SSInfo; std::map SpillSlotsAvailable; // PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating @@ -281,15 +281,16 @@ unsigned getSpillSlotPhysReg(int Slot, MachineInstr *&SSMI) const { std::map::const_iterator I = SpillSlotsAvailable.find(Slot); if (I != SpillSlotsAvailable.end()) { - SSMI = I->second.second; + if (!I->second.second.empty()) +SSMI = I->second.second.back(); return I->second.first >> 1; // Remove the CanClobber bit. } return 0; } - /// UpdateLastUses - Update the last use information of all stack slots whose + /// addLastUse - Add the last use information of all stack slots whose /// values are available in the specific register. - void UpdateLastUse(unsigned PhysReg, MachineInstr *Use) { + void addLastUse(unsigned PhysReg, MachineInstr *Use) { std::multimap::iterator I = PhysRegsAvailable.lower_bound(PhysReg); while (I != PhysRegsAvailable.end() && I->first == PhysReg) { @@ -300,8 +301,25 @@ 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); + II->second.second.push_back(Use); +} + } + + /// removeLastUse - Remove the last use information of all stack slots whose + /// values are available in the specific register. + void removeLastUse(unsigned PhysReg, MachineInstr *Use) { +std::multimap::iterator I = + PhysRegsAvailable.lower_bound(PhysReg); +while (I != PhysRegsAvailable.end() && I->first == PhysReg) { + int Slot = I->second; + I++; + + std::map::iterator II = SpillSlotsAvailable.find(Slot); + assert(II != SpillSlotsAvailable.end() && "Slot not available!"); + unsigned Val = II->second.first; + assert((Val >> 1) == PhysReg && "Bidirectional map mismatch!"); + if (II->second.second.back() == Use) +II->second.second.pop_back(); } } @@ -315,8 +333,10 @@ ModifyStackSlot(Slot); PhysRegsAvailable.insert(std::make_pair(Reg, Slot)); +std::vector DefUses; +DefUses.push_back(MI); SpillSlotsAvailable[Slot] = - std::make_pair((Reg << 1) | (unsigned)CanClobber, MI); + std::make_pair((Reg << 1) | (unsigned)CanClobber, DefUses); DOUT << "Remembering SS#" << Slot << " in physreg " << MRI->getName(Reg) << "\n"; @@ -683,15 +703,16 @@ // Extend the live range of the MI that last kill the register if // necessary. - MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true); - if (MOK) { -MOK->unsetIsKill(); -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); -} + if (SSMI) { +MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true); +if (MOK) + MOK->unsetIsKill(); + } + 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.addLastUse(PhysReg, &MI); } // The only technical detail we have is that we don't know that @@ -763,14 +784,13 @@ // necessary. if (SSMI) { MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true); - if (MOK) { -MachineInstr *CopyMI = prior(MII); -MachineOperand *MOU = CopyMI->findRegisterUseOperand(PhysReg); -MOU->setIsKill(); + if (MOK)
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.101 -> 1.102 --- Log message: Invalidate last use of a reused register if the use is a deleted noop copy. --- Diffs of the changes: (+1 -0) VirtRegMap.cpp |1 + 1 files changed, 1 insertion(+) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.101 llvm/lib/CodeGen/VirtRegMap.cpp:1.102 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.101 Wed Feb 28 20:27:30 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Mar 1 23:41:42 2007 @@ -937,6 +937,7 @@ DOUT << "Removing now-noop copy: " << MI; MBB.erase(&MI); VRM.RemoveFromFoldedVirtMap(&MI); +Spills.UpdateLastUse(Src, NULL); Spills.disallowClobberPhysReg(VirtReg); goto ProcessNextInst; } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.100 -> 1.101 --- Log message: A restore is promoted to copy (or deleted entirely), remove the kill from the last use of the targetted register. --- Diffs of the changes: (+4 -3) VirtRegMap.cpp |7 --- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.100 llvm/lib/CodeGen/VirtRegMap.cpp:1.101 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.100 Sun Feb 25 03:51:27 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Wed Feb 28 20:27:30 2007 @@ -855,14 +855,15 @@ } 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. + // Either way, the live range of the last kill of InReg has been + // extended. Remove its kill. MachineOperand *MOK = SSMI->findRegisterUseOperand(InReg, true); if (MOK && NextMII != MBB.end()) { +MOK->unsetIsKill(); +// If NextMII uses InReg (must be the copy?), mark it killed. MachineOperand *MOU = NextMII->findRegisterUseOperand(InReg); if (MOU) { MOU->setIsKill(); - MOK->unsetIsKill(); Spills.UpdateLastUse(InReg, &(*NextMII)); } } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.99 -> 1.100 --- Log message: A couple of more places where a register liveness has been extended and its last kill should be updated accordingly. --- Diffs of the changes: (+57 -5) VirtRegMap.cpp | 62 - 1 files changed, 57 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.99 llvm/lib/CodeGen/VirtRegMap.cpp:1.100 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.99Fri Feb 23 15:47:50 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Sun Feb 25 03:51:27 2007 @@ -254,7 +254,8 @@ // 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 SSInfo; std::map SpillSlotsAvailable; @@ -285,6 +286,24 @@ } 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::iterator I = + PhysRegsAvailable.lower_bound(PhysReg); +while (I != PhysRegsAvailable.end() && I->first == PhysReg) { + int Slot = I->second; + I++; + + std::map::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 @@ -667,10 +686,12 @@ 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 @@ -737,7 +758,20 @@ PhysRegsUsed[DesignatedReg] = true; 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 @@ // 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 @@ 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 @@ // 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); +
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.98 -> 1.99 --- Log message: Reuse extends the liveness of a register. Transfer the kill to the operand that reuse it. --- Diffs of the changes: (+6 -1) VirtRegMap.cpp |7 ++- 1 files changed, 6 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.98 llvm/lib/CodeGen/VirtRegMap.cpp:1.99 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.98Thu Feb 22 19:13:26 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 23 15:47:50 2007 @@ -665,8 +665,13 @@ // Extend the live range of the MI that last kill the register if // necessary. MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true); - if (MOK) + if (MOK) { MOK->unsetIsKill(); +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(); + } // The only technical detail we have is that we don't know that // PhysReg won't be clobbered by a reloaded stack slot that occurs ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.97 -> 1.98 --- Log message: A spill kills the register being stored. But it is later being reused by spiller, its live range has to be extended. --- Diffs of the changes: (+39 -25) VirtRegMap.cpp | 64 ++--- 1 files changed, 39 insertions(+), 25 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.97 llvm/lib/CodeGen/VirtRegMap.cpp:1.98 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.97Tue Feb 20 20:22:03 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 22 19:13:26 2007 @@ -255,7 +255,8 @@ // 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 SpillSlotsAvailable; + typedef std::pair SSInfo; + std::map SpillSlotsAvailable; // PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating // which stack slot values are currently held by a physreg. This is used to @@ -270,27 +271,33 @@ : MRI(mri), TII(tii) { } + const MRegisterInfo *getRegInfo() const { return MRI; } + /// 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::const_iterator I = SpillSlotsAvailable.find(Slot); -if (I != SpillSlotsAvailable.end()) - return I->second >> 1; // Remove the CanClobber bit. + /// physical register, return that PhysReg, otherwise return 0. It also + /// returns by reference the instruction that either defines or last uses + /// the register. + unsigned getSpillSlotPhysReg(int Slot, MachineInstr *&SSMI) const { +std::map::const_iterator I = SpillSlotsAvailable.find(Slot); +if (I != SpillSlotsAvailable.end()) { + SSMI = I->second.second; + return I->second.first >> 1; // Remove the CanClobber bit. +} return 0; } - const MRegisterInfo *getRegInfo() const { return MRI; } - /// 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. - void addAvailable(int Slot, unsigned Reg, bool CanClobber = true) { + void addAvailable(int Slot, MachineInstr *MI, unsigned Reg, +bool CanClobber = true) { // If this stack slot is thought to be available in some other physreg, // remove its record. ModifyStackSlot(Slot); PhysRegsAvailable.insert(std::make_pair(Reg, Slot)); -SpillSlotsAvailable[Slot] = (Reg << 1) | (unsigned)CanClobber; +SpillSlotsAvailable[Slot] = + std::make_pair((Reg << 1) | (unsigned)CanClobber, MI); DOUT << "Remembering SS#" << Slot << " in physreg " << MRI->getName(Reg) << "\n"; @@ -301,7 +308,7 @@ /// stack slot must be available in a physreg for this query to make sense. bool canClobberPhysReg(int Slot) const { assert(SpillSlotsAvailable.count(Slot) && "Slot not available!"); -return SpillSlotsAvailable.find(Slot)->second & 1; +return SpillSlotsAvailable.find(Slot)->second.first & 1; } /// disallowClobberPhysReg - Unset the CanClobber bit of the specified @@ -330,9 +337,9 @@ while (I != PhysRegsAvailable.end() && I->first == PhysReg) { int Slot = I->second; I++; -assert((SpillSlotsAvailable[Slot] >> 1) == PhysReg && +assert((SpillSlotsAvailable[Slot].first >> 1) == PhysReg && "Bidirectional map mismatch!"); -SpillSlotsAvailable[Slot] &= ~1; +SpillSlotsAvailable[Slot].first &= ~1; DOUT << "PhysReg " << MRI->getName(PhysReg) << " copied, it is available for use but can no longer be modified\n"; } @@ -355,7 +362,7 @@ while (I != PhysRegsAvailable.end() && I->first == PhysReg) { int Slot = I->second; PhysRegsAvailable.erase(I++); -assert((SpillSlotsAvailable[Slot] >> 1) == PhysReg && +assert((SpillSlotsAvailable[Slot].first >> 1) == PhysReg && "Bidirectional map mismatch!"); SpillSlotsAvailable.erase(Slot); DOUT << "PhysReg " << MRI->getName(PhysReg) @@ -376,9 +383,9 @@ /// changes. This removes information about which register the previous value /// for this slot lives in (as the previous value is dead now). void AvailableSpills::ModifyStackSlot(int Slot) { - std::map::iterator It = SpillSlotsAvailable.find(Slot); + std::map::iterator It = SpillSlotsAvailable.find(Slot); if (It == SpillSlotsAvailable.end()) return; - unsigned Reg = It->second >> 1; + unsigned Reg = It->second.first >> 1; SpillSlotsAvailable.erase(It); // This register may hold the value of multiple stack slots, only remove this @@ -514,7 +521,7 @@ MI->getOperand(NewOp.Operand).setReg(Ne
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.96 -> 1.97 --- Log message: Use BitVector instead. No functionality change. --- Diffs of the changes: (+5 -8) VirtRegMap.cpp | 13 + 1 files changed, 5 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.96 llvm/lib/CodeGen/VirtRegMap.cpp:1.97 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.96Mon Feb 19 19:29:10 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Tue Feb 20 20:22:03 2007 @@ -27,6 +27,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Compiler.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallSet.h" @@ -423,14 +424,10 @@ class VISIBILITY_HIDDEN ReuseInfo { MachineInstr &MI; std::vector Reuses; -bool *PhysRegsClobbered; +BitVector PhysRegsClobbered; public: ReuseInfo(MachineInstr &mi, const MRegisterInfo *mri) : MI(mi) { - PhysRegsClobbered = new bool[mri->getNumRegs()]; - std::fill(PhysRegsClobbered, PhysRegsClobbered+mri->getNumRegs(), false); -} -~ReuseInfo() { - delete[] PhysRegsClobbered; + PhysRegsClobbered.resize(mri->getNumRegs()); } bool hasReuses() const { @@ -452,11 +449,11 @@ } void markClobbered(unsigned PhysReg) { - PhysRegsClobbered[PhysReg] = true; + PhysRegsClobbered.set(PhysReg); } bool isClobbered(unsigned PhysReg) const { - return PhysRegsClobbered[PhysReg]; + return PhysRegsClobbered.test(PhysReg); } /// GetRegForReload - We are about to emit a reload into PhysReg. If there ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.95 -> 1.96 --- Log message: Dead code. --- Diffs of the changes: (+0 -6) VirtRegMap.cpp |6 -- 1 files changed, 6 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.95 llvm/lib/CodeGen/VirtRegMap.cpp:1.96 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.95Thu Feb 8 00:04:54 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Mon Feb 19 19:29:10 2007 @@ -233,12 +233,6 @@ } private: void RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM); -void ClobberPhysReg(unsigned PR, std::map &SpillSlots, -std::multimap &PhysRegs); -void ClobberPhysRegOnly(unsigned PR, std::map &SpillSlots, -std::multimap &PhysRegs); -void ModifyStackSlot(int Slot, std::map &SpillSlots, - std::multimap &PhysRegs); }; } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.94 -> 1.95 --- Log message: Fixed a long standing spiller bug that's exposed by Thumb: The code sequence before the spiller is something like: = tMOVrr %reg1117 = tMOVrr %reg1078 = tLSLri %reg1117, 2 The it starts spilling: %r0 = tRestore , 0 %r1 = tRestore , 0 %r1 = tMOVrr %r1 tSpill %r1, , 0 %reg1078 = tLSLri %reg1117, 2 It restores the value while processing the first tMOVrr. At this point, the spiller remembers fi#5 is available in %r0. Next it processes the second move. It restores the source before the move and spills the result afterwards. The move becomes a noop and is deleted. However, a spill has been inserted and that should invalidate reuse of %r0 for fi#5 and add reuse of %r1 for fi#5. Therefore, %reg1117 (which is also assigned fi#5) should get %r1, not %r0. --- Diffs of the changes: (+13 -13) VirtRegMap.cpp | 26 +- 1 files changed, 13 insertions(+), 13 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.94 llvm/lib/CodeGen/VirtRegMap.cpp:1.95 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.94Mon Jan 22 18:59:48 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 8 00:04:54 2007 @@ -923,19 +923,6 @@ DOUT << "Store:\t" << *next(MII); MI.getOperand(i).setReg(PhysReg); -// Check to see if this is a noop copy. If so, eliminate the -// instruction before considering the dest reg to be changed. -{ - unsigned Src, Dst; - if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) { -++NumDCE; -DOUT << "Removing now-noop copy: " << MI; -MBB.erase(&MI); -VRM.RemoveFromFoldedVirtMap(&MI); -goto ProcessNextInst; - } -} - // If there is a dead store to this stack slot, nuke it now. MachineInstr *&LastStore = MaybeDeadStores[StackSlot]; if (LastStore) { @@ -953,6 +940,19 @@ Spills.ClobberPhysReg(PhysReg); Spills.addAvailable(StackSlot, PhysReg); ++NumStores; + +// Check to see if this is a noop copy. If so, eliminate the +// instruction before considering the dest reg to be changed. +{ + unsigned Src, Dst; + if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) { +++NumDCE; +DOUT << "Removing now-noop copy: " << MI; +MBB.erase(&MI); +VRM.RemoveFromFoldedVirtMap(&MI); +goto ProcessNextInst; + } +} } } ProcessNextInst: ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.93 -> 1.94 --- Log message: Switch this to use SmallSet to avoid mallocs in the common case. --- Diffs of the changes: (+3 -3) VirtRegMap.cpp |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.93 llvm/lib/CodeGen/VirtRegMap.cpp:1.94 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.93Fri Jan 19 16:40:14 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Mon Jan 22 18:59:48 2007 @@ -29,8 +29,8 @@ #include "llvm/Support/Compiler.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallSet.h" #include -#include using namespace llvm; STATISTIC(NumSpills, "Number of register spills"); @@ -471,7 +471,7 @@ unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI, AvailableSpills &Spills, std::map &MaybeDeadStores, - std::set &Rejected) { + SmallSet &Rejected) { if (Reuses.empty()) return PhysReg; // This is most often empty. for (unsigned ro = 0, e = Reuses.size(); ro != e; ++ro) { @@ -553,7 +553,7 @@ unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI, AvailableSpills &Spills, std::map &MaybeDeadStores) { - std::set Rejected; + SmallSet Rejected; return GetRegForReload(PhysReg, MI, Spills, MaybeDeadStores, Rejected); } }; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.92 -> 1.93 --- Log message: GetRegForReload() now keeps track which registers have been considered and rejected during its quest to find a suitable reload register. This avoids an infinite loop in case like this: t1 := op t2, t3 t2 <- assigned r0 for use by the reload but ended up reuse r1 t3 <- assigned r1 for use by the reload but ended up reuse r0 t1 <- desires r1 sees r1 is taken by t2, tries t2's reload register r0 sees r0 is taken by t3, tries t3's reload register r1 sees r1 is taken by t2, tries t2's reload register r0 ... --- Diffs of the changes: (+32 -8) VirtRegMap.cpp | 40 1 files changed, 32 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.92 llvm/lib/CodeGen/VirtRegMap.cpp:1.93 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.92Tue Dec 19 16:41:21 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Jan 19 16:40:14 2007 @@ -30,6 +30,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" #include +#include using namespace llvm; STATISTIC(NumSpills, "Number of register spills"); @@ -469,18 +470,23 @@ /// a new register to use, or evict the previous reload and use this reg. unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI, AvailableSpills &Spills, - std::map &MaybeDeadStores) { + std::map &MaybeDeadStores, + std::set &Rejected) { if (Reuses.empty()) return PhysReg; // This is most often empty. for (unsigned ro = 0, e = Reuses.size(); ro != e; ++ro) { ReusedOp &Op = Reuses[ro]; // If we find some other reuse that was supposed to use this register // exactly for its reload, we can change this reload to use ITS reload -// register. -if (Op.PhysRegReused == PhysReg) { +// register. That is, unless its reload register has already been +// considered and subsequently rejected because it has also been reused +// by another operand. +if (Op.PhysRegReused == PhysReg && +Rejected.count(Op.AssignedPhysReg) == 0) { // Yup, use the reload register that we didn't use before. - unsigned NewReg = Op.AssignedPhysReg; - return GetRegForReload(NewReg, MI, Spills, MaybeDeadStores); + unsigned NewReg = Op.AssignedPhysReg; + Rejected.insert(PhysReg); + return GetRegForReload(NewReg, MI, Spills, MaybeDeadStores, Rejected); } else { // Otherwise, we might also have a problem if a previously reused // value aliases the new register. If so, codegen the previous reload @@ -505,7 +511,7 @@ // register could hold a reuse. Check to see if it conflicts or // would prefer us to use a different register. unsigned NewPhysReg = GetRegForReload(NewOp.AssignedPhysReg, - MI, Spills, MaybeDeadStores); + MI, Spills, MaybeDeadStores, Rejected); MRI->loadRegFromStackSlot(*MBB, MI, NewPhysReg, NewOp.StackSlot, AliasRC); @@ -532,6 +538,24 @@ } return PhysReg; } + +/// GetRegForReload - Helper for the above GetRegForReload(). Add a +/// 'Rejected' set to remember which registers have been considered and +/// rejected for the reload. This avoids infinite looping in case like +/// this: +/// t1 := op t2, t3 +/// t2 <- assigned r0 for use by the reload but ended up reuse r1 +/// t3 <- assigned r1 for use by the reload but ended up reuse r0 +/// t1 <- desires r1 +/// sees r1 is taken by t2, tries t2's reload register r0 +/// sees r0 is taken by t3, tries t3's reload register r1 +/// sees r1 is taken by t2, tries t2's reload register r0 ... +unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI, +
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.89 -> 1.90 --- Log message: Minor clean up. --- Diffs of the changes: (+3 -2) VirtRegMap.cpp |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.89 llvm/lib/CodeGen/VirtRegMap.cpp:1.90 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.89Thu Dec 14 01:54:05 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Dec 15 00:41:01 2006 @@ -573,7 +573,8 @@ // Loop over all of the implicit defs, clearing them from our available // sets. -const unsigned *ImpDef = TII->getImplicitDefs(MI.getOpcode()); +const TargetInstrDescriptor *TID = MI.getInstrDescriptor(); +const unsigned *ImpDef = TID->ImplicitDefs; if (ImpDef) { for ( ; *ImpDef; ++ImpDef) { PhysRegsUsed[*ImpDef] = true; @@ -626,7 +627,7 @@ // aren't allowed to modify the reused register. If none of these cases // apply, reuse it. bool CanReuse = true; -int ti = MI.getInstrDescriptor()->getOperandConstraint(i, TOI::TIED_TO); +int ti = TID->getOperandConstraint(i, TOI::TIED_TO); if (ti != -1 && MI.getOperand(ti).isReg() && MI.getOperand(ti).getReg() == VirtReg) { ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.88 -> 1.89 --- Log message: Fix a long-standing spiller bug: If a spillslot value is available in a register, and there is a noop copy that targets that register, the spiller correctly decide not to invalidate the spillslot register. However, even though the noop copy does not clobbers the value. It does start a new intersecting live range. That means the spillslot register is available for use but should not be reused for a two-address instruction modref operand which would clobber the new live range. When we remove the noop copy, update the available information by clearing the canClobber bit. --- Diffs of the changes: (+35 -1) VirtRegMap.cpp | 36 +++- 1 files changed, 35 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.88 llvm/lib/CodeGen/VirtRegMap.cpp:1.89 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.88Fri Dec 8 12:45:48 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Dec 14 01:54:05 2006 @@ -272,6 +272,8 @@ // invalidate entries in SpillSlotsAvailable when a physreg is modified. std::multimap PhysRegsAvailable; + void disallowClobberPhysRegOnly(unsigned PhysReg); + void ClobberPhysRegOnly(unsigned PhysReg); public: AvailableSpills(const MRegisterInfo *mri, const TargetInstrInfo *tii) @@ -303,7 +305,7 @@ DOUT << "Remembering SS#" << Slot << " in physreg " << MRI->getName(Reg) << "\n"; } - + /// canClobberPhysReg - Return true if the spiller is allowed to change the /// value of the specified stackslot register if it desires. The specified /// stack slot must be available in a physreg for this query to make sense. @@ -312,6 +314,11 @@ return SpillSlotsAvailable.find(Slot)->second & 1; } + /// disallowClobberPhysReg - Unset the CanClobber bit of the specified + /// stackslot register. The register is still available but is no longer + /// allowed to be modifed. + void disallowClobberPhysReg(unsigned PhysReg); + /// 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. @@ -324,6 +331,32 @@ }; } +/// disallowClobberPhysRegOnly - Unset the CanClobber bit of the specified +/// stackslot register. The register is still available but is no longer +/// allowed to be modifed. +void AvailableSpills::disallowClobberPhysRegOnly(unsigned PhysReg) { + std::multimap::iterator I = +PhysRegsAvailable.lower_bound(PhysReg); + while (I != PhysRegsAvailable.end() && I->first == PhysReg) { +int Slot = I->second; +I++; +assert((SpillSlotsAvailable[Slot] >> 1) == PhysReg && + "Bidirectional map mismatch!"); +SpillSlotsAvailable[Slot] &= ~1; +DOUT << "PhysReg " << MRI->getName(PhysReg) + << " copied, it is available for use but can no longer be modified\n"; + } +} + +/// disallowClobberPhysReg - Unset the CanClobber bit of the specified +/// stackslot register and its aliases. The register and its aliases may +/// still available but is no longer allowed to be modifed. +void AvailableSpills::disallowClobberPhysReg(unsigned PhysReg) { + for (const unsigned *AS = MRI->getAliasSet(PhysReg); *AS; ++AS) +disallowClobberPhysRegOnly(*AS); + disallowClobberPhysRegOnly(PhysReg); +} + /// 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) { @@ -822,6 +855,7 @@ DOUT << "Removing now-noop copy: " << MI; MBB.erase(&MI); VRM.RemoveFromFoldedVirtMap(&MI); +Spills.disallowClobberPhysReg(VirtReg); goto ProcessNextInst; } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.86 -> 1.87 --- Log message: Proper fix for PR1037: http://llvm.org/PR1037 : to determine is a VR is a modref, check 1) whether it is tied to another oeprand, 2) whether is is being tied to by another operand. So the destination operand of a two-address MI can be correctly identified. --- Diffs of the changes: (+4 -2) VirtRegMap.cpp |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.86 llvm/lib/CodeGen/VirtRegMap.cpp:1.87 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.86Thu Dec 7 10:21:19 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Dec 8 02:02:34 2006 @@ -97,7 +97,9 @@ } ModRef MRInfo; - if (TII.getOperandConstraint(OldMI->getOpcode(), OpNo, TOI::TIED_TO)) { + const TargetInstrDescriptor *TID = OldMI->getInstrDescriptor(); + if (TID->getOperandConstraint(OpNo, TOI::TIED_TO) != -1 || + TII.findTiedToSrcOperand(TID, OpNo) != -1) { // Folded a two-address operand. MRInfo = isModRef; } else if (OldMI->getOperand(OpNo).isDef()) { @@ -849,7 +851,7 @@ // If this def is part of a two-address operand, make sure to execute // the store from the correct physical register. unsigned PhysReg; -int TiedOp = TII->findTiedToSrcOperand(MI.getOpcode(), i); +int TiedOp = TII->findTiedToSrcOperand(MI.getInstrDescriptor(), i); if (TiedOp != -1) PhysReg = MI.getOperand(TiedOp).getReg(); else { ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.85 -> 1.86 --- Log message: Revision 1.83 causes PR1037: http://llvm.org/PR1037 . Reverted. --- Diffs of the changes: (+1 -2) VirtRegMap.cpp |3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.85 llvm/lib/CodeGen/VirtRegMap.cpp:1.86 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.85Wed Dec 6 19:30:31 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Dec 7 10:21:19 2006 @@ -97,8 +97,7 @@ } ModRef MRInfo; - if (OldMI->getInstrDescriptor()-> - getOperandConstraint(OpNo, TOI::TIED_TO) != -1) { + if (TII.getOperandConstraint(OldMI->getOpcode(), OpNo, TOI::TIED_TO)) { // Folded a two-address operand. MRInfo = isModRef; } else if (OldMI->getOperand(OpNo).isDef()) { ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.82 -> 1.83 --- Log message: getOperandConstraint returns -1 if the operand does have the specific constraint. This bug was causing excessive spills. --- Diffs of the changes: (+1 -1) VirtRegMap.cpp |2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.82 llvm/lib/CodeGen/VirtRegMap.cpp:1.83 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.82Wed Dec 6 11:46:31 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Wed Dec 6 18:46:04 2006 @@ -97,7 +97,7 @@ } ModRef MRInfo; - if (TII.getOperandConstraint(OldMI->getOpcode(), OpNo, TOI::TIED_TO)) { + if (TII.getOperandConstraint(OldMI->getOpcode(), OpNo, TOI::TIED_TO) != -1) { // Folded a two-address operand. MRInfo = isModRef; } else if (OldMI->getOperand(OpNo).isDef()) { ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.78 -> 1.79 --- Log message: Fixed some spiller bugs exposed by the recent two-address code changes. Now there may be other def(s) apart from the use&def two-address operand. We need to check if the register reuse for a use&def operand may conflicts with another def. Provide a mean to recover from the conflict if it is detected when the defs are processed later. --- Diffs of the changes: (+53 -21) VirtRegMap.cpp | 74 - 1 files changed, 53 insertions(+), 21 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.78 llvm/lib/CodeGen/VirtRegMap.cpp:1.79 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.78Wed Nov 1 17:18:32 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Nov 3 18:21:55 2006 @@ -394,8 +394,15 @@ class VISIBILITY_HIDDEN ReuseInfo { MachineInstr &MI; std::vector Reuses; +bool *PhysRegsClobbered; public: -ReuseInfo(MachineInstr &mi) : MI(mi) {} +ReuseInfo(MachineInstr &mi, const MRegisterInfo *mri) : MI(mi) { + PhysRegsClobbered = new bool[mri->getNumRegs()]; + std::fill(PhysRegsClobbered, PhysRegsClobbered+mri->getNumRegs(), false); +} +~ReuseInfo() { + delete[] PhysRegsClobbered; +} bool hasReuses() const { return !Reuses.empty(); @@ -414,6 +421,14 @@ Reuses.push_back(ReusedOp(OpNo, StackSlot, PhysRegReused, AssignedPhysReg, VirtReg)); } + +void markClobbered(unsigned PhysReg) { + PhysRegsClobbered[PhysReg] = true; +} + +bool isClobbered(unsigned PhysReg) const { + return PhysRegsClobbered[PhysReg]; +} /// GetRegForReload - We are about to emit a reload into PhysReg. If there /// is some other operand that is using the specified register, either pick @@ -430,11 +445,7 @@ // register. if (Op.PhysRegReused == PhysReg) { // Yup, use the reload register that we didn't use before. - unsigned NewReg = Op.AssignedPhysReg; - - // Remove the record for the previous reuse. We know it can never be - // invalidated now. - Reuses.erase(Reuses.begin()+ro); + unsigned NewReg = Op.AssignedPhysReg; return GetRegForReload(NewReg, MI, Spills, MaybeDeadStores); } else { // Otherwise, we might also have a problem if a previously reused @@ -518,8 +529,19 @@ /// ReusedOperands - Keep track of operand reuse in case we need to undo /// reuse. -ReuseInfo ReusedOperands(MI); - +ReuseInfo ReusedOperands(MI, MRI); + +// Loop over all of the implicit defs, clearing them from our available +// sets. +const unsigned *ImpDef = TII->getImplicitDefs(MI.getOpcode()); +if (ImpDef) { + for ( ; *ImpDef; ++ImpDef) { +PhysRegsUsed[*ImpDef] = true; +ReusedOperands.markClobbered(*ImpDef); +Spills.ClobberPhysReg(*ImpDef); + } +} + // Process all of the spilled uses and all non spilled reg references. for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { MachineOperand &MO = MI.getOperand(i); @@ -530,6 +552,7 @@ // Ignore physregs for spilling, but remember that it is used by this // function. PhysRegsUsed[MO.getReg()] = true; +ReusedOperands.markClobbered(MO.getReg()); continue; } @@ -541,6 +564,8 @@ // This virtual register was assigned a physreg! unsigned Phys = VRM.getPhys(VirtReg); PhysRegsUsed[Phys] = true; +if (MO.isDef()) + ReusedOperands.markClobbered(Phys); MI.getOperand(i).setReg(Phys); continue; } @@ -567,8 +592,10 @@ MI.getOperand(ti).isReg() && MI.getOperand(ti).getReg() == VirtReg) { // Okay, we have a two address operand. We can reuse this physreg as - // long as we are allowed to clobber the value. - CanReuse = Spills.canClobberPhysReg(StackSlot); + // long as we are allowed to clobber the value and there is an earlier + // def that has already clobbered the physreg. + CanReuse = Spills.canClobberPhysReg(StackSlot) && +!ReusedOperands.isClobbered(PhysReg); } if (CanReuse) { @@ -595,6 +622,9 @@ // we can get at R0 or its alias. ReusedOperands.addReuse(i, StackSlot, PhysReg, VRM.getPhys(VirtReg), VirtReg); + if (ti != -1) +// Only mark it clobbered if this is a use&def operand. +ReusedOperands.markClobbered(PhysReg); ++NumReused; continue; } @@ -629,6 +659,7 @@ << VirtReg << " instead of reloading into same physreg.\n"); MI.getOperand(i).setRe
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.75 -> 1.76 --- Log message: restore my previous patch, now that the X86 backend bug has been fixed: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20061009/038518.html --- Diffs of the changes: (+32 -17) VirtRegMap.cpp | 49 - 1 files changed, 32 insertions(+), 17 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.75 llvm/lib/CodeGen/VirtRegMap.cpp:1.76 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.75Thu Oct 12 03:00:47 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Oct 12 12:45:38 2006 @@ -706,24 +706,25 @@ if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) { int FrameIdx; if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) { - // If this spill slot is available, turn it into a copy (or nothing) - // instead of leaving it as a load! - unsigned InReg; - if (FrameIdx == SS && (InReg = Spills.getSpillSlotPhysReg(SS))) { -DEBUG(std::cerr << "Promoted Load To Copy: " << MI); -MachineFunction &MF = *MBB.getParent(); -if (DestReg != InReg) { - MRI->copyRegToReg(MBB, &MI, DestReg, InReg, -MF.getSSARegMap()->getRegClass(VirtReg)); - // 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 - // virtual or needing to clobber any values if it's physical). - NextMII = &MI; - --NextMII; // backtrack to the copy. + if (FrameIdx == SS) { +// If this spill slot is available, turn it into a copy (or nothing) +// instead of leaving it as a load! +if (unsigned InReg = Spills.getSpillSlotPhysReg(SS)) { + DEBUG(std::cerr << "Promoted Load To Copy: " << MI); + MachineFunction &MF = *MBB.getParent(); + if (DestReg != InReg) { +MRI->copyRegToReg(MBB, &MI, DestReg, InReg, + MF.getSSARegMap()->getRegClass(VirtReg)); +// 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 +// virtual or needing to clobber any values if it's physical). +NextMII = &MI; +--NextMII; // backtrack to the copy. + } + VRM.RemoveFromFoldedVirtMap(&MI); + MBB.erase(&MI); + goto ProcessNextInst; } -VRM.RemoveFromFoldedVirtMap(&MI); -MBB.erase(&MI); -goto ProcessNextInst; } } } @@ -791,7 +792,21 @@ VRM.RemoveFromFoldedVirtMap(&MI); goto ProcessNextInst; } + + // If it's not a no-op copy, it clobbers the value in the destreg. Spills.ClobberPhysReg(VirtReg); + + // Check to see if this instruction is a load from a stack slot into + // a register. If so, this provides the stack slot value in the reg. + int FrameIdx; + if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) { +assert(DestReg == VirtReg && "Unknown load situation!"); + +// Otherwise, if it wasn't available, remember that it is now! +Spills.addAvailable(FrameIdx, DestReg); +goto ProcessNextInst; + } + continue; } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.74 -> 1.75 --- Log message: Backing out Chris' last commit. It's breaking llvm-gcc bootstrapping. It's turning: movl -24(%ebp), %esp subl $16, %esp movl -24(%ebp), %ecx into movl -24(%ebp), %esp subl $16, %esp movl %esp, (%esp) --- Diffs of the changes: (+17 -32) VirtRegMap.cpp | 49 + 1 files changed, 17 insertions(+), 32 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.74 llvm/lib/CodeGen/VirtRegMap.cpp:1.75 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.74Wed Oct 11 21:34:07 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Oct 12 03:00:47 2006 @@ -706,25 +706,24 @@ if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) { int FrameIdx; if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) { - if (FrameIdx == SS) { -// If this spill slot is available, turn it into a copy (or nothing) -// instead of leaving it as a load! -if (unsigned InReg = Spills.getSpillSlotPhysReg(SS)) { - DEBUG(std::cerr << "Promoted Load To Copy: " << MI); - MachineFunction &MF = *MBB.getParent(); - if (DestReg != InReg) { -MRI->copyRegToReg(MBB, &MI, DestReg, InReg, - MF.getSSARegMap()->getRegClass(VirtReg)); -// 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 -// virtual or needing to clobber any values if it's physical). -NextMII = &MI; ---NextMII; // backtrack to the copy. - } - VRM.RemoveFromFoldedVirtMap(&MI); - MBB.erase(&MI); - goto ProcessNextInst; + // If this spill slot is available, turn it into a copy (or nothing) + // instead of leaving it as a load! + unsigned InReg; + if (FrameIdx == SS && (InReg = Spills.getSpillSlotPhysReg(SS))) { +DEBUG(std::cerr << "Promoted Load To Copy: " << MI); +MachineFunction &MF = *MBB.getParent(); +if (DestReg != InReg) { + MRI->copyRegToReg(MBB, &MI, DestReg, InReg, +MF.getSSARegMap()->getRegClass(VirtReg)); + // 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 + // virtual or needing to clobber any values if it's physical). + NextMII = &MI; + --NextMII; // backtrack to the copy. } +VRM.RemoveFromFoldedVirtMap(&MI); +MBB.erase(&MI); +goto ProcessNextInst; } } } @@ -792,21 +791,7 @@ VRM.RemoveFromFoldedVirtMap(&MI); goto ProcessNextInst; } - - // If it's not a no-op copy, it clobbers the value in the destreg. Spills.ClobberPhysReg(VirtReg); - - // Check to see if this instruction is a load from a stack slot into - // a register. If so, this provides the stack slot value in the reg. - int FrameIdx; - if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) { -assert(DestReg == VirtReg && "Unknown load situation!"); - -// Otherwise, if it wasn't available, remember that it is now! -Spills.addAvailable(FrameIdx, DestReg); -goto ProcessNextInst; - } - continue; } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.73 -> 1.74 --- Log message: If we see a load from a stack slot into a physreg, consider it as providing the stack slot. This fixes PR943: http://llvm.org/PR943 . --- Diffs of the changes: (+32 -17) VirtRegMap.cpp | 49 - 1 files changed, 32 insertions(+), 17 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.73 llvm/lib/CodeGen/VirtRegMap.cpp:1.74 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.73Mon Sep 4 21:12:02 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Wed Oct 11 21:34:07 2006 @@ -706,24 +706,25 @@ if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) { int FrameIdx; if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) { - // If this spill slot is available, turn it into a copy (or nothing) - // instead of leaving it as a load! - unsigned InReg; - if (FrameIdx == SS && (InReg = Spills.getSpillSlotPhysReg(SS))) { -DEBUG(std::cerr << "Promoted Load To Copy: " << MI); -MachineFunction &MF = *MBB.getParent(); -if (DestReg != InReg) { - MRI->copyRegToReg(MBB, &MI, DestReg, InReg, -MF.getSSARegMap()->getRegClass(VirtReg)); - // 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 - // virtual or needing to clobber any values if it's physical). - NextMII = &MI; - --NextMII; // backtrack to the copy. + if (FrameIdx == SS) { +// If this spill slot is available, turn it into a copy (or nothing) +// instead of leaving it as a load! +if (unsigned InReg = Spills.getSpillSlotPhysReg(SS)) { + DEBUG(std::cerr << "Promoted Load To Copy: " << MI); + MachineFunction &MF = *MBB.getParent(); + if (DestReg != InReg) { +MRI->copyRegToReg(MBB, &MI, DestReg, InReg, + MF.getSSARegMap()->getRegClass(VirtReg)); +// 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 +// virtual or needing to clobber any values if it's physical). +NextMII = &MI; +--NextMII; // backtrack to the copy. + } + VRM.RemoveFromFoldedVirtMap(&MI); + MBB.erase(&MI); + goto ProcessNextInst; } -VRM.RemoveFromFoldedVirtMap(&MI); -MBB.erase(&MI); -goto ProcessNextInst; } } } @@ -791,7 +792,21 @@ VRM.RemoveFromFoldedVirtMap(&MI); goto ProcessNextInst; } + + // If it's not a no-op copy, it clobbers the value in the destreg. Spills.ClobberPhysReg(VirtReg); + + // Check to see if this instruction is a load from a stack slot into + // a register. If so, this provides the stack slot value in the reg. + int FrameIdx; + if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) { +assert(DestReg == VirtReg && "Unknown load situation!"); + +// Otherwise, if it wasn't available, remember that it is now! +Spills.addAvailable(FrameIdx, DestReg); +goto ProcessNextInst; + } + continue; } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.69 -> 1.70 --- Log message: Added a check so that if we have two machine instructions in this form MOV R0, R1 MOV R1, R0 the second machine instruction is removed. Added a regression test. --- Diffs of the changes: (+30 -10) VirtRegMap.cpp | 40 ++-- 1 files changed, 30 insertions(+), 10 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.69 llvm/lib/CodeGen/VirtRegMap.cpp:1.70 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.69Fri Jul 21 16:15:20 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Mon Aug 21 02:33:33 2006 @@ -521,6 +521,7 @@ // Process all of the spilled uses and all non spilled reg references. for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { MachineOperand &MO = MI.getOperand(i); + if (!MO.isRegister() || MO.getReg() == 0) continue; // Ignore non-register operands. @@ -790,16 +791,37 @@ } if (!OpTakenCareOf) { -// Check to see if this is a noop copy. If so, eliminate the -// instruction before considering the dest reg to be changed. unsigned Src, Dst; -if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) { - ++NumDCE; - DEBUG(std::cerr << "Removing now-noop copy: " << MI); - MBB.erase(&MI); - VRM.RemoveFromFoldedVirtMap(&MI); - goto ProcessNextInst; +if (TII->isMoveInstr(MI, Src, Dst)) { + if (Src == Dst) { +// Check to see if this is a noop copy. If so, eliminate +// the instruction before considering the dest reg to be +// changed. +++NumDCE; +DEBUG(std::cerr << "Removing now-noop copy: " << MI); +MBB.erase(&MI); +VRM.RemoveFromFoldedVirtMap(&MI); +goto ProcessNextInst; + } else if (MII != MBB.begin()) { +// Check to see if this is a sequence of the form: +//mov R0, R1 +//mov R1, R0 +// Eliminate the second move if so. +MachineBasicBlock::iterator PrevMII = MII; --PrevMII; +MachineInstr& PrevMI = *PrevMII; +unsigned PrevSrc, PrevDst; + +if (TII->isMoveInstr(PrevMI, PrevSrc, PrevDst)) + if (PrevSrc == Dst && PrevDst == Src) { +++NumDCE; +DEBUG(std::cerr << "Removing now-noop copy: " << MI); +MBB.erase(&MI); +VRM.RemoveFromFoldedVirtMap(&MI); +goto ProcessNextInst; + } + } } + Spills.ClobberPhysReg(VirtReg); continue; } @@ -861,8 +883,6 @@ } } - - llvm::Spiller* llvm::createSpiller() { switch (SpillerOpt) { default: assert(0 && "Unreachable!"); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp VirtRegMap.h
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.64 -> 1.65 VirtRegMap.h updated: 1.20 -> 1.21 --- Log message: Fix a latent bug that my spiller patch last week exposed: we were leaving instructions in the virtregfolded map that were deleted. Because they were deleted, newly allocated instructions could end up at the same address, magically finding themselves in the map. The solution is to remove entries from the map when we delete the instructions. --- Diffs of the changes: (+7 -4) VirtRegMap.cpp |4 VirtRegMap.h |7 +++ 2 files changed, 7 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.64 llvm/lib/CodeGen/VirtRegMap.cpp:1.65 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.64Mon May 1 16:17:10 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Mon May 1 17:03:24 2006 @@ -730,6 +730,7 @@ assert(VirtRegMap::isMod && "Can't be modref!"); DEBUG(std::cerr << "Removed dead store:\t" << *MDSI->second); MBB.erase(MDSI->second); + VRM.RemoveFromFoldedVirtMap(MDSI->second); MaybeDeadStores.erase(MDSI); ++NumDSE; } @@ -791,6 +792,7 @@ ++NumDCE; DEBUG(std::cerr << "Removing now-noop copy: " << MI); MBB.erase(&MI); + VRM.RemoveFromFoldedVirtMap(&MI); goto ProcessNextInst; } Spills.ClobberPhysReg(VirtReg); @@ -825,6 +827,7 @@ ++NumDCE; DEBUG(std::cerr << "Removing now-noop copy: " << MI); MBB.erase(&MI); +VRM.RemoveFromFoldedVirtMap(&MI); goto ProcessNextInst; } } @@ -835,6 +838,7 @@ DEBUG(std::cerr << "Removed dead store:\t" << *LastStore); ++NumDSE; MBB.erase(LastStore); + VRM.RemoveFromFoldedVirtMap(LastStore); } LastStore = next(MII); Index: llvm/lib/CodeGen/VirtRegMap.h diff -u llvm/lib/CodeGen/VirtRegMap.h:1.20 llvm/lib/CodeGen/VirtRegMap.h:1.21 --- llvm/lib/CodeGen/VirtRegMap.h:1.20 Mon May 1 16:16:03 2006 +++ llvm/lib/CodeGen/VirtRegMap.h Mon May 1 17:03:24 2006 @@ -137,11 +137,10 @@ return MI2VirtMap.equal_range(MI); } -/// RemoveFromFoldedVirtMap - Given a machine instruction in the folded -/// instruction map, remove the entry in the folded instruction map. +/// RemoveFromFoldedVirtMap - If the specified machine instruction is in +/// the folded instruction map, remove its entry from the map. void RemoveFromFoldedVirtMap(MachineInstr *MI) { - bool ErasedAny = MI2VirtMap.erase(MI); - assert(ErasedAny && "Machine instr not in folded vreg map!"); + MI2VirtMap.erase(MI); } void print(std::ostream &OS) const; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.63 -> 1.64 --- Log message: When promoting a load to a reg-reg copy, where the load was a previous instruction folded with spill code, make sure the remove the load from the virt reg folded map. --- Diffs of the changes: (+1 -0) VirtRegMap.cpp |1 + 1 files changed, 1 insertion(+) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.63 llvm/lib/CodeGen/VirtRegMap.cpp:1.64 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.63Mon May 1 16:16:03 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Mon May 1 16:17:10 2006 @@ -712,6 +712,7 @@ NextMII = &MI; --NextMII; // backtrack to the copy. } +VRM.RemoveFromFoldedVirtMap(&MI); MBB.erase(&MI); goto ProcessNextInst; } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.61 -> 1.62 --- Log message: Remove temp. option -spiller-check-liveout, it didn't cause any failure nor performance regressions. --- Diffs of the changes: (+1 -5) VirtRegMap.cpp |6 +- 1 files changed, 1 insertion(+), 5 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.61 llvm/lib/CodeGen/VirtRegMap.cpp:1.62 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.61Sun Apr 30 03:41:47 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Mon May 1 03:54:57 2006 @@ -50,10 +50,6 @@ clEnumVal(local, " local spiller"), clEnumValEnd), cl::init(local)); - - // TEMPORARY option to test a fix. - cl::opt - SpillerCheckLiveOut("spiller-check-liveout", cl::Hidden); } //===--===// @@ -735,7 +731,7 @@ // If we get here, the store is dead, nuke it now. assert(!(MR & VirtRegMap::isRef) && "Can't be modref!"); // Don't nuke it if the value is needed in another block. - if (!SpillerCheckLiveOut || !(MR & VirtRegMap::isLiveOut)) { + if (!(MR & VirtRegMap::isLiveOut)) { DEBUG(std::cerr << " Killed store:\t" << *MDSI->second); MBB.erase(MDSI->second); MaybeDeadStores.erase(MDSI); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.59 -> 1.60 --- Log message: Mapping of physregs can make it so that the designated and input physregs are the same. In this case, don't emit a noop copy. --- Diffs of the changes: (+13 -0) VirtRegMap.cpp | 13 + 1 files changed, 13 insertions(+) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.59 llvm/lib/CodeGen/VirtRegMap.cpp:1.60 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.59Thu Apr 27 20:46:50 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Apr 27 23:43:18 2006 @@ -611,6 +611,19 @@ DesignatedReg = ReusedOperands.GetRegForReload(DesignatedReg, &MI, Spills, MaybeDeadStores); +// If the mapped designated register is actually the physreg we have +// incoming, we don't need to inserted a dead copy. +if (DesignatedReg == PhysReg) { + // If this stack slot value is already available, reuse it! + DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg " + << MRI->getName(PhysReg) << " for vreg" + << VirtReg + << " instead of reloading into same physreg.\n"); + MI.SetMachineOperandReg(i, PhysReg); + ++NumReused; + continue; +} + const TargetRegisterClass* RC = MBB.getParent()->getSSARegMap()->getRegClass(VirtReg); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.58 -> 1.59 --- Log message: When we have a two-address instruction where the input cannot be clobbered and is already available, instead of falling back to emitting a load, fall back to emitting a reg-reg copy. This generates significantly better code for some SSE testcases, as SSE has lots of two-address instructions and none of them are read/modify/write. As one example, this change does: pshufd %XMM5, XMMWORD PTR [%ESP + 84], 255 xorps %XMM2, %XMM5 cmpltps %XMM1, %XMM0 - movaps XMMWORD PTR [%ESP + 52], %XMM0 - movapd %XMM6, XMMWORD PTR [%ESP + 52] + movaps %XMM6, %XMM0 cmpltps %XMM6, XMMWORD PTR [%ESP + 68] movapd XMMWORD PTR [%ESP + 52], %XMM6 movaps %XMM6, %XMM0 cmpltps %XMM6, XMMWORD PTR [%ESP + 36] cmpltps %XMM3, %XMM0 - movaps XMMWORD PTR [%ESP + 20], %XMM0 - movapd %XMM7, XMMWORD PTR [%ESP + 20] + movaps %XMM7, %XMM0 cmpltps %XMM7, XMMWORD PTR [%ESP + 4] movapd XMMWORD PTR [%ESP + 20], %XMM7 cmpltps %XMM4, %XMM0 ... which is far better than a store followed by a load! --- Diffs of the changes: (+63 -25) VirtRegMap.cpp | 88 - 1 files changed, 63 insertions(+), 25 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.58 llvm/lib/CodeGen/VirtRegMap.cpp:1.59 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.58Fri Feb 24 20:17:31 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Apr 27 20:46:50 2006 @@ -558,33 +558,71 @@ unsigned PhysReg; // Check to see if this stack slot is available. - if ((PhysReg = Spills.getSpillSlotPhysReg(StackSlot)) && - // Don't reuse it for a def&use operand if we aren't allowed to change - // the physreg! - (!MO.isDef() || Spills.canClobberPhysReg(StackSlot))) { -// If this stack slot value is already available, reuse it! -DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg " -<< MRI->getName(PhysReg) << " for vreg" -<< VirtReg <<" instead of reloading into physreg " -<< MRI->getName(VRM.getPhys(VirtReg)) << "\n"); -MI.SetMachineOperandReg(i, PhysReg); + if ((PhysReg = Spills.getSpillSlotPhysReg(StackSlot))) { -// The only technical detail we have is that we don't know that -// PhysReg won't be clobbered by a reloaded stack slot that occurs -// later in the instruction. In particular, consider 'op V1, V2'. -// If V1 is available in physreg R0, we would choose to reuse it -// here, instead of reloading it into the register the allocator -// indicated (say R1). However, V2 might have to be reloaded -// later, and it might indicate that it needs to live in R0. When -// this occurs, we need to have information available that -// indicates it is safe to use R1 for the reload instead of R0. +// Don't reuse it for a def&use operand if we aren't allowed to change +// the physreg! +if (!MO.isDef() || Spills.canClobberPhysReg(StackSlot)) { + // If this stack slot value is already available, reuse it! + DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg " + << MRI->getName(PhysReg) << " for vreg" + << VirtReg <<" instead of reloading into physreg " + << MRI->getName(VRM.getPhys(VirtReg)) << "\n"); + MI.SetMachineOperandReg(i, PhysReg); + + // The only technical detail we have is that we don't know that + // PhysReg won't be clobbered by a reloaded stack slot that occurs + // later in the instruction. In particular, consider 'op V1, V2'. + // If V1 is available in physreg R0, we would choose to reuse it + // here, instead of reloading it into the register the allocator + // indicated (say R1). However, V2 might have to be reloaded + // later, and it might indicate that it needs to live in R0. When + // this occurs, we need to have information available that + // indicates it is safe to use R1 for the reload instead of R0. + // + // To further complicate matters, we might conflict with an alias, + // or R0 and R1 might not be compatible with each other. In this + // case, we actually insert a reload for V1 in R1, ensuring that + // we can get at R0 or its alias. + ReusedOperands.addReuse(i, StackSlot, PhysReg, + VRM.getPhys(VirtReg), VirtReg); + ++NumReused; + continue; +} + +// Otherwise we have a situation where we have a two-address instruction +// whose mod/ref operand needs to be reloaded. This re
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.57 -> 1.58 --- Log message: Fix a bug that Evan exposed with some changes he's making, and that was exposed with a fastcc problem (breaking pcompress2 on x86 with -enable-x86-fastcc). When reloading a reused reg, make sure to invalidate the reloaded reg, and check to see if there are any other pending uses of the same register. --- Diffs of the changes: (+23 -9) VirtRegMap.cpp | 32 +++- 1 files changed, 23 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.57 llvm/lib/CodeGen/VirtRegMap.cpp:1.58 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.57Fri Feb 24 20:03:40 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 24 20:17:31 2006 @@ -437,25 +437,39 @@ // to undo a previous reuse. MachineBasicBlock *MBB = MI->getParent(); const TargetRegisterClass *AliasRC = -MBB->getParent()->getSSARegMap()->getRegClass(Op.VirtReg); -MRI->loadRegFromStackSlot(*MBB, MI, Op.AssignedPhysReg, - Op.StackSlot, AliasRC); -Spills.ClobberPhysReg(Op.AssignedPhysReg); -Spills.ClobberPhysReg(Op.PhysRegReused); + MBB->getParent()->getSSARegMap()->getRegClass(Op.VirtReg); + +// Copy Op out of the vector and remove it, we're going to insert an +// explicit load for it. +ReusedOp NewOp = Op; +Reuses.erase(Reuses.begin()+ro); + +// Ok, we're going to try to reload the assigned physreg into the +// slot that we were supposed to in the first place. However, that +// register could hold a reuse. Check to see if it conflicts or +// would prefer us to use a different register. +unsigned NewPhysReg = GetRegForReload(NewOp.AssignedPhysReg, + MI, Spills, MaybeDeadStores); + +MRI->loadRegFromStackSlot(*MBB, MI, NewPhysReg, + NewOp.StackSlot, AliasRC); +Spills.ClobberPhysReg(NewPhysReg); +Spills.ClobberPhysReg(NewOp.PhysRegReused); // Any stores to this stack slot are not dead anymore. -MaybeDeadStores.erase(Op.StackSlot); +MaybeDeadStores.erase(NewOp.StackSlot); -MI->SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg); +MI->SetMachineOperandReg(NewOp.Operand, NewPhysReg); -Spills.addAvailable(Op.StackSlot, Op.AssignedPhysReg); +Spills.addAvailable(NewOp.StackSlot, NewPhysReg); ++NumLoads; DEBUG(MachineBasicBlock::iterator MII = MI; std::cerr << '\t' << *prior(MII)); DEBUG(std::cerr << "Reuse undone!\n"); -Reuses.erase(Reuses.begin()+ro); --NumReused; + +// Finally, PhysReg is now available, go ahead and use it. return PhysReg; } } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.56 -> 1.57 --- Log message: Remove debugging printout :) Add a minor compile time win, no codegen change. --- Diffs of the changes: (+6 -5) VirtRegMap.cpp | 11 ++- 1 files changed, 6 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.56 llvm/lib/CodeGen/VirtRegMap.cpp:1.57 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.56Fri Feb 24 19:51:33 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 24 20:03:40 2006 @@ -419,8 +419,12 @@ // register. if (Op.PhysRegReused == PhysReg) { // Yup, use the reload register that we didn't use before. - return GetRegForReload(Op.AssignedPhysReg, MI, - Spills, MaybeDeadStores); + unsigned NewReg = Op.AssignedPhysReg; + + // Remove the record for the previous reuse. We know it can never be + // invalidated now. + Reuses.erase(Reuses.begin()+ro); + return GetRegForReload(NewReg, MI, Spills, MaybeDeadStores); } else { // Otherwise, we might also have a problem if a previously reused // value aliases the new register. If so, codegen the previous reload @@ -487,9 +491,6 @@ bool *PhysRegsUsed = MBB.getParent()->getUsedPhysregs(); - if (MBB.getBasicBlock()->getName() == "endif.3.i") -std::cerr << "HERE\n"; - for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end(); MII != E; ) { MachineInstr &MI = *MII; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.55 -> 1.56 --- Log message: Refactor some code from being inline to being out in a new class with methods. This gets rid of two gotos, which is always nice, and also adds some comments. No functionality change, this is just a refactor. --- Diffs of the changes: (+97 -42) VirtRegMap.cpp | 139 +++-- 1 files changed, 97 insertions(+), 42 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.55 llvm/lib/CodeGen/VirtRegMap.cpp:1.56 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.55Fri Feb 3 21:27:39 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 24 19:51:33 2006 @@ -269,6 +269,8 @@ return I->second >> 1; // Remove the CanClobber bit. return 0; } + + const MRegisterInfo *getRegInfo() const { return MRI; } /// addAvailable - Mark that the specified stack slot is available in the /// specified physreg. If CanClobber is true, the physreg can be modified at @@ -375,6 +377,88 @@ : Operand(o), StackSlot(ss), PhysRegReused(prr), AssignedPhysReg(apr), VirtReg(vreg) {} }; + + /// ReuseInfo - This maintains a collection of ReuseOp's for each operand that + /// is reused instead of reloaded. + class ReuseInfo { +MachineInstr &MI; +std::vector Reuses; + public: +ReuseInfo(MachineInstr &mi) : MI(mi) {} + +bool hasReuses() const { + return !Reuses.empty(); +} + +/// addReuse - If we choose to reuse a virtual register that is already +/// available instead of reloading it, remember that we did so. +void addReuse(unsigned OpNo, unsigned StackSlot, + unsigned PhysRegReused, unsigned AssignedPhysReg, + unsigned VirtReg) { + // If the reload is to the assigned register anyway, no undo will be + // required. + if (PhysRegReused == AssignedPhysReg) return; + + // Otherwise, remember this. + Reuses.push_back(ReusedOp(OpNo, StackSlot, PhysRegReused, +AssignedPhysReg, VirtReg)); +} + +/// GetRegForReload - We are about to emit a reload into PhysReg. If there +/// is some other operand that is using the specified register, either pick +/// a new register to use, or evict the previous reload and use this reg. +unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI, + AvailableSpills &Spills, + std::map &MaybeDeadStores) { + if (Reuses.empty()) return PhysReg; // This is most often empty. + + for (unsigned ro = 0, e = Reuses.size(); ro != e; ++ro) { +ReusedOp &Op = Reuses[ro]; +// If we find some other reuse that was supposed to use this register +// exactly for its reload, we can change this reload to use ITS reload +// register. +if (Op.PhysRegReused == PhysReg) { + // Yup, use the reload register that we didn't use before. + return GetRegForReload(Op.AssignedPhysReg, MI, + Spills, MaybeDeadStores); +} else { + // Otherwise, we might also have a problem if a previously reused + // value aliases the new register. If so, codegen the previous reload + // and use this one. + unsigned PRRU = Op.PhysRegReused; + const MRegisterInfo *MRI = Spills.getRegInfo(); + if (MRI->areAliases(PRRU, PhysReg)) { +// Okay, we found out that an alias of a reused register +// was used. This isn't good because it means we have +// to undo a previous reuse. +MachineBasicBlock *MBB = MI->getParent(); +const TargetRegisterClass *AliasRC = +MBB->getParent()->getSSARegMap()->getRegClass(Op.VirtReg); +MRI->loadRegFromStackSlot(*MBB, MI, Op.AssignedPhysReg, + Op.StackSlot, AliasRC); +Spills.ClobberPhysReg(Op.AssignedPhysReg); +Spills.ClobberPhysReg(Op.PhysRegReused); + +// Any stores to this stack slot are not dead anymore. +MaybeDeadStores.erase(Op.StackSlot); + +MI->SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg); + +Spills.addAvailable(Op.StackSlot, Op.AssignedPhysReg); +++NumLoads; +DEBUG(MachineBasicBlock::iterator MII = MI; + std::cerr << '\t' << *prior(MII)); + +DEBUG(std::cerr << "Reuse undone!\n"); +Reuses.erase(Reuses.begin()+ro); +--NumReused; +return PhysReg; + } +} + } + return PhysReg; +} + }; } @@ -388,8 +472,6 @@ // that we can choose to reuse the physregs instead of emitting reloads. AvailableSpills Spills(MRI, TII); - std::vector ReusedOperands; -
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.54 -> 1.55 --- Log message: Fix VC++ warning. --- Diffs of the changes: (+1 -1) VirtRegMap.cpp |2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.54 llvm/lib/CodeGen/VirtRegMap.cpp:1.55 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.54Fri Feb 3 17:50:46 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 3 21:27:39 2006 @@ -279,7 +279,7 @@ ModifyStackSlot(Slot); PhysRegsAvailable.insert(std::make_pair(Reg, Slot)); -SpillSlotsAvailable[Slot] = (Reg << 1) | CanClobber; +SpillSlotsAvailable[Slot] = (Reg << 1) | (unsigned)CanClobber; DEBUG(std::cerr << "Remembering SS#" << Slot << " in physreg " << MRI->getName(Reg) << "\n"); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.53 -> 1.54 --- Log message: Handle another case exposed on X86. --- Diffs of the changes: (+4 -0) VirtRegMap.cpp |4 1 files changed, 4 insertions(+) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.53 llvm/lib/CodeGen/VirtRegMap.cpp:1.54 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.53Fri Feb 3 17:28:46 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 3 17:50:46 2006 @@ -274,6 +274,10 @@ /// specified physreg. If CanClobber is true, the physreg can be modified at /// any time without changing the semantics of the program. void addAvailable(int Slot, unsigned Reg, bool CanClobber = true) { +// If this stack slot is thought to be available in some other physreg, +// remove its record. +ModifyStackSlot(Slot); + PhysRegsAvailable.insert(std::make_pair(Reg, Slot)); SpillSlotsAvailable[Slot] = (Reg << 1) | CanClobber; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.52 -> 1.53 --- Log message: Fix a nasty problem on two-address machines in the following situation: store EAX -> [ss#0] [ss#0] += 1 ... use(EAX) In this case, it is not valid to rewrite this as: store EAX -> [ss#0] EAX += 1 store EAX -> [ss#0] ;;; this would also delete the store above ... use(EAX) ... because EAX is not a dead at that point. Keep track of which registers we are allowed to clobber, and which ones we aren't, and don't clobber the ones we're not supposed to. :) This should resolve the issues on X86 last night. --- Diffs of the changes: (+27 -9) VirtRegMap.cpp | 36 +++- 1 files changed, 27 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.52 llvm/lib/CodeGen/VirtRegMap.cpp:1.53 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.52Fri Feb 3 17:13:58 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 3 17:28:46 2006 @@ -233,6 +233,14 @@ /// AvailableSpills - As the local spiller is scanning and rewriting an MBB from /// top down, keep track of which spills slots are available in each register. +/// +/// Note that not all physregs are created equal here. In particular, some +/// physregs are reloads that we are allowed to clobber or ignore at any time. +/// Other physregs are values that the register allocated program is using that +/// we cannot CHANGE, but we can read if we like. We keep track of this on a +/// per-stack-slot basis as the low bit in the value of the SpillSlotsAvailable +/// entries. The predicate 'canClobberPhysReg()' checks this bit and +/// addAvailable sets it if. class AvailableSpills { const MRegisterInfo *MRI; const TargetInstrInfo *TII; @@ -258,20 +266,28 @@ unsigned getSpillSlotPhysReg(int Slot) const { std::map::const_iterator I = SpillSlotsAvailable.find(Slot); if (I != SpillSlotsAvailable.end()) - return I->second; + return I->second >> 1; // Remove the CanClobber bit. return 0; } /// addAvailable - Mark that the specified stack slot is available in the - /// specified physreg. - void addAvailable(int Slot, unsigned Reg) { + /// specified physreg. If CanClobber is true, the physreg can be modified at + /// any time without changing the semantics of the program. + void addAvailable(int Slot, unsigned Reg, bool CanClobber = true) { PhysRegsAvailable.insert(std::make_pair(Reg, Slot)); -SpillSlotsAvailable[Slot] = Reg; +SpillSlotsAvailable[Slot] = (Reg << 1) | CanClobber; DEBUG(std::cerr << "Remembering SS#" << Slot << " in physreg " << MRI->getName(Reg) << "\n"); } + /// canClobberPhysReg - Return true if the spiller is allowed to change the + /// value of the specified stackslot register if it desires. The specified + /// stack slot must be available in a physreg for this query to make sense. + bool canClobberPhysReg(int Slot) const { +assert(SpillSlotsAvailable.count(Slot) && "Slot not available!"); +return SpillSlotsAvailable.find(Slot)->second & 1; + } /// ClobberPhysReg - This is called when the specified physreg changes /// value. We use this to invalidate any info about stuff we thing lives in @@ -292,7 +308,7 @@ while (I != PhysRegsAvailable.end() && I->first == PhysReg) { int Slot = I->second; PhysRegsAvailable.erase(I++); -assert(SpillSlotsAvailable[Slot] == PhysReg && +assert((SpillSlotsAvailable[Slot] >> 1) == PhysReg && "Bidirectional map mismatch!"); SpillSlotsAvailable.erase(Slot); DEBUG(std::cerr << "PhysReg " << MRI->getName(PhysReg) @@ -315,7 +331,7 @@ void AvailableSpills::ModifyStackSlot(int Slot) { std::map::iterator It = SpillSlotsAvailable.find(Slot); if (It == SpillSlotsAvailable.end()) return; - unsigned Reg = It->second; + unsigned Reg = It->second >> 1; SpillSlotsAvailable.erase(It); // This register may hold the value of multiple stack slots, only remove this @@ -435,7 +451,10 @@ unsigned PhysReg; // Check to see if this stack slot is available. - if ((PhysReg = Spills.getSpillSlotPhysReg(StackSlot))) { + if ((PhysReg = Spills.getSpillSlotPhysReg(StackSlot)) && + // Don't reuse it for a def&use operand if we aren't allowed to change + // the physreg! + (!MO.isDef() || Spills.canClobberPhysReg(StackSlot))) { // If this stack slot value is already available, reuse it! DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg " << MRI->getName(PhysReg) << " for vreg" @@ -613,7 +632,7 @@ // If the stack slot value was previously available in some other // register, change it now. Otherwise, make the register available, // in PhysReg. -Spills.addAvailable(StackSlot, SrcReg); +Spills.addAvailable(StackSlot, Src
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.51 -> 1.52 --- Log message: 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. --- Diffs of the changes: (+97 -69) VirtRegMap.cpp | 166 + 1 files changed, 97 insertions(+), 69 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.51 llvm/lib/CodeGen/VirtRegMap.cpp:1.52 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.51Thu Feb 2 21:48:54 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 3 17:13:58 2006 @@ -231,38 +231,92 @@ }; } -void LocalSpiller::ClobberPhysRegOnly(unsigned PhysReg, - std::map &SpillSlots, - std::multimap &PhysRegsAvailable) { - std::multimap::iterator I = PhysRegsAvailable.lower_bound(PhysReg); +/// AvailableSpills - As the local spiller is scanning and rewriting an MBB from +/// top down, keep track of which spills slots are available in each register. +class AvailableSpills { + 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 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 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::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::iterator I = +PhysRegsAvailable.lower_bound(PhysReg); while (I != PhysRegsAvailable.end() && I->first == PhysReg) { int Slot = I->second; PhysRegsAvailable.erase(I++); -assert(SpillSlots[Slot] == PhysReg && "Bidirectional map mismatch!"); -SpillSlots.erase(Slot); +assert(SpillSlotsAvailable[Slot] == PhysReg && + "Bidirectional map mismatch!"); +SpillSlotsAvailable.erase(Slot); DEBUG(std::cerr << "PhysReg " << MRI->getName(PhysReg) << " clobbered, invalidating SS#" << Slot << "\n"); - } } -void LocalSpiller::ClobberPhysReg(unsigned PhysReg, - std::map &SpillSlots, - std::multimap &PhysRegsAvailable) { +/// 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 AvailableSpills::ClobberPhysReg(unsigned PhysReg) { for (const unsigned *AS = MRI->getAliasSet(PhysReg); *AS; ++AS) -ClobberPhysRegOnly(*AS, SpillSlots, PhysRegsAvailable); - ClobberPhysRegOnly(PhysReg, SpillSlots, PhysRegsAvailable); +ClobberPhysRegOnly(*AS); + ClobberPhysRegOnly(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 LocalSpiller::ModifyStackSlot(int Slot, std::map &SpillSlots, -
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.50 -> 1.51 --- Log message: Fix VC++ compilation error caused by using a std::map iterator variable to receive a std::multimap iterator value. For some reason, GCC doesn't have a problem with this. --- Diffs of the changes: (+1 -1) VirtRegMap.cpp |2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.50 llvm/lib/CodeGen/VirtRegMap.cpp:1.51 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.50Thu Feb 2 21:16:14 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 2 21:48:54 2006 @@ -234,7 +234,7 @@ void LocalSpiller::ClobberPhysRegOnly(unsigned PhysReg, std::map &SpillSlots, std::multimap &PhysRegsAvailable) { - std::map::iterator I = PhysRegsAvailable.lower_bound(PhysReg); + std::multimap::iterator I = PhysRegsAvailable.lower_bound(PhysReg); while (I != PhysRegsAvailable.end() && I->first == PhysReg) { int Slot = I->second; PhysRegsAvailable.erase(I++); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.49 -> 1.50 --- Log message: Remove move copies and dead stuff by not clobbering the result reg of a noop copy. --- Diffs of the changes: (+21 -12) VirtRegMap.cpp | 33 + 1 files changed, 21 insertions(+), 12 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.49 llvm/lib/CodeGen/VirtRegMap.cpp:1.50 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.49Thu Feb 2 21:06:49 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 2 21:16:14 2006 @@ -607,6 +607,15 @@ } if (!OpTakenCareOf) { +// Check to see if this is a noop copy. If so, eliminate the +// instruction before considering the dest reg to be changed. +unsigned Src, Dst; +if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) { + ++NumDCE; + DEBUG(std::cerr << "Removing now-noop copy: " << MI); + MBB.erase(&MI); + goto ProcessNextInst; +} ClobberPhysReg(VirtReg, SpillSlotsAvailable, PhysRegsAvailable); continue; } @@ -631,6 +640,18 @@ DEBUG(std::cerr << "Store:\t" << *next(MII)); MI.SetMachineOperandReg(i, PhysReg); +// Check to see if this is a noop copy. If so, eliminate the +// instruction before considering the dest reg to be changed. +{ + unsigned Src, Dst; + if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) { +++NumDCE; +DEBUG(std::cerr << "Removing now-noop copy: " << MI); +MBB.erase(&MI); +goto ProcessNextInst; + } +} + // If there is a dead store to this stack slot, nuke it now. MachineInstr *&LastStore = MaybeDeadStores[StackSlot]; if (LastStore) { @@ -654,18 +675,6 @@ ++NumStores; } } - -// Okay, the instruction has been completely processed, input and output -// registers have been added. As a final sanity check, make sure this is -// not a noop-copy. If it is, nuke it. -{ - unsigned Src, Dst; - if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) { -++NumDCE; -DEBUG(std::cerr << "Removing now-noop copy: " << MI); -MBB.erase(&MI); - } -} ProcessNextInst: MII = NextMII; } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.48 -> 1.49 --- Log message: Simplify some code --- Diffs of the changes: (+40 -45) VirtRegMap.cpp | 85 ++--- 1 files changed, 40 insertions(+), 45 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.48 llvm/lib/CodeGen/VirtRegMap.cpp:1.49 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.48Thu Feb 2 20:02:59 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 2 21:06:49 2006 @@ -593,7 +593,6 @@ if (MO.isRegister() && MO.getReg() && MO.isDef()) { unsigned VirtReg = MO.getReg(); -bool TakenCareOf = false; if (!MRegisterInfo::isVirtualRegister(VirtReg)) { // Check to see if this is a def-and-use vreg operand that we do need // to insert a store for. @@ -609,54 +608,50 @@ if (!OpTakenCareOf) { ClobberPhysReg(VirtReg, SpillSlotsAvailable, PhysRegsAvailable); -TakenCareOf = true; +continue; } } -if (!TakenCareOf) { - // The only vregs left are stack slot definitions. - int StackSlot = VRM.getStackSlot(VirtReg); - const TargetRegisterClass *RC = -MBB.getParent()->getSSARegMap()->getRegClass(VirtReg); - unsigned PhysReg; - - // If this is a def&use operand, and we used a different physreg for - // it than the one assigned, make sure to execute the store from the - // correct physical register. - if (MO.getReg() == VirtReg) -PhysReg = VRM.getPhys(VirtReg); - else -PhysReg = MO.getReg(); - - PhysRegsUsed[PhysReg] = true; - MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC); - DEBUG(std::cerr << "Store:\t" << *next(MII)); - MI.SetMachineOperandReg(i, PhysReg); - - // If there is a dead store to this stack slot, nuke it now. - MachineInstr *&LastStore = MaybeDeadStores[StackSlot]; - if (LastStore) { -DEBUG(std::cerr << " Killed store:\t" << *LastStore); -++NumDSE; -MBB.erase(LastStore); - } - LastStore = next(MII); - - // If the stack slot value was previously available in some other - // register, change it now. Otherwise, make the register available, - // in PhysReg. - ModifyStackSlot(StackSlot, SpillSlotsAvailable, PhysRegsAvailable); - ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable); - - PhysRegsAvailable.insert(std::make_pair(PhysReg, StackSlot)); - SpillSlotsAvailable[StackSlot] = PhysReg; - DEBUG(std::cerr << "Updating SS#" << StackSlot <<" in physreg " - << MRI->getName(PhysReg) << " for virtreg #" - << VirtReg << "\n"); - - ++NumStores; - VirtReg = PhysReg; +// The only vregs left are stack slot definitions. +int StackSlot = VRM.getStackSlot(VirtReg); +const TargetRegisterClass *RC = + MBB.getParent()->getSSARegMap()->getRegClass(VirtReg); +unsigned PhysReg; + +// If this is a def&use operand, and we used a different physreg for +// it than the one assigned, make sure to execute the store from the +// correct physical register. +if (MO.getReg() == VirtReg) + PhysReg = VRM.getPhys(VirtReg); +else + PhysReg = MO.getReg(); + +PhysRegsUsed[PhysReg] = true; +MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC); +DEBUG(std::cerr << "Store:\t" << *next(MII)); +MI.SetMachineOperandReg(i, PhysReg); + +// If there is a dead store to this stack slot, nuke it now. +MachineInstr *&LastStore = MaybeDeadStores[StackSlot]; +if (LastStore) { + DEBUG(std::cerr << " Killed store:\t" << *LastStore); + ++NumDSE; + MBB.erase(LastStore); } +LastStore = next(MII); + +// If the stack slot value was previously available in some other +// register, change it now. Otherwise, make the register available, +// in PhysReg. +ModifyStackSlot(StackSlot, SpillSlotsAvailable, PhysRegsAvailable); +ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable); + +PhysRegsAvailable.insert(std::make_pair(PhysReg, StackSlot)); +SpillSlotsAvailable[StackSlot] = PhysReg; +DEBUG(std::cerr << "Updating SS#" << StackSlot <<" in physreg " +<< MRI->getName(PhysReg) << " for virtreg #" +<< VirtReg << "\n"); +++NumStores; } } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.47 -> 1.48 --- Log message: Add code that checks for noop copies, which triggers when either: 1. a target doesn't know how to fold load/stores into copies, or 2. the spiller rewrites the input to a copy to the same register as the dest instead of to the reloaded reg. This will be moved/improved in the near future, but allows elimination of some ancient x86 hacks. This eliminates 92 copies from SMG2000 on X86 and 163 copies from 252.eon. --- Diffs of the changes: (+13 -0) VirtRegMap.cpp | 13 + 1 files changed, 13 insertions(+) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.47 llvm/lib/CodeGen/VirtRegMap.cpp:1.48 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.47Thu Feb 2 18:36:31 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 2 20:02:59 2006 @@ -38,6 +38,7 @@ Statistic<> NumLoads ("spiller", "Number of loads added"); Statistic<> NumReused("spiller", "Number of values reused"); Statistic<> NumDSE ("spiller", "Number of dead stores elided"); + Statistic<> NumDCE ("spiller", "Number of copies elided"); enum SpillerName { simple, local }; @@ -658,6 +659,18 @@ } } } + +// Okay, the instruction has been completely processed, input and output +// registers have been added. As a final sanity check, make sure this is +// not a noop-copy. If it is, nuke it. +{ + unsigned Src, Dst; + if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) { +++NumDCE; +DEBUG(std::cerr << "Removing now-noop copy: " << MI); +MBB.erase(&MI); + } +} ProcessNextInst: MII = NextMII; } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.46 -> 1.47 --- Log message: Physregs may hold multiple stack slot values at the same time. Keep track of this, and use it to our advantage (bwahahah). This allows us to eliminate another 60 instructions from smg2000 on PPC (probably significantly more on X86). A common old-new diff looks like this: stw r2, 3304(r1) - lwz r2, 3192(r1) stw r2, 3300(r1) - lwz r2, 3192(r1) stw r2, 3296(r1) - lwz r2, 3192(r1) stw r2, 3200(r1) - lwz r2, 3192(r1) stw r2, 3196(r1) - lwz r2, 3192(r1) + or r2, r2, r2 stw r2, 3188(r1) and - lwz r31, 604(r1) - lwz r13, 604(r1) - lwz r14, 604(r1) - lwz r15, 604(r1) - lwz r16, 604(r1) - lwz r30, 604(r1) + or r31, r30, r30 + or r13, r30, r30 + or r14, r30, r30 + or r15, r30, r30 + or r16, r30, r30 + or r30, r30, r30 Removal of the R = R copies is coming next... --- Diffs of the changes: (+49 -37) VirtRegMap.cpp | 86 - 1 files changed, 49 insertions(+), 37 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.46 llvm/lib/CodeGen/VirtRegMap.cpp:1.47 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.46Thu Feb 2 17:29:36 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 2 18:36:31 2006 @@ -222,36 +222,60 @@ private: void RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM); void ClobberPhysReg(unsigned PR, std::map &SpillSlots, -std::map &PhysRegs); +std::multimap &PhysRegs); void ClobberPhysRegOnly(unsigned PR, std::map &SpillSlots, -std::map &PhysRegs); +std::multimap &PhysRegs); +void ModifyStackSlot(int Slot, std::map &SpillSlots, + std::multimap &PhysRegs); }; } void LocalSpiller::ClobberPhysRegOnly(unsigned PhysReg, std::map &SpillSlots, - std::map &PhysRegs) { - std::map::iterator I = PhysRegs.find(PhysReg); - if (I != PhysRegs.end()) { + std::multimap &PhysRegsAvailable) { + std::map::iterator I = PhysRegsAvailable.lower_bound(PhysReg); + while (I != PhysRegsAvailable.end() && I->first == PhysReg) { int Slot = I->second; -PhysRegs.erase(I); +PhysRegsAvailable.erase(I++); assert(SpillSlots[Slot] == PhysReg && "Bidirectional map mismatch!"); SpillSlots.erase(Slot); DEBUG(std::cerr << "PhysReg " << MRI->getName(PhysReg) - << " clobbered, invalidating SS#" << Slot << "\n"); +<< " clobbered, invalidating SS#" << Slot << "\n"); } } void LocalSpiller::ClobberPhysReg(unsigned PhysReg, std::map &SpillSlots, - std::map &PhysRegs) { + std::multimap &PhysRegsAvailable) { for (const unsigned *AS = MRI->getAliasSet(PhysReg); *AS; ++AS) -ClobberPhysRegOnly(*AS, SpillSlots, PhysRegs); - ClobberPhysRegOnly(PhysReg, SpillSlots, PhysRegs); +ClobberPhysRegOnly(*AS, SpillSlots, PhysRegsAvailable); + ClobberPhysRegOnly(PhysReg, SpillSlots, PhysRegsAvailable); +} + +/// 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 LocalSpiller::ModifyStackSlot(int Slot, std::map &SpillSlots, + std::multimap &PhysRegsAvailable) { + std::map::iterator It = SpillSlots.find(Slot); + if (It == SpillSlots.end()) return; + unsigned Reg = It->second; + SpillSlots.erase(It); + + // This register may hold the value of multiple stack slots, only remove this + // stack slot from the set of values the register contains. + std::multimap::iterator I = PhysRegsAvailable.lower_bound(Reg); + for (; ; ++I) { +assert(I != PhysRegsAvailable.end() && I->first == Reg && + "Map inverse broken!"); +if (I->second == Slot) break; + } + PhysRegsAvailable.erase(I); } + // ReusedOp - For each reused operand, we keep track of a bit of information, in // case we need to rollback upon processing a new operand. See comments below. namespace { @@ -289,8 +313,9 @@ std::map SpillSlotsAvailable; // PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating - // which physregs are in use holding a stack slot value. - std::map PhysRegsAvailable; + // 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 PhysRegsAvailable; DEBUG(std::cerr << MBB.getBasicBlock()->getName() << ":\n"); @@ -427,12 +452
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.45 -> 1.46 --- Log message: Fix a deficiency in the spiller that Evan noticed. In particular, consider this code: store [stack slot #0], R10 = add R14, [stack slot #0] The spiller didn't know that the store made the value of [stackslot#0] available in R10 *IF* the store came from a copy instruction with the store folded into it. This patch teaches VirtRegMap to look at these stores and recognize the values they make available. In one case Evan provided, this code: divsd %XMM0, %XMM1 movsd %XMM1, QWORD PTR [%ESP + 40] 1) movsd QWORD PTR [%ESP + 48], %XMM1 2) movsd %XMM1, QWORD PTR [%ESP + 48] addsd %XMM1, %XMM0 3) movsd QWORD PTR [%ESP + 48], %XMM1 movsd QWORD PTR [%ESP + 4], %XMM0 turns into: divsd %XMM0, %XMM1 movsd %XMM1, QWORD PTR [%ESP + 40] addsd %XMM1, %XMM0 3) movsd QWORD PTR [%ESP + 48], %XMM1 movsd QWORD PTR [%ESP + 4], %XMM0 In this case, instruction #2 was removed because of the value made available by #1, and inst #1 was later deleted because it is now never used before the stack slot is redefined by #3. This occurs here and there in a lot of code with high spilling, on PPC most of the removed loads/stores are LSU-reject-causing loads, which is nice. On X86, things are much better (because it spills more), where we nuke about 1% of the instructions from SMG2000 and several hundred from eon. More improvements to come... --- Diffs of the changes: (+31 -1) VirtRegMap.cpp | 32 +++- 1 files changed, 31 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.45 llvm/lib/CodeGen/VirtRegMap.cpp:1.46 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.45Thu Feb 2 14:12:13 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 2 17:29:36 2006 @@ -284,7 +284,7 @@ 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 to stored to, + // register values that are still available, due to being loaded or stored to, // but not invalidated yet. std::map SpillSlotsAvailable; @@ -535,6 +535,36 @@ PhysRegsAvailable.erase(It->second); SpillSlotsAvailable.erase(It); } + +// 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 +// so, realize that the vreg is available now, and add the store to the +// MaybeDeadStore info. +int StackSlot; +if (!(MR & VirtRegMap::isRef)) { + if (unsigned SrcReg = TII->isStoreToStackSlot(&MI, StackSlot)) { +assert(MRegisterInfo::isPhysicalRegister(SrcReg) && + "Src hasn't been allocated yet?"); +// Okay, this is certainly a store of SrcReg to [FrameIdx]. Mark +// this as a potentially dead store in case there is a subsequent +// store into the stack slot without a read from it. +MaybeDeadStores[StackSlot] = &MI; + +// FIXME: PhysRegsAvailable is a 1-1 map, not a N-1 map, which means +// that we have to *forget* that SrcReg contains the old value it +// does. +ClobberPhysRegOnly(SrcReg, SpillSlotsAvailable, PhysRegsAvailable); + +// If the stack slot value was previously available in some other +// register, change it now. Otherwise, make the register available, +// in PhysReg. +SpillSlotsAvailable[StackSlot] = SrcReg; +PhysRegsAvailable[SrcReg] = StackSlot; +DEBUG(std::cerr << "Updating SS#" << StackSlot << " in physreg " +<< MRI->getName(SrcReg) << " for virtreg #" +<< VirtReg << "\n" << MI); + } +} } } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.44 -> 1.45 --- Log message: Move isLoadFrom/StoreToStackSlot from MRegisterInfo to TargetInstrInfo,a far more logical place. Other methods should also be moved if anyoneis interested. :) --- Diffs of the changes: (+3 -2) VirtRegMap.cpp |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.44 llvm/lib/CodeGen/VirtRegMap.cpp:1.45 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.44Sun Jan 22 17:41:00 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 2 14:12:13 2006 @@ -490,8 +490,9 @@ // straight load from the virt reg slot. if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) { int FrameIdx; -if (unsigned DestReg = MRI->isLoadFromStackSlot(&MI, FrameIdx)) { - // If this spill slot is available, insert a copy for it! +if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) { + // If this spill slot is available, turn it into a copy (or nothing) + // instead of leaving it as a load! std::map::iterator It = SpillSlotsAvailable.find(SS); if (FrameIdx == SS && It != SpillSlotsAvailable.end()) { DEBUG(std::cerr << "Promoted Load To Copy: " << MI); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits