/// Shrink the segments in the live interval for a given register to the last /// use before each subsequent def. Unlike LiveIntervals::shrinkToUses, this /// function will not mark any definitions of Reg as dead. The reason for this /// is that this function is used while a MUX instruction is being expanded, /// or while a conditional copy is undergoing predication. During these /// processes, there may be defs present in the instruction sequence that have /// not yet been removed, or there may be missing uses that have not yet been /// added. We want to utilize LiveIntervals::shrinkToUses as much as possible, /// but since it does not extend any intervals that are too short, we need to /// pre-emptively extend them here in anticipation of further changes. void HexagonExpandCondsets::shrinkToUses(unsigned Reg, LiveInterval &LI) { SmallVector<MachineInstr*,4> Deads; LIS->shrinkToUses(&LI, &Deads); // Need to undo the deadification made by "shrinkToUses". It's easier to // do it here, since we have a list of all instructions that were just // marked as dead. for (unsigned i = 0, n = Deads.size(); i < n; ++i) { MachineInstr *MI = Deads[i]; // Clear the "dead" flag. for (auto &Op : MI->operands()) { if (!Op.isReg() || !Op.isDef() || Op.getReg() != Reg) continue; Op.setIsDead(false); } // Extend the live segment to the beginning of the next one. LiveInterval::iterator End = LI.end(); SlotIndex S = LIS->getInstructionIndex(*MI).getRegSlot(); LiveInterval::iterator T = LI.FindSegmentContaining(S); assert(T != End); LiveInterval::iterator N = std::next(T); if (N != End) T->end = N->start; else T->end = LIS->getMBBEndIdx(MI->getParent()); } updateKillFlags(Reg, LI); }
bool LiveIntervals::computeDeadValues(LiveInterval &LI, SmallVectorImpl<MachineInstr*> *dead) { bool PHIRemoved = false; for (auto VNI : LI.valnos) { if (VNI->isUnused()) continue; SlotIndex Def = VNI->def; LiveRange::iterator I = LI.FindSegmentContaining(Def); assert(I != LI.end() && "Missing segment for VNI"); // Is the register live before? Otherwise we may have to add a read-undef // flag for subregister defs. if (MRI->tracksSubRegLiveness()) { if ((I == LI.begin() || std::prev(I)->end < Def) && !VNI->isPHIDef()) { MachineInstr *MI = getInstructionFromIndex(Def); MI->addRegisterDefReadUndef(LI.reg); } } if (I->end != Def.getDeadSlot()) continue; if (VNI->isPHIDef()) { // This is a dead PHI. Remove it. VNI->markUnused(); LI.removeSegment(I); DEBUG(dbgs() << "Dead PHI at " << Def << " may separate interval\n"); PHIRemoved = true; } else { // This is a dead def. Make sure the instruction knows. MachineInstr *MI = getInstructionFromIndex(Def); assert(MI && "No instruction defining live value"); MI->addRegisterDead(LI.reg, TRI); if (dead && MI->allDefsAreDead()) { DEBUG(dbgs() << "All defs dead: " << Def << '\t' << *MI); dead->push_back(MI); } } } return PHIRemoved; }