Index: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -258,11 +258,6 @@ Indexes->replaceMachineInstrInMaps(MI, NewMI); } - bool findLiveInMBBs(SlotIndex Start, SlotIndex End, - SmallVectorImpl &MBBs) const { - return Indexes->findLiveInMBBs(Start, End, MBBs); - } - VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; } void getAnalysisUsage(AnalysisUsage &AU) const override; Index: llvm/trunk/include/llvm/CodeGen/SlotIndexes.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/SlotIndexes.h +++ llvm/trunk/include/llvm/CodeGen/SlotIndexes.h @@ -541,17 +541,6 @@ return J->second; } - bool findLiveInMBBs(SlotIndex start, SlotIndex end, - SmallVectorImpl &mbbs) const { - bool resVal = false; - for (MBBIndexIterator itr = findMBBIndex(start); - itr != MBBIndexEnd() && itr->first < end; ++itr) { - mbbs.push_back(itr->second); - resVal = true; - } - return resVal; - } - /// Returns the MBB covering the given range, or null if the range covers /// more than one basic block. MachineBasicBlock* getMBBCoveringRange(SlotIndex start, SlotIndex end) const { Index: llvm/trunk/lib/CodeGen/VirtRegMap.cpp =================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp @@ -167,6 +167,8 @@ void rewrite(); void addMBBLiveIns(); bool readsUndefSubreg(const MachineOperand &MO) const; + void addLiveInsForSubRanges(const LiveInterval &LI, unsigned PhysReg) const; + public: static char ID; VirtRegRewriter() : MachineFunctionPass(ID) {} @@ -236,10 +238,58 @@ return true; } +void VirtRegRewriter::addLiveInsForSubRanges(const LiveInterval &LI, + unsigned PhysReg) const { + assert(!LI.empty()); + assert(LI.hasSubRanges()); + + typedef std::pair SubRangeIteratorPair; + SmallVector SubRanges; + SlotIndex First; + SlotIndex Last; + for (const LiveInterval::SubRange &SR : LI.subranges()) { + SubRanges.push_back(std::make_pair(&SR, SR.begin())); + if (!First.isValid() || SR.segments.front().start < First) + First = SR.segments.front().start; + if (!Last.isValid() || SR.segments.back().end > Last) + Last = SR.segments.back().end; + } + + // Check all mbb start positions between First and Last while + // simulatenously advancing an iterator for each subrange. + for (SlotIndexes::MBBIndexIterator MBBI = Indexes->findMBBIndex(First); + MBBI != Indexes->MBBIndexEnd() && MBBI->first <= Last; ++MBBI) { + SlotIndex MBBBegin = MBBI->first; + // Advance all subrange iterators so that their end position is just + // behind MBBBegin (or the iterator is at the end). + unsigned LaneMask = 0; + for (auto &RangeIterPair : SubRanges) { + const LiveInterval::SubRange *SR = RangeIterPair.first; + LiveInterval::const_iterator &SRI = RangeIterPair.second; + while (SRI != SR->end() && SRI->end <= MBBBegin) + ++SRI; + if (SRI == SR->end()) + continue; + if (SRI->start <= MBBBegin) + LaneMask |= SR->LaneMask; + } + if (LaneMask == 0) + continue; + MachineBasicBlock *MBB = MBBI->second; + for (MCSubRegIndexIterator SR(PhysReg, TRI); SR.isValid(); ++SR) { + unsigned SubReg = SR.getSubReg(); + unsigned SubRegIndex = SR.getSubRegIndex(); + unsigned SubRegLaneMask = TRI->getSubRegIndexLaneMask(SubRegIndex); + if ((SubRegLaneMask & LaneMask) != 0) + MBB->addLiveIn(SubReg); + } + } +} + // Compute MBB live-in lists from virtual register live ranges and their // assignments. void VirtRegRewriter::addMBBLiveIns() { - SmallVector LiveIn; for (unsigned Idx = 0, IdxE = MRI->getNumVirtRegs(); Idx != IdxE; ++Idx) { unsigned VirtReg = TargetRegisterInfo::index2VirtReg(Idx); if (MRI->reg_nodbg_empty(VirtReg)) @@ -253,31 +303,18 @@ assert(PhysReg != VirtRegMap::NO_PHYS_REG && "Unmapped virtual register."); if (LI.hasSubRanges()) { - for (LiveInterval::SubRange &S : LI.subranges()) { - for (const auto &Seg : S.segments) { - if (!Indexes->findLiveInMBBs(Seg.start, Seg.end, LiveIn)) - continue; - for (MCSubRegIndexIterator SR(PhysReg, TRI); SR.isValid(); ++SR) { - unsigned SubReg = SR.getSubReg(); - unsigned SubRegIndex = SR.getSubRegIndex(); - unsigned SubRegLaneMask = TRI->getSubRegIndexLaneMask(SubRegIndex); - if ((SubRegLaneMask & S.LaneMask) == 0) - continue; - for (unsigned i = 0, e = LiveIn.size(); i != e; ++i) { - LiveIn[i]->addLiveIn(SubReg); - } - } - LiveIn.clear(); - } - } + addLiveInsForSubRanges(LI, PhysReg); } else { - // Scan the segments of LI. - for (const auto &Seg : LI.segments) { - if (!Indexes->findLiveInMBBs(Seg.start, Seg.end, LiveIn)) - continue; - for (unsigned i = 0, e = LiveIn.size(); i != e; ++i) - LiveIn[i]->addLiveIn(PhysReg); - LiveIn.clear(); + // Go over MBB begin positions and see if we have segments covering them. + // The following works because segments and the MBBIndex list are both + // sorted by slot indexes. + SlotIndexes::MBBIndexIterator I = Indexes->MBBIndexBegin(); + for (const auto &Seg : LI) { + I = Indexes->advanceMBBIndex(I, Seg.start); + for (; I != Indexes->MBBIndexEnd() && I->first < Seg.end; ++I) { + MachineBasicBlock *MBB = I->second; + MBB->addLiveIn(PhysReg); + } } } }