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.88 Fri 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<unsigned, int> 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<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 @@ 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