diff options
author | Evan Cheng <evan.cheng@apple.com> | 2006-12-14 07:54:05 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2006-12-14 07:54:05 +0000 |
commit | 7a0d51c8e3d6cdc6d961f6525f97f8926fb76c83 (patch) | |
tree | 7adcde95c80848de9531083a042556a7d570a462 /lib/CodeGen/VirtRegMap.cpp | |
parent | 8e58a1b17bb57e6ffa187a0ec758f9a1bed7685b (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32576 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/VirtRegMap.cpp')
-rw-r--r-- | lib/CodeGen/VirtRegMap.cpp | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index c51d4ab9aa..04a6cf1307 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -272,6 +272,8 @@ class VISIBILITY_HIDDEN AvailableSpills { // invalidate entries in SpillSlotsAvailable when a physreg is modified. std::multimap<unsigned, int> PhysRegsAvailable; + void disallowClobberPhysRegOnly(unsigned PhysReg); + void ClobberPhysRegOnly(unsigned PhysReg); public: AvailableSpills(const MRegisterInfo *mri, const TargetInstrInfo *tii) @@ -303,7 +305,7 @@ public: 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 @@ public: 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 @@ public: }; } +/// 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<unsigned, int>::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 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) { DOUT << "Removing now-noop copy: " << MI; MBB.erase(&MI); VRM.RemoveFromFoldedVirtMap(&MI); + Spills.disallowClobberPhysReg(VirtReg); goto ProcessNextInst; } |