bool LiveRangeEdit::foldAsLoad(LiveInterval *LI, SmallVectorImpl<MachineInstr*> &Dead) { MachineInstr *DefMI = 0, *UseMI = 0; // Check that there is a single def and a single use. for (MachineRegisterInfo::reg_nodbg_iterator I = MRI.reg_nodbg_begin(LI->reg), E = MRI.reg_nodbg_end(); I != E; ++I) { MachineOperand &MO = I.getOperand(); MachineInstr *MI = MO.getParent(); if (MO.isDef()) { if (DefMI && DefMI != MI) return false; if (!MI->canFoldAsLoad()) return false; DefMI = MI; } else if (!MO.isUndef()) { if (UseMI && UseMI != MI) return false; // FIXME: Targets don't know how to fold subreg uses. if (MO.getSubReg()) return false; UseMI = MI; } } if (!DefMI || !UseMI) return false; // Since we're moving the DefMI load, make sure we're not extending any live // ranges. if (!allUsesAvailableAt(DefMI, LIS.getInstructionIndex(DefMI), LIS.getInstructionIndex(UseMI))) return false; // We also need to make sure it is safe to move the load. // Assume there are stores between DefMI and UseMI. bool SawStore = true; if (!DefMI->isSafeToMove(&TII, 0, SawStore)) return false; DEBUG(dbgs() << "Try to fold single def: " << *DefMI << " into single use: " << *UseMI); SmallVector<unsigned, 8> Ops; if (UseMI->readsWritesVirtualRegister(LI->reg, &Ops).second) return false; MachineInstr *FoldMI = TII.foldMemoryOperand(UseMI, Ops, DefMI); if (!FoldMI) return false; DEBUG(dbgs() << " folded: " << *FoldMI); LIS.ReplaceMachineInstrInMaps(UseMI, FoldMI); UseMI->eraseFromParent(); DefMI->addRegisterDead(LI->reg, 0); Dead.push_back(DefMI); ++NumDCEFoldedLoads; return true; }
bool LiveRangeEdit::foldAsLoad(LiveInterval *LI, SmallVectorImpl<MachineInstr*> &Dead) { MachineInstr *DefMI = 0, *UseMI = 0; // Check that there is a single def and a single use. for (MachineRegisterInfo::reg_nodbg_iterator I = MRI.reg_nodbg_begin(LI->reg), E = MRI.reg_nodbg_end(); I != E; ++I) { MachineOperand &MO = I.getOperand(); MachineInstr *MI = MO.getParent(); if (MO.isDef()) { if (DefMI && DefMI != MI) return false; if (!MI->canFoldAsLoad()) return false; DefMI = MI; } else if (!MO.isUndef()) { if (UseMI && UseMI != MI) return false; // FIXME: Targets don't know how to fold subreg uses. if (MO.getSubReg()) return false; UseMI = MI; } } if (!DefMI || !UseMI) return false; DEBUG(dbgs() << "Try to fold single def: " << *DefMI << " into single use: " << *UseMI); SmallVector<unsigned, 8> Ops; if (UseMI->readsWritesVirtualRegister(LI->reg, &Ops).second) return false; MachineInstr *FoldMI = TII.foldMemoryOperand(UseMI, Ops, DefMI); if (!FoldMI) return false; DEBUG(dbgs() << " folded: " << *FoldMI); LIS.ReplaceMachineInstrInMaps(UseMI, FoldMI); UseMI->eraseFromParent(); DefMI->addRegisterDead(LI->reg, 0); Dead.push_back(DefMI); ++NumDCEFoldedLoads; return true; }