mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-24 22:24:54 +00:00
[MachineCSE] Clear kill-flag on registers imp-def'd by the CSE'd instruction.
Go through implicit defs of CSMI and MI, and clear the kill flags on their uses in all the instructions between CSMI and MI. We might have made some of the kill flags redundant, consider: subs ... %NZCV<imp-def> <- CSMI csinc ... %NZCV<imp-use,kill> <- this kill flag isn't valid anymore subs ... %NZCV<imp-def> <- MI, to be eliminated csinc ... %NZCV<imp-use,kill> Since we eliminated MI, and reused a register imp-def'd by CSMI (here %NZCV), that register, if it was killed before MI, should have that kill flag removed, because it's lifetime was extended. Also, add an exhaustive testcase for the motivating example. Reviewed by: Juergen Ributzka <juergen@apple.com> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223133 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -451,6 +451,7 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) {
|
||||
|
||||
SmallVector<std::pair<unsigned, unsigned>, 8> CSEPairs;
|
||||
SmallVector<unsigned, 2> ImplicitDefsToUpdate;
|
||||
SmallVector<unsigned, 2> ImplicitDefs;
|
||||
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E; ) {
|
||||
MachineInstr *MI = &*I;
|
||||
++I;
|
||||
@@ -542,6 +543,12 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) {
|
||||
// we should make sure it is not dead at CSMI.
|
||||
if (MO.isImplicit() && !MO.isDead() && CSMI->getOperand(i).isDead())
|
||||
ImplicitDefsToUpdate.push_back(i);
|
||||
|
||||
// Keep track of implicit defs of CSMI and MI, to clear possibly
|
||||
// made-redundant kill flags.
|
||||
if (MO.isImplicit() && !MO.isDead() && OldReg == NewReg)
|
||||
ImplicitDefs.push_back(OldReg);
|
||||
|
||||
if (OldReg == NewReg) {
|
||||
--NumDefs;
|
||||
continue;
|
||||
@@ -582,6 +589,29 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) {
|
||||
for (unsigned i = 0, e = ImplicitDefsToUpdate.size(); i != e; ++i)
|
||||
CSMI->getOperand(ImplicitDefsToUpdate[i]).setIsDead(false);
|
||||
|
||||
// Go through implicit defs of CSMI and MI, and clear the kill flags on
|
||||
// their uses in all the instructions between CSMI and MI.
|
||||
// We might have made some of the kill flags redundant, consider:
|
||||
// subs ... %NZCV<imp-def> <- CSMI
|
||||
// csinc ... %NZCV<imp-use,kill> <- this kill flag isn't valid anymore
|
||||
// subs ... %NZCV<imp-def> <- MI, to be eliminated
|
||||
// csinc ... %NZCV<imp-use,kill>
|
||||
// Since we eliminated MI, and reused a register imp-def'd by CSMI
|
||||
// (here %NZCV), that register, if it was killed before MI, should have
|
||||
// that kill flag removed, because it's lifetime was extended.
|
||||
if (CSMI->getParent() == MI->getParent()) {
|
||||
for (MachineBasicBlock::iterator II = CSMI, IE = MI; II != IE; ++II)
|
||||
for (auto ImplicitDef : ImplicitDefs)
|
||||
if (MachineOperand *MO = II->findRegisterUseOperand(
|
||||
ImplicitDef, /*isKill=*/true, TRI))
|
||||
MO->setIsKill(false);
|
||||
} else {
|
||||
// If the instructions aren't in the same BB, bail out and clear the
|
||||
// kill flag on all uses of the imp-def'd register.
|
||||
for (auto ImplicitDef : ImplicitDefs)
|
||||
MRI->clearKillFlags(ImplicitDef);
|
||||
}
|
||||
|
||||
if (CrossMBBPhysDef) {
|
||||
// Add physical register defs now coming in from a predecessor to MBB
|
||||
// livein list.
|
||||
@@ -606,6 +636,7 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) {
|
||||
}
|
||||
CSEPairs.clear();
|
||||
ImplicitDefsToUpdate.clear();
|
||||
ImplicitDefs.clear();
|
||||
}
|
||||
|
||||
return Changed;
|
||||
|
Reference in New Issue
Block a user