17a7e6055SDimitry Andric //===- LiveIntervalUnion.cpp - Live interval union data structure ---------===//
22754fe60SDimitry Andric //
32754fe60SDimitry Andric //                     The LLVM Compiler Infrastructure
42754fe60SDimitry Andric //
52754fe60SDimitry Andric // This file is distributed under the University of Illinois Open Source
62754fe60SDimitry Andric // License. See LICENSE.TXT for details.
72754fe60SDimitry Andric //
82754fe60SDimitry Andric //===----------------------------------------------------------------------===//
92754fe60SDimitry Andric //
102754fe60SDimitry Andric // LiveIntervalUnion represents a coalesced set of live intervals. This may be
112754fe60SDimitry Andric // used during coalescing to represent a congruence class, or during register
122754fe60SDimitry Andric // allocation to model liveness of a physical register.
132754fe60SDimitry Andric //
142754fe60SDimitry Andric //===----------------------------------------------------------------------===//
152754fe60SDimitry Andric 
167a7e6055SDimitry Andric #include "llvm/CodeGen/LiveIntervalUnion.h"
17db17bf38SDimitry Andric #include "llvm/ADT/STLExtras.h"
18db17bf38SDimitry Andric #include "llvm/ADT/SparseBitVector.h"
19db17bf38SDimitry Andric #include "llvm/CodeGen/LiveInterval.h"
202cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
212754fe60SDimitry Andric #include "llvm/Support/raw_ostream.h"
227a7e6055SDimitry Andric #include <cassert>
237a7e6055SDimitry Andric #include <cstdlib>
24dff0c46cSDimitry Andric 
252754fe60SDimitry Andric using namespace llvm;
262754fe60SDimitry Andric 
2791bc56edSDimitry Andric #define DEBUG_TYPE "regalloc"
2891bc56edSDimitry Andric 
292754fe60SDimitry Andric // Merge a LiveInterval's segments. Guarantee no overlaps.
unify(LiveInterval & VirtReg,const LiveRange & Range)3039d628a0SDimitry Andric void LiveIntervalUnion::unify(LiveInterval &VirtReg, const LiveRange &Range) {
3139d628a0SDimitry Andric   if (Range.empty())
322754fe60SDimitry Andric     return;
332754fe60SDimitry Andric   ++Tag;
342754fe60SDimitry Andric 
352754fe60SDimitry Andric   // Insert each of the virtual register's live segments into the map.
3639d628a0SDimitry Andric   LiveRange::const_iterator RegPos = Range.begin();
3739d628a0SDimitry Andric   LiveRange::const_iterator RegEnd = Range.end();
382754fe60SDimitry Andric   SegmentIter SegPos = Segments.find(RegPos->start);
392754fe60SDimitry Andric 
403b0f4066SDimitry Andric   while (SegPos.valid()) {
412754fe60SDimitry Andric     SegPos.insert(RegPos->start, RegPos->end, &VirtReg);
422754fe60SDimitry Andric     if (++RegPos == RegEnd)
432754fe60SDimitry Andric       return;
442754fe60SDimitry Andric     SegPos.advanceTo(RegPos->start);
452754fe60SDimitry Andric   }
463b0f4066SDimitry Andric 
473b0f4066SDimitry Andric   // We have reached the end of Segments, so it is no longer necessary to search
483b0f4066SDimitry Andric   // for the insertion position.
493b0f4066SDimitry Andric   // It is faster to insert the end first.
503b0f4066SDimitry Andric   --RegEnd;
513b0f4066SDimitry Andric   SegPos.insert(RegEnd->start, RegEnd->end, &VirtReg);
523b0f4066SDimitry Andric   for (; RegPos != RegEnd; ++RegPos, ++SegPos)
533b0f4066SDimitry Andric     SegPos.insert(RegPos->start, RegPos->end, &VirtReg);
542754fe60SDimitry Andric }
552754fe60SDimitry Andric 
562754fe60SDimitry Andric // Remove a live virtual register's segments from this union.
extract(LiveInterval & VirtReg,const LiveRange & Range)5739d628a0SDimitry Andric void LiveIntervalUnion::extract(LiveInterval &VirtReg, const LiveRange &Range) {
5839d628a0SDimitry Andric   if (Range.empty())
592754fe60SDimitry Andric     return;
602754fe60SDimitry Andric   ++Tag;
612754fe60SDimitry Andric 
622754fe60SDimitry Andric   // Remove each of the virtual register's live segments from the map.
6339d628a0SDimitry Andric   LiveRange::const_iterator RegPos = Range.begin();
6439d628a0SDimitry Andric   LiveRange::const_iterator RegEnd = Range.end();
652754fe60SDimitry Andric   SegmentIter SegPos = Segments.find(RegPos->start);
662754fe60SDimitry Andric 
677a7e6055SDimitry Andric   while (true) {
682754fe60SDimitry Andric     assert(SegPos.value() == &VirtReg && "Inconsistent LiveInterval");
692754fe60SDimitry Andric     SegPos.erase();
702754fe60SDimitry Andric     if (!SegPos.valid())
712754fe60SDimitry Andric       return;
722754fe60SDimitry Andric 
732754fe60SDimitry Andric     // Skip all segments that may have been coalesced.
7439d628a0SDimitry Andric     RegPos = Range.advanceTo(RegPos, SegPos.start());
752754fe60SDimitry Andric     if (RegPos == RegEnd)
762754fe60SDimitry Andric       return;
772754fe60SDimitry Andric 
782754fe60SDimitry Andric     SegPos.advanceTo(RegPos->start);
792754fe60SDimitry Andric   }
802754fe60SDimitry Andric }
812754fe60SDimitry Andric 
822754fe60SDimitry Andric void
print(raw_ostream & OS,const TargetRegisterInfo * TRI) const832754fe60SDimitry Andric LiveIntervalUnion::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const {
842754fe60SDimitry Andric   if (empty()) {
852754fe60SDimitry Andric     OS << " empty\n";
862754fe60SDimitry Andric     return;
872754fe60SDimitry Andric   }
882754fe60SDimitry Andric   for (LiveSegments::const_iterator SI = Segments.begin(); SI.valid(); ++SI) {
892754fe60SDimitry Andric     OS << " [" << SI.start() << ' ' << SI.stop() << "):"
902cab237bSDimitry Andric        << printReg(SI.value()->reg, TRI);
912754fe60SDimitry Andric   }
922754fe60SDimitry Andric   OS << '\n';
932754fe60SDimitry Andric }
942754fe60SDimitry Andric 
952754fe60SDimitry Andric #ifndef NDEBUG
962754fe60SDimitry Andric // Verify the live intervals in this union and add them to the visited set.
verify(LiveVirtRegBitSet & VisitedVRegs)972754fe60SDimitry Andric void LiveIntervalUnion::verify(LiveVirtRegBitSet& VisitedVRegs) {
982754fe60SDimitry Andric   for (SegmentIter SI = Segments.begin(); SI.valid(); ++SI)
992754fe60SDimitry Andric     VisitedVRegs.set(SI.value()->reg);
1002754fe60SDimitry Andric }
1012754fe60SDimitry Andric #endif //!NDEBUG
1022754fe60SDimitry Andric 
1032754fe60SDimitry Andric // Scan the vector of interfering virtual registers in this union. Assume it's
1042754fe60SDimitry Andric // quite small.
isSeenInterference(LiveInterval * VirtReg) const1052754fe60SDimitry Andric bool LiveIntervalUnion::Query::isSeenInterference(LiveInterval *VirtReg) const {
106d88c1a5aSDimitry Andric   return is_contained(InterferingVRegs, VirtReg);
1072754fe60SDimitry Andric }
1082754fe60SDimitry Andric 
1096122f3e6SDimitry Andric // Collect virtual registers in this union that interfere with this
1102754fe60SDimitry Andric // query's live virtual register.
1112754fe60SDimitry Andric //
1126122f3e6SDimitry Andric // The query state is one of:
1132754fe60SDimitry Andric //
1146122f3e6SDimitry Andric // 1. CheckedFirstInterference == false: Iterators are uninitialized.
1156122f3e6SDimitry Andric // 2. SeenAllInterferences == true: InterferingVRegs complete, iterators unused.
1166122f3e6SDimitry Andric // 3. Iterators left at the last seen intersection.
1176122f3e6SDimitry Andric //
1182754fe60SDimitry Andric unsigned LiveIntervalUnion::Query::
collectInterferingVRegs(unsigned MaxInterferingRegs)11917a519f9SDimitry Andric collectInterferingVRegs(unsigned MaxInterferingRegs) {
1206122f3e6SDimitry Andric   // Fast path return if we already have the desired information.
1216122f3e6SDimitry Andric   if (SeenAllInterferences || InterferingVRegs.size() >= MaxInterferingRegs)
1226122f3e6SDimitry Andric     return InterferingVRegs.size();
1232754fe60SDimitry Andric 
1246122f3e6SDimitry Andric   // Set up iterators on the first call.
1256122f3e6SDimitry Andric   if (!CheckedFirstInterference) {
1266122f3e6SDimitry Andric     CheckedFirstInterference = true;
1272754fe60SDimitry Andric 
1286122f3e6SDimitry Andric     // Quickly skip interference check for empty sets.
1297a7e6055SDimitry Andric     if (LR->empty() || LiveUnion->empty()) {
1306122f3e6SDimitry Andric       SeenAllInterferences = true;
1316122f3e6SDimitry Andric       return 0;
1322754fe60SDimitry Andric     }
1336122f3e6SDimitry Andric 
1347a7e6055SDimitry Andric     // In most cases, the union will start before LR.
1357a7e6055SDimitry Andric     LRI = LR->begin();
1366122f3e6SDimitry Andric     LiveUnionI.setMap(LiveUnion->getMap());
1377a7e6055SDimitry Andric     LiveUnionI.find(LRI->start);
1386122f3e6SDimitry Andric   }
1396122f3e6SDimitry Andric 
1407a7e6055SDimitry Andric   LiveRange::const_iterator LREnd = LR->end();
14191bc56edSDimitry Andric   LiveInterval *RecentReg = nullptr;
1426122f3e6SDimitry Andric   while (LiveUnionI.valid()) {
1437a7e6055SDimitry Andric     assert(LRI != LREnd && "Reached end of LR");
1446122f3e6SDimitry Andric 
1456122f3e6SDimitry Andric     // Check for overlapping interference.
1467a7e6055SDimitry Andric     while (LRI->start < LiveUnionI.stop() && LRI->end > LiveUnionI.start()) {
1476122f3e6SDimitry Andric       // This is an overlap, record the interfering register.
1486122f3e6SDimitry Andric       LiveInterval *VReg = LiveUnionI.value();
1496122f3e6SDimitry Andric       if (VReg != RecentReg && !isSeenInterference(VReg)) {
1506122f3e6SDimitry Andric         RecentReg = VReg;
1516122f3e6SDimitry Andric         InterferingVRegs.push_back(VReg);
1526122f3e6SDimitry Andric         if (InterferingVRegs.size() >= MaxInterferingRegs)
1536122f3e6SDimitry Andric           return InterferingVRegs.size();
1546122f3e6SDimitry Andric       }
1556122f3e6SDimitry Andric       // This LiveUnion segment is no longer interesting.
1566122f3e6SDimitry Andric       if (!(++LiveUnionI).valid()) {
1576122f3e6SDimitry Andric         SeenAllInterferences = true;
1586122f3e6SDimitry Andric         return InterferingVRegs.size();
1596122f3e6SDimitry Andric       }
1606122f3e6SDimitry Andric     }
1616122f3e6SDimitry Andric 
1626122f3e6SDimitry Andric     // The iterators are now not overlapping, LiveUnionI has been advanced
1637a7e6055SDimitry Andric     // beyond LRI.
1647a7e6055SDimitry Andric     assert(LRI->end <= LiveUnionI.start() && "Expected non-overlap");
1656122f3e6SDimitry Andric 
1666122f3e6SDimitry Andric     // Advance the iterator that ends first.
1677a7e6055SDimitry Andric     LRI = LR->advanceTo(LRI, LiveUnionI.start());
1687a7e6055SDimitry Andric     if (LRI == LREnd)
1696122f3e6SDimitry Andric       break;
1706122f3e6SDimitry Andric 
1716122f3e6SDimitry Andric     // Detect overlap, handle above.
1727a7e6055SDimitry Andric     if (LRI->start < LiveUnionI.stop())
1736122f3e6SDimitry Andric       continue;
1746122f3e6SDimitry Andric 
1756122f3e6SDimitry Andric     // Still not overlapping. Catch up LiveUnionI.
1767a7e6055SDimitry Andric     LiveUnionI.advanceTo(LRI->start);
1772754fe60SDimitry Andric   }
1782754fe60SDimitry Andric   SeenAllInterferences = true;
1792754fe60SDimitry Andric   return InterferingVRegs.size();
1802754fe60SDimitry Andric }
1812754fe60SDimitry Andric 
init(LiveIntervalUnion::Allocator & Alloc,unsigned NSize)1827ae0e2c9SDimitry Andric void LiveIntervalUnion::Array::init(LiveIntervalUnion::Allocator &Alloc,
1837ae0e2c9SDimitry Andric                                     unsigned NSize) {
1847ae0e2c9SDimitry Andric   // Reuse existing allocation.
1857ae0e2c9SDimitry Andric   if (NSize == Size)
1867ae0e2c9SDimitry Andric     return;
1877ae0e2c9SDimitry Andric   clear();
1887ae0e2c9SDimitry Andric   Size = NSize;
1897ae0e2c9SDimitry Andric   LIUs = static_cast<LiveIntervalUnion*>(
190*4ba319b5SDimitry Andric       safe_malloc(sizeof(LiveIntervalUnion)*NSize));
1917ae0e2c9SDimitry Andric   for (unsigned i = 0; i != Size; ++i)
1927ae0e2c9SDimitry Andric     new(LIUs + i) LiveIntervalUnion(Alloc);
1937ae0e2c9SDimitry Andric }
1947ae0e2c9SDimitry Andric 
clear()1957ae0e2c9SDimitry Andric void LiveIntervalUnion::Array::clear() {
1967ae0e2c9SDimitry Andric   if (!LIUs)
1977ae0e2c9SDimitry Andric     return;
1987ae0e2c9SDimitry Andric   for (unsigned i = 0; i != Size; ++i)
1997ae0e2c9SDimitry Andric     LIUs[i].~LiveIntervalUnion();
2007ae0e2c9SDimitry Andric   free(LIUs);
2017ae0e2c9SDimitry Andric   Size =  0;
20291bc56edSDimitry Andric   LIUs = nullptr;
2037ae0e2c9SDimitry Andric }
204