mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-30 02:25:19 +00:00
Fix PR5412: Fix an inverted check and another missing sub-register check.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@88738 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -483,19 +483,20 @@ static void InvalidateKills(MachineInstr &MI,
|
||||
}
|
||||
|
||||
/// InvalidateRegDef - If the def operand of the specified def MI is now dead
|
||||
/// (since it's spill instruction is removed), mark it isDead. Also checks if
|
||||
/// (since its spill instruction is removed), mark it isDead. Also checks if
|
||||
/// the def MI has other definition operands that are not dead. Returns it by
|
||||
/// reference.
|
||||
static bool InvalidateRegDef(MachineBasicBlock::iterator I,
|
||||
MachineInstr &NewDef, unsigned Reg,
|
||||
bool &HasLiveDef) {
|
||||
bool &HasLiveDef,
|
||||
const TargetRegisterInfo *TRI) {
|
||||
// Due to remat, it's possible this reg isn't being reused. That is,
|
||||
// the def of this reg (by prev MI) is now dead.
|
||||
MachineInstr *DefMI = I;
|
||||
MachineOperand *DefOp = NULL;
|
||||
for (unsigned i = 0, e = DefMI->getNumOperands(); i != e; ++i) {
|
||||
MachineOperand &MO = DefMI->getOperand(i);
|
||||
if (!MO.isReg() || !MO.isUse() || !MO.isKill() || MO.isUndef())
|
||||
if (!MO.isReg() || !MO.isDef() || !MO.isKill() || MO.isUndef())
|
||||
continue;
|
||||
if (MO.getReg() == Reg)
|
||||
DefOp = &MO;
|
||||
@@ -512,7 +513,8 @@ static bool InvalidateRegDef(MachineBasicBlock::iterator I,
|
||||
MachineInstr *NMI = I;
|
||||
for (unsigned j = 0, ee = NMI->getNumOperands(); j != ee; ++j) {
|
||||
MachineOperand &MO = NMI->getOperand(j);
|
||||
if (!MO.isReg() || MO.getReg() != Reg)
|
||||
if (!MO.isReg() || MO.getReg() == 0 ||
|
||||
(MO.getReg() != Reg && !TRI->isSubRegister(Reg, MO.getReg())))
|
||||
continue;
|
||||
if (MO.isUse())
|
||||
FoundUse = true;
|
||||
@@ -556,11 +558,30 @@ static void UpdateKills(MachineInstr &MI, const TargetRegisterInfo* TRI,
|
||||
KillOps[*SR] = NULL;
|
||||
RegKills.reset(*SR);
|
||||
}
|
||||
} else {
|
||||
// Check for subreg kills as well.
|
||||
// d4 =
|
||||
// store d4, fi#0
|
||||
// ...
|
||||
// = s8<kill>
|
||||
// ...
|
||||
// = d4 <avoiding reload>
|
||||
for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR) {
|
||||
unsigned SReg = *SR;
|
||||
if (RegKills[SReg] && KillOps[SReg]->getParent() != &MI) {
|
||||
KillOps[SReg]->setIsKill(false);
|
||||
unsigned KReg = KillOps[SReg]->getReg();
|
||||
KillOps[KReg] = NULL;
|
||||
RegKills.reset(KReg);
|
||||
|
||||
if (!MI.isRegTiedToDefOperand(i))
|
||||
// Unless it's a two-address operand, this is the new kill.
|
||||
MO.setIsKill();
|
||||
for (const unsigned *SSR = TRI->getSubRegisters(KReg); *SSR; ++SSR) {
|
||||
KillOps[*SSR] = NULL;
|
||||
RegKills.reset(*SSR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (MO.isKill()) {
|
||||
RegKills.set(Reg);
|
||||
KillOps[Reg] = &MO;
|
||||
@@ -1458,7 +1479,7 @@ private:
|
||||
// being reused.
|
||||
for (unsigned j = 0, ee = KillRegs.size(); j != ee; ++j) {
|
||||
bool HasOtherDef = false;
|
||||
if (InvalidateRegDef(PrevMII, *MII, KillRegs[j], HasOtherDef)) {
|
||||
if (InvalidateRegDef(PrevMII, *MII, KillRegs[j], HasOtherDef, TRI)) {
|
||||
MachineInstr *DeadDef = PrevMII;
|
||||
if (ReMatDefs.count(DeadDef) && !HasOtherDef) {
|
||||
// FIXME: This assumes a remat def does not have side effects.
|
||||
|
Reference in New Issue
Block a user