void ConnectedVNInfoEqClasses::Distribute(LiveInterval &LI, LiveInterval *LIV[], MachineRegisterInfo &MRI) { // Rewrite instructions. for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(LI.reg), RE = MRI.reg_end(); RI != RE;) { MachineOperand &MO = *RI; MachineInstr *MI = RI->getParent(); ++RI; // DBG_VALUE instructions don't have slot indexes, so get the index of the // instruction before them. // Normally, DBG_VALUE instructions are removed before this function is // called, but it is not a requirement. SlotIndex Idx; if (MI->isDebugValue()) Idx = LIS.getSlotIndexes()->getIndexBefore(MI); else Idx = LIS.getInstructionIndex(MI); LiveQueryResult LRQ = LI.Query(Idx); const VNInfo *VNI = MO.readsReg() ? LRQ.valueIn() : LRQ.valueDefined(); // In the case of an <undef> use that isn't tied to any def, VNI will be // NULL. If the use is tied to a def, VNI will be the defined value. if (!VNI) continue; if (unsigned EqClass = getEqClass(VNI)) MO.setReg(LIV[EqClass-1]->reg); } // Move runs to new intervals. LiveInterval::iterator J = LI.begin(), E = LI.end(); while (J != E && EqClass[J->valno->id] == 0) ++J; for (LiveInterval::iterator I = J; I != E; ++I) { if (unsigned eq = EqClass[I->valno->id]) { assert((LIV[eq-1]->empty() || LIV[eq-1]->expiredAt(I->start)) && "New intervals should be empty"); LIV[eq-1]->segments.push_back(*I); } else *J++ = *I; } // TODO: do not cheat anymore by simply cleaning all subranges LI.clearSubRanges(); LI.segments.erase(J, E); // Transfer VNInfos to their new owners and renumber them. unsigned j = 0, e = LI.getNumValNums(); while (j != e && EqClass[j] == 0) ++j; for (unsigned i = j; i != e; ++i) { VNInfo *VNI = LI.getValNumInfo(i); if (unsigned eq = EqClass[i]) { VNI->id = LIV[eq-1]->getNumValNums(); LIV[eq-1]->valnos.push_back(VNI); } else { VNI->id = j; LI.valnos[j++] = VNI; } } LI.valnos.resize(j); }
void ConnectedVNInfoEqClasses::Distribute(LiveInterval &LI, LiveInterval *LIV[], MachineRegisterInfo &MRI) { // Rewrite instructions. for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(LI.reg), RE = MRI.reg_end(); RI != RE;) { MachineOperand &MO = *RI; MachineInstr *MI = RI->getParent(); ++RI; // DBG_VALUE instructions don't have slot indexes, so get the index of the // instruction before them. // Normally, DBG_VALUE instructions are removed before this function is // called, but it is not a requirement. SlotIndex Idx; if (MI->isDebugValue()) Idx = LIS.getSlotIndexes()->getIndexBefore(*MI); else Idx = LIS.getInstructionIndex(*MI); LiveQueryResult LRQ = LI.Query(Idx); const VNInfo *VNI = MO.readsReg() ? LRQ.valueIn() : LRQ.valueDefined(); // In the case of an <undef> use that isn't tied to any def, VNI will be // NULL. If the use is tied to a def, VNI will be the defined value. if (!VNI) continue; if (unsigned EqClass = getEqClass(VNI)) MO.setReg(LIV[EqClass-1]->reg); } // Distribute subregister liveranges. if (LI.hasSubRanges()) { unsigned NumComponents = EqClass.getNumClasses(); SmallVector<unsigned, 8> VNIMapping; SmallVector<LiveInterval::SubRange*, 8> SubRanges; BumpPtrAllocator &Allocator = LIS.getVNInfoAllocator(); for (LiveInterval::SubRange &SR : LI.subranges()) { // Create new subranges in the split intervals and construct a mapping // for the VNInfos in the subrange. unsigned NumValNos = SR.valnos.size(); VNIMapping.clear(); VNIMapping.reserve(NumValNos); SubRanges.clear(); SubRanges.resize(NumComponents-1, nullptr); for (unsigned I = 0; I < NumValNos; ++I) { const VNInfo &VNI = *SR.valnos[I]; unsigned ComponentNum; if (VNI.isUnused()) { ComponentNum = 0; } else { const VNInfo *MainRangeVNI = LI.getVNInfoAt(VNI.def); assert(MainRangeVNI != nullptr && "SubRange def must have corresponding main range def"); ComponentNum = getEqClass(MainRangeVNI); if (ComponentNum > 0 && SubRanges[ComponentNum-1] == nullptr) { SubRanges[ComponentNum-1] = LIV[ComponentNum-1]->createSubRange(Allocator, SR.LaneMask); } } VNIMapping.push_back(ComponentNum); } DistributeRange(SR, SubRanges.data(), VNIMapping); } LI.removeEmptySubRanges(); } // Distribute main liverange. DistributeRange(LI, LIV, EqClass); }