void LiveIntervals::addKillFlags(const VirtRegMap *VRM) { // Keep track of regunit ranges. SmallVector<std::pair<const LiveRange*, LiveRange::const_iterator>, 8> RU; // Keep track of subregister ranges. SmallVector<std::pair<const LiveInterval::SubRange*, LiveRange::const_iterator>, 4> SRs; for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) { unsigned Reg = TargetRegisterInfo::index2VirtReg(i); if (MRI->reg_nodbg_empty(Reg)) continue; const LiveInterval &LI = getInterval(Reg); if (LI.empty()) continue; // Find the regunit intervals for the assigned register. They may overlap // the virtual register live range, cancelling any kills. RU.clear(); for (MCRegUnitIterator Units(VRM->getPhys(Reg), TRI); Units.isValid(); ++Units) { const LiveRange &RURange = getRegUnit(*Units); if (RURange.empty()) continue; RU.push_back(std::make_pair(&RURange, RURange.find(LI.begin()->end))); } if (MRI->tracksSubRegLiveness()) { SRs.clear(); for (const LiveInterval::SubRange &SR : LI.subranges()) { SRs.push_back(std::make_pair(&SR, SR.find(LI.begin()->end))); } } // Every instruction that kills Reg corresponds to a segment range end // point. for (LiveInterval::const_iterator RI = LI.begin(), RE = LI.end(); RI != RE; ++RI) { // A block index indicates an MBB edge. if (RI->end.isBlock()) continue; MachineInstr *MI = getInstructionFromIndex(RI->end); if (!MI) continue; // Check if any of the regunits are live beyond the end of RI. That could // happen when a physreg is defined as a copy of a virtreg: // // %EAX = COPY %vreg5 // FOO %vreg5 <--- MI, cancel kill because %EAX is live. // BAR %EAX<kill> // // There should be no kill flag on FOO when %vreg5 is rewritten as %EAX. for (auto &RUP : RU) { const LiveRange &RURange = *RUP.first; LiveRange::const_iterator &I = RUP.second; if (I == RURange.end()) continue; I = RURange.advanceTo(I, RI->end); if (I == RURange.end() || I->start >= RI->end) continue; // I is overlapping RI. goto CancelKill; } if (MRI->tracksSubRegLiveness()) { // When reading a partial undefined value we must not add a kill flag. // The regalloc might have used the undef lane for something else. // Example: // %vreg1 = ... ; R32: %vreg1 // %vreg2:high16 = ... ; R64: %vreg2 // = read %vreg2<kill> ; R64: %vreg2 // = read %vreg1 ; R32: %vreg1 // The <kill> flag is correct for %vreg2, but the register allocator may // assign R0L to %vreg1, and R0 to %vreg2 because the low 32bits of R0 // are actually never written by %vreg2. After assignment the <kill> // flag at the read instruction is invalid. unsigned DefinedLanesMask; if (!SRs.empty()) { // Compute a mask of lanes that are defined. DefinedLanesMask = 0; for (auto &SRP : SRs) { const LiveInterval::SubRange &SR = *SRP.first; LiveRange::const_iterator &I = SRP.second; if (I == SR.end()) continue; I = SR.advanceTo(I, RI->end); if (I == SR.end() || I->start >= RI->end) continue; // I is overlapping RI DefinedLanesMask |= SR.LaneMask; } } else DefinedLanesMask = ~0u; bool IsFullWrite = false; for (const MachineOperand &MO : MI->operands()) { if (!MO.isReg() || MO.getReg() != Reg) continue; if (MO.isUse()) { // Reading any undefined lanes? unsigned UseMask = TRI->getSubRegIndexLaneMask(MO.getSubReg()); if ((UseMask & ~DefinedLanesMask) != 0) goto CancelKill; } else if (MO.getSubReg() == 0) { // Writing to the full register? assert(MO.isDef()); IsFullWrite = true; } } // If an instruction writes to a subregister, a new segment starts in // the LiveInterval. But as this is only overriding part of the register // adding kill-flags is not correct here after registers have been // assigned. if (!IsFullWrite) { // Next segment has to be adjacent in the subregister write case. LiveRange::const_iterator N = std::next(RI); if (N != LI.end() && N->start == RI->end) goto CancelKill; } } MI->addRegisterKilled(Reg, nullptr); continue; CancelKill: MI->clearRegisterKills(Reg, nullptr); } } }
void LiveIntervals::addKillFlags(const VirtRegMap *VRM) { // Keep track of regunit ranges. SmallVector<std::pair<LiveInterval*, LiveInterval::iterator>, 8> RU; for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) { unsigned Reg = TargetRegisterInfo::index2VirtReg(i); if (MRI->reg_nodbg_empty(Reg)) continue; LiveInterval *LI = &getInterval(Reg); if (LI->empty()) continue; // Find the regunit intervals for the assigned register. They may overlap // the virtual register live range, cancelling any kills. RU.clear(); for (MCRegUnitIterator Units(VRM->getPhys(Reg), TRI); Units.isValid(); ++Units) { LiveInterval *RUInt = &getRegUnit(*Units); if (RUInt->empty()) continue; RU.push_back(std::make_pair(RUInt, RUInt->find(LI->begin()->end))); } // Every instruction that kills Reg corresponds to a live range end point. for (LiveInterval::iterator RI = LI->begin(), RE = LI->end(); RI != RE; ++RI) { // A block index indicates an MBB edge. if (RI->end.isBlock()) continue; MachineInstr *MI = getInstructionFromIndex(RI->end); if (!MI) continue; // Check if any of the regunits are live beyond the end of RI. That could // happen when a physreg is defined as a copy of a virtreg: // // %EAX = COPY %vreg5 // FOO %vreg5 <--- MI, cancel kill because %EAX is live. // BAR %EAX<kill> // // There should be no kill flag on FOO when %vreg5 is rewritten as %EAX. bool CancelKill = false; for (unsigned u = 0, e = RU.size(); u != e; ++u) { LiveInterval *RInt = RU[u].first; LiveInterval::iterator &I = RU[u].second; if (I == RInt->end()) continue; I = RInt->advanceTo(I, RI->end); if (I == RInt->end() || I->start >= RI->end) continue; // I is overlapping RI. CancelKill = true; break; } if (CancelKill) MI->clearRegisterKills(Reg, NULL); else MI->addRegisterKilled(Reg, NULL); } } }