aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2007-07-11 19:17:18 +0000
committerEvan Cheng <evan.cheng@apple.com>2007-07-11 19:17:18 +0000
commit28bb462d4cfb8c849a0d9a1b1f3c643b77b8efc6 (patch)
tree711cb517a9635e1a633bfd09768c227c45c32e99
parentbfbfb3c464e2e89653bc0a76c67cf807ecd0fd6a (diff)
downloadexternal_llvm-28bb462d4cfb8c849a0d9a1b1f3c643b77b8efc6.zip
external_llvm-28bb462d4cfb8c849a0d9a1b1f3c643b77b8efc6.tar.gz
external_llvm-28bb462d4cfb8c849a0d9a1b1f3c643b77b8efc6.tar.bz2
Missed a couple of places where new instructions are added due to spill / restore.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@39748 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/VirtRegMap.cpp144
1 files changed, 77 insertions, 67 deletions
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp
index c9eb17d..196e849 100644
--- a/lib/CodeGen/VirtRegMap.cpp
+++ b/lib/CodeGen/VirtRegMap.cpp
@@ -426,6 +426,63 @@ void AvailableSpills::ModifyStackSlot(int Slot) {
+/// InvalidateKills - MI is going to be deleted. If any of its operands are
+/// marked kill, then invalidate the information.
+static void InvalidateKills(MachineInstr &MI, BitVector &RegKills,
+ std::vector<MachineOperand*> &KillOps) {
+ for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI.getOperand(i);
+ if (!MO.isReg() || !MO.isUse() || !MO.isKill())
+ continue;
+ unsigned Reg = MO.getReg();
+ if (KillOps[Reg] == &MO) {
+ RegKills.reset(Reg);
+ KillOps[Reg] = NULL;
+ }
+ }
+}
+
+/// UpdateKills - Track and update kill info. If a MI reads a register that is
+/// marked kill, then it must be due to register reuse. Transfer the kill info
+/// over.
+static void UpdateKills(MachineInstr &MI, BitVector &RegKills,
+ std::vector<MachineOperand*> &KillOps) {
+ const TargetInstrDescriptor *TID = MI.getInstrDescriptor();
+ for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI.getOperand(i);
+ if (!MO.isReg() || !MO.isUse())
+ continue;
+ unsigned Reg = MO.getReg();
+ if (Reg == 0)
+ continue;
+
+ if (RegKills[Reg]) {
+ // That can't be right. Register is killed but not re-defined and it's
+ // being reused. Let's fix that.
+ KillOps[Reg]->unsetIsKill();
+ if (i < TID->numOperands &&
+ TID->getOperandConstraint(i, TOI::TIED_TO) == -1)
+ // Unless it's a two-address operand, this is the new kill.
+ MO.setIsKill();
+ }
+
+ if (MO.isKill()) {
+ RegKills.set(Reg);
+ KillOps[Reg] = &MO;
+ }
+ }
+
+ for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI.getOperand(i);
+ if (!MO.isReg() || !MO.isDef())
+ continue;
+ unsigned Reg = MO.getReg();
+ RegKills.reset(Reg);
+ KillOps[Reg] = NULL;
+ }
+}
+
+
// 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 {
@@ -494,7 +551,9 @@ namespace {
unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
AvailableSpills &Spills,
std::map<int, MachineInstr*> &MaybeDeadStores,
- SmallSet<unsigned, 8> &Rejected) {
+ SmallSet<unsigned, 8> &Rejected,
+ BitVector &RegKills,
+ std::vector<MachineOperand*> &KillOps) {
if (Reuses.empty()) return PhysReg; // This is most often empty.
for (unsigned ro = 0, e = Reuses.size(); ro != e; ++ro) {
@@ -509,7 +568,8 @@ namespace {
// Yup, use the reload register that we didn't use before.
unsigned NewReg = Op.AssignedPhysReg;
Rejected.insert(PhysReg);
- return GetRegForReload(NewReg, MI, Spills, MaybeDeadStores, Rejected);
+ return GetRegForReload(NewReg, MI, Spills, MaybeDeadStores, Rejected,
+ RegKills, KillOps);
} else {
// Otherwise, we might also have a problem if a previously reused
// value aliases the new register. If so, codegen the previous reload
@@ -534,7 +594,8 @@ namespace {
// 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, Rejected);
+ MI, Spills, MaybeDeadStores,
+ Rejected, RegKills, KillOps);
MRI->loadRegFromStackSlot(*MBB, MI, NewPhysReg,
NewOp.StackSlot, AliasRC);
@@ -548,8 +609,10 @@ namespace {
Spills.addAvailable(NewOp.StackSlot, MI, NewPhysReg);
++NumLoads;
- DEBUG(MachineBasicBlock::iterator MII = MI;
- DOUT << '\t' << *prior(MII));
+ MachineBasicBlock::iterator MII = MI;
+ --MII;
+ UpdateKills(*MII, RegKills, KillOps);
+ DOUT << '\t' << *MII;
DOUT << "Reuse undone!\n";
--NumReused;
@@ -575,71 +638,17 @@ namespace {
/// sees r1 is taken by t2, tries t2's reload register r0 ...
unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
AvailableSpills &Spills,
- std::map<int, MachineInstr*> &MaybeDeadStores) {
+ std::map<int, MachineInstr*> &MaybeDeadStores,
+ BitVector &RegKills,
+ std::vector<MachineOperand*> &KillOps) {
SmallSet<unsigned, 8> Rejected;
- return GetRegForReload(PhysReg, MI, Spills, MaybeDeadStores, Rejected);
+ return GetRegForReload(PhysReg, MI, Spills, MaybeDeadStores, Rejected,
+ RegKills, KillOps);
}
};
}
-/// InvalidateKills - MI is going to be deleted. If any of its operands are
-/// marked kill, then invalidate the information.
-static void InvalidateKills(MachineInstr &MI, BitVector &RegKills,
- std::vector<MachineOperand*> &KillOps) {
- for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
- MachineOperand &MO = MI.getOperand(i);
- if (!MO.isReg() || !MO.isUse() || !MO.isKill())
- continue;
- unsigned Reg = MO.getReg();
- if (KillOps[Reg] == &MO) {
- RegKills.reset(Reg);
- KillOps[Reg] = NULL;
- }
- }
-}
-
-/// UpdateKills - Track and update kill info. If a MI reads a register that is
-/// marked kill, then it must be due to register reuse. Transfer the kill info
-/// over.
-static void UpdateKills(MachineInstr &MI, BitVector &RegKills,
- std::vector<MachineOperand*> &KillOps) {
- const TargetInstrDescriptor *TID = MI.getInstrDescriptor();
- for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
- MachineOperand &MO = MI.getOperand(i);
- if (!MO.isReg() || !MO.isUse())
- continue;
- unsigned Reg = MO.getReg();
- if (Reg == 0)
- continue;
-
- if (RegKills[Reg]) {
- // That can't be right. Register is killed but not re-defined and it's
- // being reused. Let's fix that.
- KillOps[Reg]->unsetIsKill();
- if (i < TID->numOperands &&
- TID->getOperandConstraint(i, TOI::TIED_TO) == -1)
- // Unless it's a two-address operand, this is the new kill.
- MO.setIsKill();
- }
-
- if (MO.isKill()) {
- RegKills.set(Reg);
- KillOps[Reg] = &MO;
- }
- }
-
- for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
- const MachineOperand &MO = MI.getOperand(i);
- if (!MO.isReg() || !MO.isDef())
- continue;
- unsigned Reg = MO.getReg();
- RegKills.reset(Reg);
- KillOps[Reg] = NULL;
- }
-}
-
-
/// rewriteMBB - Keep track of which spills are available even after the
/// register allocator is done with them. If possible, avoid reloading vregs.
void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
@@ -820,7 +829,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
// reuser.
if (ReusedOperands.hasReuses())
DesignatedReg = ReusedOperands.GetRegForReload(DesignatedReg, &MI,
- Spills, MaybeDeadStores);
+ Spills, MaybeDeadStores, RegKills, KillOps);
// If the mapped designated register is actually the physreg we have
// incoming, we don't need to inserted a dead copy.
@@ -868,7 +877,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
// reuser.
if (ReusedOperands.hasReuses())
PhysReg = ReusedOperands.GetRegForReload(PhysReg, &MI,
- Spills, MaybeDeadStores);
+ Spills, MaybeDeadStores, RegKills, KillOps);
MF.setPhysRegUsed(PhysReg);
ReusedOperands.markClobbered(PhysReg);
@@ -1044,7 +1053,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
// Another def has taken the assigned physreg. It must have been a
// use&def which got it due to reuse. Undo the reuse!
PhysReg = ReusedOperands.GetRegForReload(PhysReg, &MI,
- Spills, MaybeDeadStores);
+ Spills, MaybeDeadStores, RegKills, KillOps);
}
}
@@ -1083,6 +1092,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
MBB.erase(&MI);
Erased = true;
VRM.RemoveFromFoldedVirtMap(&MI);
+ UpdateKills(*LastStore, RegKills, KillOps);
goto ProcessNextInst;
}
}