mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
Another rewriter bug exposed by recent coalescer changes. ReuseInfo::GetRegForReload() should make sure the "switched" register is in the desired register class. I'm surprised this hasn't caused more failures in the past.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76558 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
92645acd33
commit
5d885023fe
@ -277,7 +277,8 @@ public:
|
||||
/// GetRegForReload - We are about to emit a reload into PhysReg. If there
|
||||
/// is some other operand that is using the specified register, either pick
|
||||
/// a new register to use, or evict the previous reload and use this reg.
|
||||
unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
|
||||
unsigned GetRegForReload(const TargetRegisterClass *RC, unsigned PhysReg,
|
||||
MachineFunction &MF, MachineInstr *MI,
|
||||
AvailableSpills &Spills,
|
||||
std::vector<MachineInstr*> &MaybeDeadStores,
|
||||
SmallSet<unsigned, 8> &Rejected,
|
||||
@ -296,15 +297,17 @@ public:
|
||||
/// 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,
|
||||
unsigned GetRegForReload(unsigned VirtReg, unsigned PhysReg, MachineInstr *MI,
|
||||
AvailableSpills &Spills,
|
||||
std::vector<MachineInstr*> &MaybeDeadStores,
|
||||
BitVector &RegKills,
|
||||
std::vector<MachineOperand*> &KillOps,
|
||||
VirtRegMap &VRM) {
|
||||
SmallSet<unsigned, 8> Rejected;
|
||||
return GetRegForReload(PhysReg, MI, Spills, MaybeDeadStores, Rejected,
|
||||
RegKills, KillOps, VRM);
|
||||
MachineFunction &MF = *MI->getParent()->getParent();
|
||||
const TargetRegisterClass* RC = MF.getRegInfo().getRegClass(VirtReg);
|
||||
return GetRegForReload(RC, PhysReg, MF, MI, Spills, MaybeDeadStores,
|
||||
Rejected, RegKills, KillOps, VRM);
|
||||
}
|
||||
};
|
||||
|
||||
@ -658,15 +661,17 @@ void AvailableSpills::ModifyStackSlotOrReMat(int SlotOrReMat) {
|
||||
/// GetRegForReload - We are about to emit a reload into PhysReg. If there
|
||||
/// is some other operand that is using the specified register, either pick
|
||||
/// a new register to use, or evict the previous reload and use this reg.
|
||||
unsigned ReuseInfo::GetRegForReload(unsigned PhysReg, MachineInstr *MI,
|
||||
AvailableSpills &Spills,
|
||||
unsigned ReuseInfo::GetRegForReload(const TargetRegisterClass *RC,
|
||||
unsigned PhysReg,
|
||||
MachineFunction &MF,
|
||||
MachineInstr *MI, AvailableSpills &Spills,
|
||||
std::vector<MachineInstr*> &MaybeDeadStores,
|
||||
SmallSet<unsigned, 8> &Rejected,
|
||||
BitVector &RegKills,
|
||||
std::vector<MachineOperand*> &KillOps,
|
||||
VirtRegMap &VRM) {
|
||||
const TargetInstrInfo* TII = MI->getParent()->getParent()->getTarget()
|
||||
.getInstrInfo();
|
||||
const TargetInstrInfo* TII = MF.getTarget().getInstrInfo();
|
||||
const TargetRegisterInfo *TRI = Spills.getRegInfo();
|
||||
|
||||
if (Reuses.empty()) return PhysReg; // This is most often empty.
|
||||
|
||||
@ -678,18 +683,18 @@ unsigned ReuseInfo::GetRegForReload(unsigned PhysReg, MachineInstr *MI,
|
||||
// considered and subsequently rejected because it has also been reused
|
||||
// by another operand.
|
||||
if (Op.PhysRegReused == PhysReg &&
|
||||
Rejected.count(Op.AssignedPhysReg) == 0) {
|
||||
Rejected.count(Op.AssignedPhysReg) == 0 &&
|
||||
RC->contains(Op.AssignedPhysReg)) {
|
||||
// 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(RC, NewReg, MF, MI, Spills, MaybeDeadStores, Rejected,
|
||||
RegKills, KillOps, VRM);
|
||||
} else {
|
||||
// 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
|
||||
// and use this one.
|
||||
unsigned PRRU = Op.PhysRegReused;
|
||||
const TargetRegisterInfo *TRI = Spills.getRegInfo();
|
||||
if (TRI->areAliases(PRRU, PhysReg)) {
|
||||
// Okay, we found out that an alias of a reused register
|
||||
// was used. This isn't good because it means we have
|
||||
@ -707,9 +712,9 @@ unsigned ReuseInfo::GetRegForReload(unsigned PhysReg, MachineInstr *MI,
|
||||
// slot that we were supposed to in the first place. However, that
|
||||
// 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, RegKills, KillOps, VRM);
|
||||
unsigned NewPhysReg = GetRegForReload(RC, NewOp.AssignedPhysReg,
|
||||
MF, MI, Spills, MaybeDeadStores,
|
||||
Rejected, RegKills, KillOps, VRM);
|
||||
|
||||
MachineBasicBlock::iterator MII = MI;
|
||||
if (NewOp.StackSlotOrReMat > VirtRegMap::MAX_STACK_SLOT) {
|
||||
@ -1352,8 +1357,6 @@ private:
|
||||
TID.isCall() || TID.isBarrier() || TID.isReturn() ||
|
||||
TID.hasUnmodeledSideEffects())
|
||||
return false;
|
||||
if (TID.getImplicitDefs())
|
||||
return false;
|
||||
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
|
||||
MachineOperand &MO = MI.getOperand(i);
|
||||
if (!MO.isReg() || !MO.getReg())
|
||||
@ -1790,8 +1793,9 @@ private:
|
||||
// available. If this occurs, use the register indicated by the
|
||||
// reuser.
|
||||
if (ReusedOperands.hasReuses())
|
||||
DesignatedReg = ReusedOperands.GetRegForReload(DesignatedReg, &MI,
|
||||
Spills, MaybeDeadStores, RegKills, KillOps, VRM);
|
||||
DesignatedReg = ReusedOperands.GetRegForReload(VirtReg,
|
||||
DesignatedReg, &MI,
|
||||
Spills, MaybeDeadStores, RegKills, KillOps, VRM);
|
||||
|
||||
// If the mapped designated register is actually the physreg we have
|
||||
// incoming, we don't need to inserted a dead copy.
|
||||
@ -1842,8 +1846,8 @@ private:
|
||||
// available. If this occurs, use the register indicated by the
|
||||
// reuser.
|
||||
if (ReusedOperands.hasReuses())
|
||||
PhysReg = ReusedOperands.GetRegForReload(PhysReg, &MI,
|
||||
Spills, MaybeDeadStores, RegKills, KillOps, VRM);
|
||||
PhysReg = ReusedOperands.GetRegForReload(VirtReg, PhysReg, &MI,
|
||||
Spills, MaybeDeadStores, RegKills, KillOps, VRM);
|
||||
|
||||
RegInfo->setPhysRegUsed(PhysReg);
|
||||
ReusedOperands.markClobbered(PhysReg);
|
||||
@ -2157,8 +2161,8 @@ private:
|
||||
if (ReusedOperands.isClobbered(PhysReg)) {
|
||||
// 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, RegKills, KillOps, VRM);
|
||||
PhysReg = ReusedOperands.GetRegForReload(VirtReg, PhysReg, &MI,
|
||||
Spills, MaybeDeadStores, RegKills, KillOps, VRM);
|
||||
}
|
||||
}
|
||||
|
||||
|
5384
test/CodeGen/X86/2009-07-21-RewriterBug.ll
Normal file
5384
test/CodeGen/X86/2009-07-21-RewriterBug.ll
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user