summaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-03-17 01:23:09 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-03-17 01:23:09 +0000
commite47b0089d92497e7726516610ff6f925d6828569 (patch)
treed0e42df0e704954a17b5a602172145c97c217211 /lib/CodeGen
parent7ea02ffe918baff29a39981276e83b0e845ede03 (diff)
downloadllvm-e47b0089d92497e7726516610ff6f925d6828569.tar.gz
llvm-e47b0089d92497e7726516610ff6f925d6828569.tar.bz2
llvm-e47b0089d92497e7726516610ff6f925d6828569.tar.xz
Spiller may unfold load / mod / store instructions as an optimization when the would be loaded value is available in a register. It needs to check if it's legal to clobber the register. Also, the register can contain values of multiple spill slots, make sure to check all instead of just the one being unfolded.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67068 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/Spiller.cpp13
-rw-r--r--lib/CodeGen/Spiller.h26
2 files changed, 30 insertions, 9 deletions
diff --git a/lib/CodeGen/Spiller.cpp b/lib/CodeGen/Spiller.cpp
index 066963e171..d47e1fd35a 100644
--- a/lib/CodeGen/Spiller.cpp
+++ b/lib/CodeGen/Spiller.cpp
@@ -28,6 +28,7 @@ STATISTIC(NumReMats , "Number of re-materialization");
STATISTIC(NumLoads , "Number of loads added");
STATISTIC(NumReused , "Number of values reused");
STATISTIC(NumDCE , "Number of copies elided");
+STATISTIC(NumSUnfold , "Number of stores unfolded");
namespace {
enum SpillerName { simple, local };
@@ -1172,8 +1173,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
// Okay, we have a two address operand. We can reuse this physreg as
// long as we are allowed to clobber the value and there isn't an
// earlier def that has already clobbered the physreg.
- CanReuse = Spills.canClobberPhysReg(ReuseSlot) &&
- !ReusedOperands.isClobbered(PhysReg);
+ CanReuse = !ReusedOperands.isClobbered(PhysReg) &&
+ Spills.canClobberPhysReg(PhysReg);
}
if (CanReuse) {
@@ -1408,6 +1409,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
DOUT << "Removing now-noop copy: " << MI;
// Unset last kill since it's being reused.
InvalidateKill(InReg, RegKills, KillOps);
+ Spills.disallowClobberPhysReg(InReg);
}
InvalidateKills(MI, RegKills, KillOps);
@@ -1446,6 +1448,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
// the value and there isn't an earlier def that has already clobbered
// the physreg.
if (PhysReg &&
+ !ReusedOperands.isClobbered(PhysReg) &&
+ Spills.canClobberPhysReg(PhysReg) &&
!TII->isStoreToStackSlot(&MI, SS)) { // Not profitable!
MachineOperand *KillOpnd =
DeadStore->findRegisterUseOperand(PhysReg, true);
@@ -1453,7 +1457,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
// super-register is needed below.
if (KillOpnd && !KillOpnd->getSubReg() &&
TII->unfoldMemoryOperand(MF, &MI, PhysReg, false, true,NewMIs)){
- MBB.insert(MII, NewMIs[0]);
+ MBB.insert(MII, NewMIs[0]);
NewStore = NewMIs[1];
MBB.insert(MII, NewStore);
VRM.addSpillSlotUse(SS, NewStore);
@@ -1465,6 +1469,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
--NextMII; // backtrack to the unfolded instruction.
BackTracked = true;
isDead = true;
+ ++NumSUnfold;
}
}
}
@@ -1519,7 +1524,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
// 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, false/*!clobber*/);
+ Spills.addAvailable(StackSlot, SrcReg, MI.killsRegister(SrcReg));
}
}
}
diff --git a/lib/CodeGen/Spiller.h b/lib/CodeGen/Spiller.h
index e85922ec39..5a42a8279d 100644
--- a/lib/CodeGen/Spiller.h
+++ b/lib/CodeGen/Spiller.h
@@ -127,15 +127,31 @@ namespace llvm {
DOUT << " in physreg " << TRI->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 SlotOrReMat) const {
+ /// canClobberPhysRegForSS - 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 canClobberPhysRegForSS(int SlotOrReMat) const {
assert(SpillSlotsOrReMatsAvailable.count(SlotOrReMat) &&
"Value not available!");
return SpillSlotsOrReMatsAvailable.find(SlotOrReMat)->second & 1;
}
+ /// canClobberPhysReg - Return true if the spiller is allowed to clobber the
+ /// physical register where values for some stack slot(s) might be
+ /// available.
+ bool canClobberPhysReg(unsigned PhysReg) const {
+ std::multimap<unsigned, int>::const_iterator I =
+ PhysRegsAvailable.lower_bound(PhysReg);
+ while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
+ int SlotOrReMat = I->second;
+ I++;
+ if (!canClobberPhysRegForSS(SlotOrReMat))
+ return false;
+ }
+ return true;
+ }
+
/// disallowClobberPhysReg - Unset the CanClobber bit of the specified
/// stackslot register. The register is still available but is no longer
/// allowed to be modifed.
@@ -305,4 +321,4 @@ namespace llvm {
};
}
-#endif \ No newline at end of file
+#endif