/// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions in /// predecessor basic blocks. /// bool PHIElimination::EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB) { if (MBB.empty() || !MBB.front().isPHI()) return false; // Quick exit for basic blocks without PHIs. // Get an iterator to the first instruction after the last PHI node (this may // also be the end of the basic block). MachineBasicBlock::iterator AfterPHIsIt = MBB.SkipPHIsAndLabels(MBB.begin()); while (MBB.front().isPHI()) LowerAtomicPHINode(MBB, AfterPHIsIt); return true; }
SlotIndex SplitEditor::leaveIntvAtTop(MachineBasicBlock &MBB) { assert(OpenIdx && "openIntv not called before leaveIntvAtTop"); SlotIndex Start = LIS.getMBBStartIdx(&MBB); DEBUG(dbgs() << " leaveIntvAtTop BB#" << MBB.getNumber() << ", " << Start); VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Start); if (!ParentVNI) { DEBUG(dbgs() << ": not live\n"); return Start; } VNInfo *VNI = defFromParent(0, ParentVNI, Start, MBB, MBB.SkipPHIsAndLabels(MBB.begin())); RegAssign.insert(Start, VNI->def, OpenIdx); DEBUG(dump()); return VNI->def; }
/// hoistSpill - Given a sibling copy that defines a value to be spilled, insert /// a spill at a better location. bool InlineSpiller::hoistSpill(LiveInterval &SpillLI, MachineInstr *CopyMI) { SlotIndex Idx = LIS.getInstructionIndex(CopyMI); VNInfo *VNI = SpillLI.getVNInfoAt(Idx.getRegSlot()); assert(VNI && VNI->def == Idx.getRegSlot() && "Not defined by copy"); SibValueMap::iterator I = SibValues.find(VNI); if (I == SibValues.end()) return false; const SibValueInfo &SVI = I->second; // Let the normal folding code deal with the boring case. if (!SVI.AllDefsAreReloads && SVI.SpillVNI == VNI) return false; // SpillReg may have been deleted by remat and DCE. if (!LIS.hasInterval(SVI.SpillReg)) { DEBUG(dbgs() << "Stale interval: " << PrintReg(SVI.SpillReg) << '\n'); SibValues.erase(I); return false; } LiveInterval &SibLI = LIS.getInterval(SVI.SpillReg); if (!SibLI.containsValue(SVI.SpillVNI)) { DEBUG(dbgs() << "Stale value: " << PrintReg(SVI.SpillReg) << '\n'); SibValues.erase(I); return false; } // Conservatively extend the stack slot range to the range of the original // value. We may be able to do better with stack slot coloring by being more // careful here. assert(StackInt && "No stack slot assigned yet."); LiveInterval &OrigLI = LIS.getInterval(Original); VNInfo *OrigVNI = OrigLI.getVNInfoAt(Idx); StackInt->MergeValueInAsValue(OrigLI, OrigVNI, StackInt->getValNumInfo(0)); DEBUG(dbgs() << "\tmerged orig valno " << OrigVNI->id << ": " << *StackInt << '\n'); // Already spilled everywhere. if (SVI.AllDefsAreReloads) { DEBUG(dbgs() << "\tno spill needed: " << SVI); ++NumOmitReloadSpill; return true; } // We are going to spill SVI.SpillVNI immediately after its def, so clear out // any later spills of the same value. eliminateRedundantSpills(SibLI, SVI.SpillVNI); MachineBasicBlock *MBB = LIS.getMBBFromIndex(SVI.SpillVNI->def); MachineBasicBlock::iterator MII; if (SVI.SpillVNI->isPHIDef()) MII = MBB->SkipPHIsAndLabels(MBB->begin()); else { MachineInstr *DefMI = LIS.getInstructionFromIndex(SVI.SpillVNI->def); assert(DefMI && "Defining instruction disappeared"); MII = DefMI; ++MII; } // Insert spill without kill flag immediately after def. TII.storeRegToStackSlot(*MBB, MII, SVI.SpillReg, false, StackSlot, MRI.getRegClass(SVI.SpillReg), &TRI); --MII; // Point to store instruction. LIS.InsertMachineInstrInMaps(MII); DEBUG(dbgs() << "\thoisted: " << SVI.SpillVNI->def << '\t' << *MII); ++NumSpills; ++NumHoists; return true; }