Handle <undef> operands in TwoAddressInstructionPass.

When the source register to a 2-addr instruction is undefined, there is
no need to attempt any transformations - simply replace the source
register with the destination register.

This also comes up when lowering IMPLICIT_DEF instructions - make sure
the <undef> flag is moved to the new partial register def operand:

  %vreg8<def> = INSERT_SUBREG %vreg9<undef>, %vreg0<kill>, sub_16bit
rewrite undef:
  %vreg8<def> = INSERT_SUBREG %vreg8<undef>, %vreg0<kill>, sub_16bit
convert to:
  %vreg8:sub_16bit<def,read-undef> = COPY %vreg0<kill>

llvm-svn: 159120
This commit is contained in:
Jakob Stoklund Olesen 2012-06-25 03:27:12 +00:00
parent 87d8fb91e9
commit 6b556f824d
1 changed files with 31 additions and 12 deletions

View File

@ -1456,6 +1456,19 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
"two address instruction invalid"); "two address instruction invalid");
unsigned regB = mi->getOperand(SrcIdx).getReg(); unsigned regB = mi->getOperand(SrcIdx).getReg();
// Deal with <undef> uses immediately - simply rewrite the src operand.
if (mi->getOperand(SrcIdx).isUndef()) {
unsigned DstReg = mi->getOperand(DstIdx).getReg();
// Constrain the DstReg register class if required.
if (TargetRegisterInfo::isVirtualRegister(DstReg))
if (const TargetRegisterClass *RC = TII->getRegClass(MCID, SrcIdx,
TRI, MF))
MRI->constrainRegClass(DstReg, RC);
mi->getOperand(SrcIdx).setReg(DstReg);
DEBUG(dbgs() << "\t\trewrite undef:\t" << *mi);
continue;
}
TiedOperands[regB].push_back(std::make_pair(SrcIdx, DstIdx)); TiedOperands[regB].push_back(std::make_pair(SrcIdx, DstIdx));
} }
@ -1609,19 +1622,20 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
MadeChange = true; MadeChange = true;
DEBUG(dbgs() << "\t\trewrite to:\t" << *mi); DEBUG(dbgs() << "\t\trewrite to:\t" << *mi);
}
// Rewrite INSERT_SUBREG as COPY now that we no longer need SSA form. // Rewrite INSERT_SUBREG as COPY now that we no longer need SSA form.
if (mi->isInsertSubreg()) { if (mi->isInsertSubreg()) {
// From %reg = INSERT_SUBREG %reg, %subreg, subidx // From %reg = INSERT_SUBREG %reg, %subreg, subidx
// To %reg:subidx = COPY %subreg // To %reg:subidx = COPY %subreg
unsigned SubIdx = mi->getOperand(3).getImm(); unsigned SubIdx = mi->getOperand(3).getImm();
mi->RemoveOperand(3); mi->RemoveOperand(3);
assert(mi->getOperand(0).getSubReg() == 0 && "Unexpected subreg idx"); assert(mi->getOperand(0).getSubReg() == 0 && "Unexpected subreg idx");
mi->getOperand(0).setSubReg(SubIdx); mi->getOperand(0).setSubReg(SubIdx);
mi->RemoveOperand(1); mi->getOperand(0).setIsUndef(mi->getOperand(1).isUndef());
mi->setDesc(TII->get(TargetOpcode::COPY)); mi->RemoveOperand(1);
DEBUG(dbgs() << "\t\tconvert to:\t" << *mi); mi->setDesc(TII->get(TargetOpcode::COPY));
} DEBUG(dbgs() << "\t\tconvert to:\t" << *mi);
} }
// Clear TiedOperands here instead of at the top of the loop // Clear TiedOperands here instead of at the top of the loop
@ -1846,6 +1860,11 @@ bool TwoAddressInstructionPass::EliminateRegSequences() {
SmallVector<unsigned, 4> RealSrcs; SmallVector<unsigned, 4> RealSrcs;
SmallSet<unsigned, 4> Seen; SmallSet<unsigned, 4> Seen;
for (unsigned i = 1, e = MI->getNumOperands(); i < e; i += 2) { for (unsigned i = 1, e = MI->getNumOperands(); i < e; i += 2) {
// Nothing needs to be inserted for <undef> operands.
if (MI->getOperand(i).isUndef()) {
MI->getOperand(i).setReg(0);
continue;
}
unsigned SrcReg = MI->getOperand(i).getReg(); unsigned SrcReg = MI->getOperand(i).getReg();
unsigned SrcSubIdx = MI->getOperand(i).getSubReg(); unsigned SrcSubIdx = MI->getOperand(i).getSubReg();
unsigned SubIdx = MI->getOperand(i+1).getImm(); unsigned SubIdx = MI->getOperand(i+1).getImm();