std::string msg;
raw_string_ostream Msg(msg);
Msg << "Ran out of registers during register allocation!";
- if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {
+ if (MI->isInlineAsm()) {
Msg << "\nPlease check your inline asm statement for invalid "
<< "constraints:\n";
MI->print(Msg, TM);
std::string msg;
raw_string_ostream Msg(msg);
Msg << "Ran out of registers during register allocation!";
- if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {
+ if (MI->isInlineAsm()) {
Msg << "\nPlease check your inline asm statement for invalid "
<< "constraints:\n";
MI->print(Msg, TM);
// Determine whether this is a copy instruction. The cases where the
// source or destination are phys regs are handled specially.
unsigned SrcCopyReg, DstCopyReg, SrcCopySubReg, DstCopySubReg;
+ unsigned SrcCopyPhysReg = 0U;
bool isCopy = TII->isMoveInstr(*MI, SrcCopyReg, DstCopyReg,
SrcCopySubReg, DstCopySubReg);
+ if (isCopy && TargetRegisterInfo::isVirtualRegister(SrcCopyReg))
+ SrcCopyPhysReg = getVirt2PhysRegMapSlot(SrcCopyReg);
// Loop over the implicit uses, making sure that they are at the head of the
// use order list, so they don't get reallocated.
// have in them, then mark them unallocatable.
// If any virtual regs are earlyclobber, allocate them now (before
// freeing inputs that are killed).
- if (MI->getOpcode()==TargetInstrInfo::INLINEASM) {
+ if (MI->isInlineAsm()) {
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
MachineOperand& MO = MI->getOperand(i);
if (MO.isReg() && MO.isDef() && MO.isEarlyClobber() &&
}
}
- // If a DEBUG_VALUE says something is located in a spilled register,
- // change the DEBUG_VALUE to be undef, which prevents the register
+ // If a DBG_VALUE says something is located in a spilled register,
+ // change the DBG_VALUE to be undef, which prevents the register
// from being reloaded here. Doing that would change the generated
// code, unless another use immediately follows this instruction.
- if (MI->getOpcode()==TargetInstrInfo::DEBUG_VALUE &&
+ if (MI->isDebugValue() &&
MI->getNumOperands()==3 && MI->getOperand(0).isReg()) {
unsigned VirtReg = MI->getOperand(0).getReg();
if (VirtReg && TargetRegisterInfo::isVirtualRegister(VirtReg) &&
// If DestVirtReg already has a value, use it.
if (!(DestPhysReg = getVirt2PhysRegMapSlot(DestVirtReg))) {
+ // If this is a copy try to reuse the input as the output;
+ // that will make the copy go away.
// If this is a copy, the source reg is a phys reg, and
// that reg is available, use that phys reg for DestPhysReg.
+ // If this is a copy, the source reg is a virtual reg, and
+ // the phys reg that was assigned to that virtual reg is now
+ // available, use that phys reg for DestPhysReg. (If it's now
+ // available that means this was the last use of the source.)
if (isCopy &&
TargetRegisterInfo::isPhysicalRegister(SrcCopyReg) &&
isPhysRegAvailable(SrcCopyReg)) {
DestPhysReg = SrcCopyReg;
assignVirtToPhysReg(DestVirtReg, DestPhysReg);
+ } else if (isCopy &&
+ TargetRegisterInfo::isVirtualRegister(SrcCopyReg) &&
+ SrcCopyPhysReg && isPhysRegAvailable(SrcCopyPhysReg) &&
+ MF->getRegInfo().getRegClass(DestVirtReg)->
+ contains(SrcCopyPhysReg)) {
+ DestPhysReg = SrcCopyPhysReg;
+ assignVirtToPhysReg(DestVirtReg, DestPhysReg);
} else
DestPhysReg = getReg(MBB, MI, DestVirtReg);
}