mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-03 15:36:21 +00:00
GetRegForReload() now keeps track which registers have been considered and rejected during its quest to find a suitable reload register. This avoids an infinite loop in case like this:
t1 := op t2, t3 t2 <- assigned r0 for use by the reload but ended up reuse r1 t3 <- assigned r1 for use by the reload but ended up reuse r0 t1 <- desires r1 sees r1 is taken by t2, tries t2's reload register r0 sees r0 is taken by t3, tries t3's reload register r1 sees r1 is taken by t2, tries t2's reload register r0 ... git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33382 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a867cf0265
commit
3c82cab9aa
@ -30,6 +30,7 @@
|
|||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <set>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
STATISTIC(NumSpills, "Number of register spills");
|
STATISTIC(NumSpills, "Number of register spills");
|
||||||
@ -469,18 +470,23 @@ namespace {
|
|||||||
/// a new register to use, or evict the previous reload and use this reg.
|
/// a new register to use, or evict the previous reload and use this reg.
|
||||||
unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
|
unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
|
||||||
AvailableSpills &Spills,
|
AvailableSpills &Spills,
|
||||||
std::map<int, MachineInstr*> &MaybeDeadStores) {
|
std::map<int, MachineInstr*> &MaybeDeadStores,
|
||||||
|
std::set<unsigned> &Rejected) {
|
||||||
if (Reuses.empty()) return PhysReg; // This is most often empty.
|
if (Reuses.empty()) return PhysReg; // This is most often empty.
|
||||||
|
|
||||||
for (unsigned ro = 0, e = Reuses.size(); ro != e; ++ro) {
|
for (unsigned ro = 0, e = Reuses.size(); ro != e; ++ro) {
|
||||||
ReusedOp &Op = Reuses[ro];
|
ReusedOp &Op = Reuses[ro];
|
||||||
// If we find some other reuse that was supposed to use this register
|
// If we find some other reuse that was supposed to use this register
|
||||||
// exactly for its reload, we can change this reload to use ITS reload
|
// exactly for its reload, we can change this reload to use ITS reload
|
||||||
// register.
|
// register. That is, unless its reload register has already been
|
||||||
if (Op.PhysRegReused == PhysReg) {
|
// considered and subsequently rejected because it has also been reused
|
||||||
|
// by another operand.
|
||||||
|
if (Op.PhysRegReused == PhysReg &&
|
||||||
|
Rejected.count(Op.AssignedPhysReg) == 0) {
|
||||||
// Yup, use the reload register that we didn't use before.
|
// Yup, use the reload register that we didn't use before.
|
||||||
unsigned NewReg = Op.AssignedPhysReg;
|
unsigned NewReg = Op.AssignedPhysReg;
|
||||||
return GetRegForReload(NewReg, MI, Spills, MaybeDeadStores);
|
Rejected.insert(PhysReg);
|
||||||
|
return GetRegForReload(NewReg, MI, Spills, MaybeDeadStores, Rejected);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, we might also have a problem if a previously reused
|
// Otherwise, we might also have a problem if a previously reused
|
||||||
// value aliases the new register. If so, codegen the previous reload
|
// value aliases the new register. If so, codegen the previous reload
|
||||||
@ -505,7 +511,7 @@ namespace {
|
|||||||
// register could hold a reuse. Check to see if it conflicts or
|
// register could hold a reuse. Check to see if it conflicts or
|
||||||
// would prefer us to use a different register.
|
// would prefer us to use a different register.
|
||||||
unsigned NewPhysReg = GetRegForReload(NewOp.AssignedPhysReg,
|
unsigned NewPhysReg = GetRegForReload(NewOp.AssignedPhysReg,
|
||||||
MI, Spills, MaybeDeadStores);
|
MI, Spills, MaybeDeadStores, Rejected);
|
||||||
|
|
||||||
MRI->loadRegFromStackSlot(*MBB, MI, NewPhysReg,
|
MRI->loadRegFromStackSlot(*MBB, MI, NewPhysReg,
|
||||||
NewOp.StackSlot, AliasRC);
|
NewOp.StackSlot, AliasRC);
|
||||||
@ -532,6 +538,24 @@ namespace {
|
|||||||
}
|
}
|
||||||
return PhysReg;
|
return PhysReg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// GetRegForReload - Helper for the above GetRegForReload(). Add a
|
||||||
|
/// 'Rejected' set to remember which registers have been considered and
|
||||||
|
/// rejected for the reload. This avoids infinite looping in case like
|
||||||
|
/// this:
|
||||||
|
/// t1 := op t2, t3
|
||||||
|
/// t2 <- assigned r0 for use by the reload but ended up reuse r1
|
||||||
|
/// t3 <- assigned r1 for use by the reload but ended up reuse r0
|
||||||
|
/// t1 <- desires r1
|
||||||
|
/// sees r1 is taken by t2, tries t2's reload register r0
|
||||||
|
/// sees r0 is taken by t3, tries t3's reload register r1
|
||||||
|
/// 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::set<unsigned> Rejected;
|
||||||
|
return GetRegForReload(PhysReg, MI, Spills, MaybeDeadStores, Rejected);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,8 +650,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
|
|||||||
MI.getOperand(ti).isReg() &&
|
MI.getOperand(ti).isReg() &&
|
||||||
MI.getOperand(ti).getReg() == VirtReg) {
|
MI.getOperand(ti).getReg() == VirtReg) {
|
||||||
// Okay, we have a two address operand. We can reuse this physreg as
|
// Okay, we have a two address operand. We can reuse this physreg as
|
||||||
// long as we are allowed to clobber the value and there is an earlier
|
// long as we are allowed to clobber the value and there isn't an
|
||||||
// def that has already clobbered the physreg.
|
// earlier def that has already clobbered the physreg.
|
||||||
CanReuse = Spills.canClobberPhysReg(StackSlot) &&
|
CanReuse = Spills.canClobberPhysReg(StackSlot) &&
|
||||||
!ReusedOperands.isClobbered(PhysReg);
|
!ReusedOperands.isClobbered(PhysReg);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user