blob: 43fa8f2d7157a7ee1da3929c2357b9c2e1118dbb [file] [log] [blame]
Eugene Zelenko5db84df2017-02-17 21:43:25 +00001//===- LiveIntervalUnion.cpp - Live interval union data structure ---------===//
Andrew Trick1c246052010-10-22 23:09:15 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Andrew Trick1c246052010-10-22 23:09:15 +00006//
7//===----------------------------------------------------------------------===//
8//
9// LiveIntervalUnion represents a coalesced set of live intervals. This may be
10// used during coalescing to represent a congruence class, or during register
11// allocation to model liveness of a physical register.
12//
13//===----------------------------------------------------------------------===//
14
Eugene Zelenko5db84df2017-02-17 21:43:25 +000015#include "llvm/CodeGen/LiveIntervalUnion.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000016#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/SparseBitVector.h"
18#include "llvm/CodeGen/LiveInterval.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000019#include "llvm/CodeGen/TargetRegisterInfo.h"
Andrew Trick1c246052010-10-22 23:09:15 +000020#include "llvm/Support/raw_ostream.h"
Eugene Zelenko5db84df2017-02-17 21:43:25 +000021#include <cassert>
22#include <cstdlib>
Lang Hamese49fbd02011-12-21 20:16:11 +000023
Andrew Trick1c246052010-10-22 23:09:15 +000024using namespace llvm;
25
Chandler Carruth1b9dde02014-04-22 02:02:50 +000026#define DEBUG_TYPE "regalloc"
27
Andrew Trick1c246052010-10-22 23:09:15 +000028// Merge a LiveInterval's segments. Guarantee no overlaps.
Matthias Brauna0f0c1f2014-12-10 01:12:59 +000029void LiveIntervalUnion::unify(LiveInterval &VirtReg, const LiveRange &Range) {
30 if (Range.empty())
Jakob Stoklund Olesendb357d72010-12-07 23:18:47 +000031 return;
Jakob Stoklund Olesen8f59b462011-02-09 21:52:03 +000032 ++Tag;
Andrew Trickfce64c92010-11-30 23:18:47 +000033
34 // Insert each of the virtual register's live segments into the map.
Matthias Brauna0f0c1f2014-12-10 01:12:59 +000035 LiveRange::const_iterator RegPos = Range.begin();
36 LiveRange::const_iterator RegEnd = Range.end();
Jakob Stoklund Olesendb357d72010-12-07 23:18:47 +000037 SegmentIter SegPos = Segments.find(RegPos->start);
Andrew Trickfce64c92010-11-30 23:18:47 +000038
Jakob Stoklund Olesen4fbbe362011-04-11 15:00:44 +000039 while (SegPos.valid()) {
Jakob Stoklund Olesendb357d72010-12-07 23:18:47 +000040 SegPos.insert(RegPos->start, RegPos->end, &VirtReg);
41 if (++RegPos == RegEnd)
42 return;
43 SegPos.advanceTo(RegPos->start);
Andrew Trick1c246052010-10-22 23:09:15 +000044 }
Jakob Stoklund Olesen4fbbe362011-04-11 15:00:44 +000045
46 // We have reached the end of Segments, so it is no longer necessary to search
47 // for the insertion position.
48 // It is faster to insert the end first.
49 --RegEnd;
50 SegPos.insert(RegEnd->start, RegEnd->end, &VirtReg);
51 for (; RegPos != RegEnd; ++RegPos, ++SegPos)
52 SegPos.insert(RegPos->start, RegPos->end, &VirtReg);
Andrew Trick1c246052010-10-22 23:09:15 +000053}
54
Andrew Trick35284652010-11-08 18:02:08 +000055// Remove a live virtual register's segments from this union.
Matthias Brauna0f0c1f2014-12-10 01:12:59 +000056void LiveIntervalUnion::extract(LiveInterval &VirtReg, const LiveRange &Range) {
57 if (Range.empty())
Jakob Stoklund Olesendb357d72010-12-07 23:18:47 +000058 return;
Jakob Stoklund Olesen8f59b462011-02-09 21:52:03 +000059 ++Tag;
Andrew Trickfce64c92010-11-30 23:18:47 +000060
Andrew Trick35284652010-11-08 18:02:08 +000061 // Remove each of the virtual register's live segments from the map.
Matthias Brauna0f0c1f2014-12-10 01:12:59 +000062 LiveRange::const_iterator RegPos = Range.begin();
63 LiveRange::const_iterator RegEnd = Range.end();
Jakob Stoklund Olesendb357d72010-12-07 23:18:47 +000064 SegmentIter SegPos = Segments.find(RegPos->start);
Andrew Trickfce64c92010-11-30 23:18:47 +000065
Eugene Zelenko5db84df2017-02-17 21:43:25 +000066 while (true) {
Jakob Stoklund Olesendb357d72010-12-07 23:18:47 +000067 assert(SegPos.value() == &VirtReg && "Inconsistent LiveInterval");
68 SegPos.erase();
69 if (!SegPos.valid())
70 return;
Andrew Trickfce64c92010-11-30 23:18:47 +000071
Jakob Stoklund Olesendb357d72010-12-07 23:18:47 +000072 // Skip all segments that may have been coalesced.
Matthias Brauna0f0c1f2014-12-10 01:12:59 +000073 RegPos = Range.advanceTo(RegPos, SegPos.start());
Jakob Stoklund Olesendb357d72010-12-07 23:18:47 +000074 if (RegPos == RegEnd)
75 return;
76
77 SegPos.advanceTo(RegPos->start);
Andrew Trick1c246052010-10-22 23:09:15 +000078 }
Andrew Trick1c246052010-10-22 23:09:15 +000079}
Andrew Trick1c246052010-10-22 23:09:15 +000080
Andrew Trick48866052010-11-09 21:04:34 +000081void
Jakob Stoklund Olesend5e38382010-12-14 18:53:47 +000082LiveIntervalUnion::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const {
Jakob Stoklund Olesen5c3ad0d2010-12-14 19:38:49 +000083 if (empty()) {
84 OS << " empty\n";
85 return;
86 }
Jakob Stoklund Olesend5e38382010-12-14 18:53:47 +000087 for (LiveSegments::const_iterator SI = Segments.begin(); SI.valid(); ++SI) {
Jakob Stoklund Olesen1331a152011-01-09 03:05:53 +000088 OS << " [" << SI.start() << ' ' << SI.stop() << "):"
Francis Visoiu Mistrih9d419d32017-11-28 12:42:37 +000089 << printReg(SI.value()->reg, TRI);
Andrew Trick48866052010-11-09 21:04:34 +000090 }
Jakob Stoklund Olesen5c3ad0d2010-12-14 19:38:49 +000091 OS << '\n';
92}
93
Andrew Trick48866052010-11-09 21:04:34 +000094#ifndef NDEBUG
95// Verify the live intervals in this union and add them to the visited set.
Andrew Trickfce64c92010-11-30 23:18:47 +000096void LiveIntervalUnion::verify(LiveVirtRegBitSet& VisitedVRegs) {
Jakob Stoklund Olesendb357d72010-12-07 23:18:47 +000097 for (SegmentIter SI = Segments.begin(); SI.valid(); ++SI)
98 VisitedVRegs.set(SI.value()->reg);
Andrew Trick48866052010-11-09 21:04:34 +000099}
100#endif //!NDEBUG
101
Andrew Trickfce64c92010-11-30 23:18:47 +0000102// Scan the vector of interfering virtual registers in this union. Assume it's
Andrew Trick89eb6a82010-11-10 19:18:47 +0000103// quite small.
Andrew Trickfce64c92010-11-30 23:18:47 +0000104bool LiveIntervalUnion::Query::isSeenInterference(LiveInterval *VirtReg) const {
David Majnemer0d955d02016-08-11 22:21:41 +0000105 return is_contained(InterferingVRegs, VirtReg);
Andrew Trick89eb6a82010-11-10 19:18:47 +0000106}
107
Jakob Stoklund Olesen1f582ba2011-08-12 00:22:04 +0000108// Collect virtual registers in this union that interfere with this
Andrew Trickfce64c92010-11-30 23:18:47 +0000109// query's live virtual register.
110//
Jakob Stoklund Olesen1f582ba2011-08-12 00:22:04 +0000111// The query state is one of:
Andrew Trick89eb6a82010-11-10 19:18:47 +0000112//
Jakob Stoklund Olesen1f582ba2011-08-12 00:22:04 +0000113// 1. CheckedFirstInterference == false: Iterators are uninitialized.
114// 2. SeenAllInterferences == true: InterferingVRegs complete, iterators unused.
115// 3. Iterators left at the last seen intersection.
116//
Andrew Trick89eb6a82010-11-10 19:18:47 +0000117unsigned LiveIntervalUnion::Query::
Jakob Stoklund Olesen4931bbc2011-07-08 20:46:18 +0000118collectInterferingVRegs(unsigned MaxInterferingRegs) {
Jakob Stoklund Olesencd14efa2011-08-11 22:46:04 +0000119 // Fast path return if we already have the desired information.
120 if (SeenAllInterferences || InterferingVRegs.size() >= MaxInterferingRegs)
Jakob Stoklund Olesenda4f0eb2011-08-11 21:18:34 +0000121 return InterferingVRegs.size();
Jakob Stoklund Olesencd14efa2011-08-11 22:46:04 +0000122
123 // Set up iterators on the first call.
124 if (!CheckedFirstInterference) {
125 CheckedFirstInterference = true;
Jakob Stoklund Olesencd14efa2011-08-11 22:46:04 +0000126
127 // Quickly skip interference check for empty sets.
Matthias Braun173e1142017-03-01 21:48:12 +0000128 if (LR->empty() || LiveUnion->empty()) {
Jakob Stoklund Olesen1f582ba2011-08-12 00:22:04 +0000129 SeenAllInterferences = true;
130 return 0;
Jakob Stoklund Olesencd14efa2011-08-11 22:46:04 +0000131 }
Jakob Stoklund Olesen1f582ba2011-08-12 00:22:04 +0000132
Matthias Braun173e1142017-03-01 21:48:12 +0000133 // In most cases, the union will start before LR.
134 LRI = LR->begin();
Jakob Stoklund Olesen1f582ba2011-08-12 00:22:04 +0000135 LiveUnionI.setMap(LiveUnion->getMap());
Matthias Braun173e1142017-03-01 21:48:12 +0000136 LiveUnionI.find(LRI->start);
Jakob Stoklund Olesencd14efa2011-08-11 22:46:04 +0000137 }
138
Matthias Braun173e1142017-03-01 21:48:12 +0000139 LiveRange::const_iterator LREnd = LR->end();
Craig Topperc0196b12014-04-14 00:51:57 +0000140 LiveInterval *RecentReg = nullptr;
Jakob Stoklund Olesen1f582ba2011-08-12 00:22:04 +0000141 while (LiveUnionI.valid()) {
Matthias Braun173e1142017-03-01 21:48:12 +0000142 assert(LRI != LREnd && "Reached end of LR");
Andrew Trick89eb6a82010-11-10 19:18:47 +0000143
Jakob Stoklund Olesen1f582ba2011-08-12 00:22:04 +0000144 // Check for overlapping interference.
Matthias Braun173e1142017-03-01 21:48:12 +0000145 while (LRI->start < LiveUnionI.stop() && LRI->end > LiveUnionI.start()) {
Jakob Stoklund Olesen1f582ba2011-08-12 00:22:04 +0000146 // This is an overlap, record the interfering register.
147 LiveInterval *VReg = LiveUnionI.value();
148 if (VReg != RecentReg && !isSeenInterference(VReg)) {
149 RecentReg = VReg;
150 InterferingVRegs.push_back(VReg);
151 if (InterferingVRegs.size() >= MaxInterferingRegs)
152 return InterferingVRegs.size();
153 }
154 // This LiveUnion segment is no longer interesting.
155 if (!(++LiveUnionI).valid()) {
156 SeenAllInterferences = true;
157 return InterferingVRegs.size();
158 }
159 }
Andrew Trick89eb6a82010-11-10 19:18:47 +0000160
Jakob Stoklund Olesen1f582ba2011-08-12 00:22:04 +0000161 // The iterators are now not overlapping, LiveUnionI has been advanced
Matthias Braun173e1142017-03-01 21:48:12 +0000162 // beyond LRI.
163 assert(LRI->end <= LiveUnionI.start() && "Expected non-overlap");
Andrew Trick89eb6a82010-11-10 19:18:47 +0000164
Jakob Stoklund Olesen1f582ba2011-08-12 00:22:04 +0000165 // Advance the iterator that ends first.
Matthias Braun173e1142017-03-01 21:48:12 +0000166 LRI = LR->advanceTo(LRI, LiveUnionI.start());
167 if (LRI == LREnd)
Andrew Trick89eb6a82010-11-10 19:18:47 +0000168 break;
169
Jakob Stoklund Olesen1f582ba2011-08-12 00:22:04 +0000170 // Detect overlap, handle above.
Matthias Braun173e1142017-03-01 21:48:12 +0000171 if (LRI->start < LiveUnionI.stop())
Andrew Trick89eb6a82010-11-10 19:18:47 +0000172 continue;
Jakob Stoklund Olesen1f582ba2011-08-12 00:22:04 +0000173
174 // Still not overlapping. Catch up LiveUnionI.
Matthias Braun173e1142017-03-01 21:48:12 +0000175 LiveUnionI.advanceTo(LRI->start);
Andrew Trick89eb6a82010-11-10 19:18:47 +0000176 }
Andrew Trickfce64c92010-11-30 23:18:47 +0000177 SeenAllInterferences = true;
178 return InterferingVRegs.size();
Andrew Trick89eb6a82010-11-10 19:18:47 +0000179}
Jakob Stoklund Olesen9c7f3a42010-12-17 04:09:47 +0000180
Jakob Stoklund Olesenc141ba52012-06-05 23:57:30 +0000181void LiveIntervalUnion::Array::init(LiveIntervalUnion::Allocator &Alloc,
182 unsigned NSize) {
183 // Reuse existing allocation.
184 if (NSize == Size)
185 return;
186 clear();
187 Size = NSize;
188 LIUs = static_cast<LiveIntervalUnion*>(
Serge Pavlov76d8cce2018-02-20 05:41:26 +0000189 safe_malloc(sizeof(LiveIntervalUnion)*NSize));
Jakob Stoklund Olesenc141ba52012-06-05 23:57:30 +0000190 for (unsigned i = 0; i != Size; ++i)
191 new(LIUs + i) LiveIntervalUnion(Alloc);
192}
193
194void LiveIntervalUnion::Array::clear() {
195 if (!LIUs)
196 return;
197 for (unsigned i = 0; i != Size; ++i)
198 LIUs[i].~LiveIntervalUnion();
199 free(LIUs);
200 Size = 0;
Craig Topperc0196b12014-04-14 00:51:57 +0000201 LIUs = nullptr;
Jakob Stoklund Olesenc141ba52012-06-05 23:57:30 +0000202}