diff options
| author | David Goodwin <david_goodwin@apple.com> | 2009-09-23 16:35:25 +0000 |
|---|---|---|
| committer | David Goodwin <david_goodwin@apple.com> | 2009-09-23 16:35:25 +0000 |
| commit | a4c98a3e342f37f31edf6fa8591902841e9dcabf (patch) | |
| tree | fa128d4031a4c93292c8de72bc0ab9074a226a4d /llvm | |
| parent | b4bd0666d2b185c9b9e3ad19cc6c3e8859a1284b (diff) | |
| download | bcm5719-llvm-a4c98a3e342f37f31edf6fa8591902841e9dcabf.tar.gz bcm5719-llvm-a4c98a3e342f37f31edf6fa8591902841e9dcabf.zip | |
Fix bug in kill flag updating for post-register-allocation scheduling. When the kill flag of a superreg needs to be cleared because there are one or more subregs live, we instead add implicit-defs of those subregs and leave the kill flag on the superreg. This allows us to end the live-range of the superreg without ending the live-ranges of the subregs.
llvm-svn: 82629
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/CodeGen/PostRASchedulerList.cpp | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/PostRASchedulerList.cpp b/llvm/lib/CodeGen/PostRASchedulerList.cpp index f6c84d89114..0f2d3095ac0 100644 --- a/llvm/lib/CodeGen/PostRASchedulerList.cpp +++ b/llvm/lib/CodeGen/PostRASchedulerList.cpp @@ -178,6 +178,11 @@ namespace { unsigned LastNewReg, const TargetRegisterClass *); void StartBlockForKills(MachineBasicBlock *BB); + + // ToggleKillFlag - Toggle a register operand kill flag. Other + // adjustments may be made to the instruction if necessary. Return + // true if the operand has been deleted, false if not. + bool ToggleKillFlag(MachineInstr *MI, MachineOperand &MO); }; } @@ -822,6 +827,40 @@ void SchedulePostRATDList::StartBlockForKills(MachineBasicBlock *BB) { } } +bool SchedulePostRATDList::ToggleKillFlag(MachineInstr *MI, + MachineOperand &MO) { + // Setting kill flag... + if (!MO.isKill()) { + MO.setIsKill(true); + return false; + } + + // If MO itself is live, clear the kill flag... + if (KillIndices[MO.getReg()] != ~0u) { + MO.setIsKill(false); + return false; + } + + // If any subreg of MO is live, then create an imp-def for that + // subreg and keep MO marked as killed. + bool AllDead = true; + const unsigned SuperReg = MO.getReg(); + for (const unsigned *Subreg = TRI->getSubRegisters(SuperReg); + *Subreg; ++Subreg) { + if (KillIndices[*Subreg] != ~0u) { + MI->addOperand(MachineOperand::CreateReg(*Subreg, + true /*IsDef*/, + true /*IsImp*/, + false /*IsKill*/, + false /*IsDead*/)); + AllDead = false; + } + } + + MO.setIsKill(AllDead); + return false; +} + /// FixupKills - Fix the register kill flags, they may have been made /// incorrect by instruction reordering. /// @@ -860,9 +899,9 @@ void SchedulePostRATDList::FixupKills(MachineBasicBlock *MBB) { } } - // Examine all used registers and set kill flag. When a register - // is used multiple times we only set the kill flag on the first - // use. + // Examine all used registers and set/clear kill flag. When a + // register is used multiple times we only set the kill flag on + // the first use. killedRegs.clear(); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand &MO = MI->getOperand(i); @@ -889,8 +928,12 @@ void SchedulePostRATDList::FixupKills(MachineBasicBlock *MBB) { } if (MO.isKill() != kill) { - MO.setIsKill(kill); - DEBUG(errs() << "Fixed " << MO << " in "); + bool removed = ToggleKillFlag(MI, MO); + if (removed) { + DEBUG(errs() << "Fixed <removed> in "); + } else { + DEBUG(errs() << "Fixed " << MO << " in "); + } DEBUG(MI->dump()); } |

