Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
// Scan the operands to find: (1) the use operand that kills regB (if
// any); (2) whether the kill operand is being replaced by regA on
// this iteration; and (3) the first use of regB that is not being
// replaced on this iteration. A use of regB will not replaced if it
// is tied to a different destination register and will be handled on
// a later iteration.
MachineOperand *KillMO = NULL;
MachineOperand *FirstKeptMO = NULL;
bool KillMOKept = false;
for (unsigned i = 0, e = mi->getNumOperands(); i != e; ++i) {
MachineOperand &MO = mi->getOperand(i);
if (MO.isReg() && MO.getReg() == regB && MO.isUse()) {
// Check if this operand is tied to a different destination.
bool isKept = false;
unsigned dsti = 0;
if (mi->isRegTiedToDefOperand(i, &dsti) && dsti != ti) {
isKept = true;
if (!FirstKeptMO)
FirstKeptMO = &MO;
}
if (MO.isKill()) {
KillMO = &MO;
KillMOKept = isKept;
}
}
}
// Update live variables for regB.
if (KillMO) {
if (!FirstKeptMO) {
// All uses of regB are being replaced; move the kill to prevMI.
if (LV && LV->removeVirtualRegisterKilled(regB, mi))
LV->addVirtualRegisterKilled(regB, prevMI);
} else {
if (!KillMOKept) {
// The kill marker is on an operand being replaced, but there
// are other uses of regB remaining. Move the kill marker to
// one of them.
KillMO->setIsKill(false);
FirstKeptMO->setIsKill(true);
}
}
DEBUG(errs() << "\t\tprepend:\t" << *prevMI);
// Replace uses of regB with regA.
for (unsigned i = 0, e = mi->getNumOperands(); i != e; ++i) {
MachineOperand &MO = mi->getOperand(i);
if (MO.isReg() && MO.getReg() == regB && MO.isUse()) {
// Skip operands that are tied to other register definitions.
unsigned dsti = 0;
if (mi->isRegTiedToDefOperand(i, &dsti) && dsti != ti)
continue;
MO.setReg(regA);
}
assert(mi->getOperand(ti).isDef() && mi->getOperand(si).isUse());
mi->getOperand(ti).setReg(mi->getOperand(si).getReg());
MadeChange = true;
DEBUG(errs() << "\t\trewrite to:\t" << *mi);
}
mi = nmi;
}
// Some remat'ed instructions are dead.
int VReg = ReMatRegs.find_first();
while (VReg != -1) {
if (MRI->use_empty(VReg)) {
MachineInstr *DefMI = MRI->getVRegDef(VReg);
DefMI->eraseFromParent();
}