/// reMaterializeAll - Try to rematerialize as many uses of li_ as possible, /// and trim the live ranges after. void InlineSpiller::reMaterializeAll() { // Do a quick scan of the interval values to find if any are remattable. reMattable_.clear(); usedValues_.clear(); for (LiveInterval::const_vni_iterator I = li_->vni_begin(), E = li_->vni_end(); I != E; ++I) { VNInfo *VNI = *I; if (VNI->isUnused() || !VNI->isDefAccurate()) continue; MachineInstr *DefMI = lis_.getInstructionFromIndex(VNI->def); if (!DefMI || !tii_.isTriviallyReMaterializable(DefMI)) continue; reMattable_.insert(VNI); } // Often, no defs are remattable. if (reMattable_.empty()) return; // Try to remat before all uses of li_->reg. bool anyRemat = false; for (MachineRegisterInfo::use_nodbg_iterator RI = mri_.use_nodbg_begin(li_->reg); MachineInstr *MI = RI.skipInstruction();) anyRemat |= reMaterializeFor(MI); if (!anyRemat) return; // Remove any values that were completely rematted. bool anyRemoved = false; for (SmallPtrSet<VNInfo*, 8>::iterator I = reMattable_.begin(), E = reMattable_.end(); I != E; ++I) { VNInfo *VNI = *I; if (VNI->hasPHIKill() || usedValues_.count(VNI)) continue; MachineInstr *DefMI = lis_.getInstructionFromIndex(VNI->def); DEBUG(dbgs() << "\tremoving dead def: " << VNI->def << '\t' << *DefMI); lis_.RemoveMachineInstrFromMaps(DefMI); vrm_.RemoveMachineInstrFromMaps(DefMI); DefMI->eraseFromParent(); VNI->setIsDefAccurate(false); anyRemoved = true; } if (!anyRemoved) return; // Removing values may cause debug uses where li_ is not live. for (MachineRegisterInfo::use_iterator RI = mri_.use_begin(li_->reg); MachineInstr *MI = RI.skipInstruction();) { if (!MI->isDebugValue()) continue; // Try to preserve the debug value if li_ is live immediately after it. MachineBasicBlock::iterator NextMI = MI; ++NextMI; if (NextMI != MI->getParent()->end() && !lis_.isNotInMIMap(NextMI)) { VNInfo *VNI = li_->getVNInfoAt(lis_.getInstructionIndex(NextMI)); if (VNI && (VNI->hasPHIKill() || usedValues_.count(VNI))) continue; } DEBUG(dbgs() << "Removing debug info due to remat:" << "\t" << *MI); MI->eraseFromParent(); } }