diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2009-11-14 02:09:09 +0000 |
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2009-11-14 02:09:09 +0000 |
| commit | 8fdd84cfa74e248394a8f5049e7478bf2535a150 (patch) | |
| tree | 39681756d8a90a4f21598cbe485ccb39086bfc58 /lib/CodeGen/VirtRegRewriter.cpp | |
| parent | ed9bab3b4da0a5c5581fdd477c19c02420dd2fc7 (diff) | |
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
Diffstat (limited to 'lib/CodeGen/VirtRegRewriter.cpp')
| -rw-r--r-- | lib/CodeGen/VirtRegRewriter.cpp | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp index dcd2a75ae0..91aaa8c063 100644 --- a/lib/CodeGen/VirtRegRewriter.cpp +++ b/lib/CodeGen/VirtRegRewriter.cpp @@ -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); } - - if (!MI.isRegTiedToDefOperand(i)) - // Unless it's a two-address operand, this is the new kill. - MO.setIsKill(); + } 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); + + 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. |
