/// shrinkToUses - After removing some uses of a register, shrink its live /// range to just the remaining uses. This method does not compute reaching /// defs for new uses, and it doesn't remove dead defs. bool LiveIntervals::shrinkToUses(LiveInterval *li, SmallVectorImpl<MachineInstr*> *dead) { DEBUG(dbgs() << "Shrink: " << *li << '\n'); assert(TargetRegisterInfo::isVirtualRegister(li->reg) && "Can only shrink virtual registers"); // Find all the values used, including PHI kills. SmallVector<std::pair<SlotIndex, VNInfo*>, 16> WorkList; // Blocks that have already been added to WorkList as live-out. SmallPtrSet<MachineBasicBlock*, 16> LiveOut; // Visit all instructions reading li->reg. for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(li->reg); MachineInstr *UseMI = I.skipInstruction();) { if (UseMI->isDebugValue() || !UseMI->readsVirtualRegister(li->reg)) continue; SlotIndex Idx = getInstructionIndex(UseMI).getRegSlot(); LiveRangeQuery LRQ(*li, Idx); VNInfo *VNI = LRQ.valueIn(); if (!VNI) { // This shouldn't happen: readsVirtualRegister returns true, but there is // no live value. It is likely caused by a target getting <undef> flags // wrong. DEBUG(dbgs() << Idx << '\t' << *UseMI << "Warning: Instr claims to read non-existent value in " << *li << '\n'); continue; } // Special case: An early-clobber tied operand reads and writes the // register one slot early. if (VNInfo *DefVNI = LRQ.valueDefined()) Idx = DefVNI->def; WorkList.push_back(std::make_pair(Idx, VNI)); } // Create a new live interval with only minimal live segments per def. LiveInterval NewLI(li->reg, 0); for (LiveInterval::vni_iterator I = li->vni_begin(), E = li->vni_end(); I != E; ++I) { VNInfo *VNI = *I; if (VNI->isUnused()) continue; NewLI.addRange(LiveRange(VNI->def, VNI->def.getDeadSlot(), VNI)); } // Keep track of the PHIs that are in use. SmallPtrSet<VNInfo*, 8> UsedPHIs; // Extend intervals to reach all uses in WorkList. while (!WorkList.empty()) { SlotIndex Idx = WorkList.back().first; VNInfo *VNI = WorkList.back().second; WorkList.pop_back(); const MachineBasicBlock *MBB = getMBBFromIndex(Idx.getPrevSlot()); SlotIndex BlockStart = getMBBStartIdx(MBB); // Extend the live range for VNI to be live at Idx. if (VNInfo *ExtVNI = NewLI.extendInBlock(BlockStart, Idx)) { (void)ExtVNI; assert(ExtVNI == VNI && "Unexpected existing value number"); // Is this a PHIDef we haven't seen before? if (!VNI->isPHIDef() || VNI->def != BlockStart || !UsedPHIs.insert(VNI)) continue; // The PHI is live, make sure the predecessors are live-out. for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PE = MBB->pred_end(); PI != PE; ++PI) { if (!LiveOut.insert(*PI)) continue; SlotIndex Stop = getMBBEndIdx(*PI); // A predecessor is not required to have a live-out value for a PHI. if (VNInfo *PVNI = li->getVNInfoBefore(Stop)) WorkList.push_back(std::make_pair(Stop, PVNI)); } continue; } // VNI is live-in to MBB. DEBUG(dbgs() << " live-in at " << BlockStart << '\n'); NewLI.addRange(LiveRange(BlockStart, Idx, VNI)); // Make sure VNI is live-out from the predecessors. for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PE = MBB->pred_end(); PI != PE; ++PI) { if (!LiveOut.insert(*PI)) continue; SlotIndex Stop = getMBBEndIdx(*PI); assert(li->getVNInfoBefore(Stop) == VNI && "Wrong value out of predecessor"); WorkList.push_back(std::make_pair(Stop, VNI)); } } // Handle dead values. bool CanSeparate = false; for (LiveInterval::vni_iterator I = li->vni_begin(), E = li->vni_end(); I != E; ++I) { VNInfo *VNI = *I; if (VNI->isUnused()) continue; LiveInterval::iterator LII = NewLI.FindLiveRangeContaining(VNI->def); assert(LII != NewLI.end() && "Missing live range for PHI"); if (LII->end != VNI->def.getDeadSlot()) continue; if (VNI->isPHIDef()) { // This is a dead PHI. Remove it. VNI->markUnused(); NewLI.removeRange(*LII); DEBUG(dbgs() << "Dead PHI at " << VNI->def << " may separate interval\n"); CanSeparate = true; } else { // This is a dead def. Make sure the instruction knows. MachineInstr *MI = getInstructionFromIndex(VNI->def); assert(MI && "No instruction defining live value"); MI->addRegisterDead(li->reg, TRI); if (dead && MI->allDefsAreDead()) { DEBUG(dbgs() << "All defs dead: " << VNI->def << '\t' << *MI); dead->push_back(MI); } } } // Move the trimmed ranges back. li->ranges.swap(NewLI.ranges); DEBUG(dbgs() << "Shrunk: " << *li << '\n'); return CanSeparate; }
/// Update the live interval information to reflect the removal of the given /// instruction from the program. As with "addInstrToLiveness", this function /// is called while the program code is being changed. void HexagonExpandCondsets::removeInstrFromLiveness(MachineInstr *MI) { SlotIndex MX = LIS->getInstructionIndex(*MI).getRegSlot(); DEBUG(dbgs() << "removing instr\n " << MX << " " << *MI); // For each def in MI: // If MI starts a live segment, merge this segment with the previous segment. // for (auto &Op : MI->operands()) { if (!Op.isReg() || !Op.isDef()) continue; unsigned DefR = Op.getReg(); LiveInterval &LID = LIS->getInterval(DefR); LiveInterval::iterator LT = LID.FindSegmentContaining(MX); assert(LT != LID.end() && "Expecting live segments"); DEBUG(dbgs() << "removing def at " << MX << " of " << PrintReg(DefR, TRI) << " with interval\n " << LID << "\n"); if (LT->start != MX) continue; VNInfo *MVN = LT->valno; if (LT != LID.begin()) { // If the current live segment is not the first, the task is easy. If // the previous segment continues into the current block, extend it to // the end of the current one, and merge the value numbers. // Otherwise, remove the current segment, and make the end of it "undef". LiveInterval::iterator P = std::prev(LT); SlotIndex PE = P->end.isBlock() ? P->end.getPrevIndex() : P->end; MachineBasicBlock *MB = MI->getParent(); MachineBasicBlock *PB = LIS->getMBBFromIndex(PE); if (PB != MB && !LIS->isLiveInToMBB(LID, MB)) { makeDefined(DefR, LT->end, false); LID.removeSegment(*LT); } else { // Make the segments adjacent, so that merge-vn can also merge the // segments. P->end = LT->start; makeUndead(DefR, P->valno->def); LID.MergeValueNumberInto(MVN, P->valno); } } else { LiveInterval::iterator N = std::next(LT); LiveInterval::iterator RmB = LT, RmE = N; while (N != LID.end()) { // Iterate until the first register-based definition is found // (i.e. skip all block-boundary entries). LiveInterval::iterator Next = std::next(N); if (N->start.isRegister()) { makeDefined(DefR, N->start, false); break; } if (N->end.isRegister()) { makeDefined(DefR, N->end, false); RmE = Next; break; } RmE = Next; N = Next; } // Erase the segments in one shot to avoid invalidating iterators. LID.segments.erase(RmB, RmE); } bool VNUsed = false; for (LiveInterval::iterator I = LID.begin(), E = LID.end(); I != E; ++I) { if (I->valno != MVN) continue; VNUsed = true; break; } if (!VNUsed) MVN->markUnused(); DEBUG(dbgs() << "new interval: "); if (!LID.empty()) { DEBUG(dbgs() << LID << "\n"); LID.verify(); } else { DEBUG(dbgs() << "<empty>\n"); LIS->removeInterval(DefR); } } // For uses there is nothing to do. The intervals will be updated via // shrinkToUses. SmallVector<unsigned,4> Uses; for (auto &Op : MI->operands()) { if (!Op.isReg() || !Op.isUse()) continue; unsigned R = Op.getReg(); if (!TargetRegisterInfo::isVirtualRegister(R)) continue; Uses.push_back(R); } LIS->RemoveMachineInstrFromMaps(*MI); MI->eraseFromParent(); for (unsigned i = 0, n = Uses.size(); i < n; ++i) { LiveInterval &LI = LIS->getInterval(Uses[i]); shrinkToUses(Uses[i], LI); } }