summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/VirtRegMap.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2006-12-14 07:54:05 +0000
committerEvan Cheng <evan.cheng@apple.com>2006-12-14 07:54:05 +0000
commit4c306ae0c2a202669c398f49d95fd6bda8ed70da (patch)
tree1fed1592cee345b447b7c0c925d9233eb0ef9033 /llvm/lib/CodeGen/VirtRegMap.cpp
parentb8817b9b6e48ce6a0847bd67c6d01dffeb0e8cb5 (diff)
downloadbcm5719-llvm-4c306ae0c2a202669c398f49d95fd6bda8ed70da.tar.gz
bcm5719-llvm-4c306ae0c2a202669c398f49d95fd6bda8ed70da.zip
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. llvm-svn: 32576
Diffstat (limited to 'llvm/lib/CodeGen/VirtRegMap.cpp')
-rw-r--r--llvm/lib/CodeGen/VirtRegMap.cpp36
1 files changed, 35 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/VirtRegMap.cpp b/llvm/lib/CodeGen/VirtRegMap.cpp
index c51d4ab9aad..04a6cf13073 100644
--- a/llvm/lib/CodeGen/VirtRegMap.cpp
+++ b/llvm/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;
}
OpenPOWER on IntegriCloud