blob: 61d065a8a22a9ba600892b828a9b2f6b476fb52e [file] [log] [blame]
Andrew Trick23d1c5c2012-01-13 22:04:16 +00001//===-- InterferenceCache.cpp - Caching per-block interference ---------*--===//
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// InterferenceCache remembers per-block interference in LiveIntervalUnions.
11//
12//===----------------------------------------------------------------------===//
13
14#define DEBUG_TYPE "regalloc"
15#include "InterferenceCache.h"
Jakob Stoklund Olesen6ef7da02012-02-10 18:58:34 +000016#include "llvm/CodeGen/LiveIntervalAnalysis.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000017#include "llvm/Support/ErrorHandling.h"
18#include "llvm/Target/TargetRegisterInfo.h"
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +000019
20using namespace llvm;
21
Jakob Stoklund Olesenc7931fd2011-07-23 03:10:17 +000022// Static member used for null interference cursors.
23InterferenceCache::BlockInterference InterferenceCache::Cursor::NoInterference;
24
Stephen Hines36b56882014-04-23 16:57:46 -070025// Initializes PhysRegEntries (instead of a SmallVector, PhysRegEntries is a
26// buffer of size NumPhysRegs to speed up alloc/clear for targets with large
27// reg files). Calloced memory is used for good form, and quites tools like
28// Valgrind too, but zero initialized memory is not required by the algorithm:
29// this is because PhysRegEntries works like a SparseSet and its entries are
30// only valid when there is a corresponding CacheEntries assignment. There is
31// also support for when pass managers are reused for targets with different
32// numbers of PhysRegs: in this case PhysRegEntries is freed and reinitialized.
33void InterferenceCache::reinitPhysRegEntries() {
34 if (PhysRegEntriesCount == TRI->getNumRegs()) return;
35 free(PhysRegEntries);
36 PhysRegEntriesCount = TRI->getNumRegs();
37 PhysRegEntries = (unsigned char*)
38 calloc(PhysRegEntriesCount, sizeof(unsigned char));
39}
40
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +000041void InterferenceCache::init(MachineFunction *mf,
42 LiveIntervalUnion *liuarray,
43 SlotIndexes *indexes,
Jakob Stoklund Olesen6ef7da02012-02-10 18:58:34 +000044 LiveIntervals *lis,
Jakob Stoklund Olesenc7931fd2011-07-23 03:10:17 +000045 const TargetRegisterInfo *tri) {
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +000046 MF = mf;
47 LIUArray = liuarray;
48 TRI = tri;
Stephen Hines36b56882014-04-23 16:57:46 -070049 reinitPhysRegEntries();
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +000050 for (unsigned i = 0; i != CacheEntries; ++i)
Jakob Stoklund Olesen6ef7da02012-02-10 18:58:34 +000051 Entries[i].clear(mf, indexes, lis);
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +000052}
53
54InterferenceCache::Entry *InterferenceCache::get(unsigned PhysReg) {
55 unsigned E = PhysRegEntries[PhysReg];
56 if (E < CacheEntries && Entries[E].getPhysReg() == PhysReg) {
57 if (!Entries[E].valid(LIUArray, TRI))
Jakob Stoklund Olesen042888d2012-06-20 22:52:26 +000058 Entries[E].revalidate(LIUArray, TRI);
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +000059 return &Entries[E];
60 }
61 // No valid entry exists, pick the next round-robin entry.
62 E = RoundRobin;
63 if (++RoundRobin == CacheEntries)
64 RoundRobin = 0;
Jakob Stoklund Olesenf1c70982011-07-14 05:35:11 +000065 for (unsigned i = 0; i != CacheEntries; ++i) {
66 // Skip entries that are in use.
67 if (Entries[E].hasRefs()) {
68 if (++E == CacheEntries)
69 E = 0;
70 continue;
71 }
72 Entries[E].reset(PhysReg, LIUArray, TRI, MF);
73 PhysRegEntries[PhysReg] = E;
74 return &Entries[E];
75 }
76 llvm_unreachable("Ran out of interference cache entries.");
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +000077}
78
79/// revalidate - LIU contents have changed, update tags.
Jakob Stoklund Olesen042888d2012-06-20 22:52:26 +000080void InterferenceCache::Entry::revalidate(LiveIntervalUnion *LIUArray,
81 const TargetRegisterInfo *TRI) {
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +000082 // Invalidate all block entries.
83 ++Tag;
84 // Invalidate all iterators.
85 PrevPos = SlotIndex();
Jakob Stoklund Olesen042888d2012-06-20 22:52:26 +000086 unsigned i = 0;
87 for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units, ++i)
88 RegUnits[i].VirtTag = LIUArray[*Units].getTag();
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +000089}
90
91void InterferenceCache::Entry::reset(unsigned physReg,
92 LiveIntervalUnion *LIUArray,
93 const TargetRegisterInfo *TRI,
94 const MachineFunction *MF) {
Jakob Stoklund Olesenf1c70982011-07-14 05:35:11 +000095 assert(!hasRefs() && "Cannot reset cache entry with references");
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +000096 // LIU's changed, invalidate cache.
97 ++Tag;
98 PhysReg = physReg;
99 Blocks.resize(MF->getNumBlockIDs());
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +0000100
101 // Reset iterators.
102 PrevPos = SlotIndex();
Jakob Stoklund Olesen042888d2012-06-20 22:52:26 +0000103 RegUnits.clear();
104 for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
105 RegUnits.push_back(LIUArray[*Units]);
106 RegUnits.back().Fixed = &LIS->getRegUnit(*Units);
107 }
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +0000108}
109
110bool InterferenceCache::Entry::valid(LiveIntervalUnion *LIUArray,
111 const TargetRegisterInfo *TRI) {
Jakob Stoklund Olesen042888d2012-06-20 22:52:26 +0000112 unsigned i = 0, e = RegUnits.size();
113 for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units, ++i) {
114 if (i == e)
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +0000115 return false;
Jakob Stoklund Olesen042888d2012-06-20 22:52:26 +0000116 if (LIUArray[*Units].changedSince(RegUnits[i].VirtTag))
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +0000117 return false;
118 }
119 return i == e;
120}
121
122void InterferenceCache::Entry::update(unsigned MBBNum) {
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +0000123 SlotIndex Start, Stop;
Stephen Hines36b56882014-04-23 16:57:46 -0700124 std::tie(Start, Stop) = Indexes->getMBBRange(MBBNum);
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +0000125
126 // Use advanceTo only when possible.
Jakob Stoklund Olesenf34ae322011-04-07 17:27:50 +0000127 if (PrevPos != Start) {
Jakob Stoklund Olesen042888d2012-06-20 22:52:26 +0000128 if (!PrevPos.isValid() || Start < PrevPos) {
129 for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) {
130 RegUnitInfo &RUI = RegUnits[i];
131 RUI.VirtI.find(Start);
132 RUI.FixedI = RUI.Fixed->find(Start);
133 }
134 } else {
135 for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) {
136 RegUnitInfo &RUI = RegUnits[i];
137 RUI.VirtI.advanceTo(Start);
138 if (RUI.FixedI != RUI.Fixed->end())
139 RUI.FixedI = RUI.Fixed->advanceTo(RUI.FixedI, Start);
140 }
141 }
Jakob Stoklund Olesenf34ae322011-04-07 17:27:50 +0000142 PrevPos = Start;
143 }
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +0000144
Jakob Stoklund Olesen9d29cba2011-04-09 02:59:05 +0000145 MachineFunction::const_iterator MFI = MF->getBlockNumbered(MBBNum);
146 BlockInterference *BI = &Blocks[MBBNum];
Jakob Stoklund Olesen6ef7da02012-02-10 18:58:34 +0000147 ArrayRef<SlotIndex> RegMaskSlots;
148 ArrayRef<const uint32_t*> RegMaskBits;
Jakob Stoklund Olesen9d29cba2011-04-09 02:59:05 +0000149 for (;;) {
150 BI->Tag = Tag;
151 BI->First = BI->Last = SlotIndex();
152
Jakob Stoklund Olesen042888d2012-06-20 22:52:26 +0000153 // Check for first interference from virtregs.
154 for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) {
155 LiveIntervalUnion::SegmentIter &I = RegUnits[i].VirtI;
Jakob Stoklund Olesen9d29cba2011-04-09 02:59:05 +0000156 if (!I.valid())
157 continue;
158 SlotIndex StartI = I.start();
159 if (StartI >= Stop)
160 continue;
161 if (!BI->First.isValid() || StartI < BI->First)
162 BI->First = StartI;
163 }
164
Jakob Stoklund Olesen042888d2012-06-20 22:52:26 +0000165 // Same thing for fixed interference.
166 for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) {
167 LiveInterval::const_iterator I = RegUnits[i].FixedI;
168 LiveInterval::const_iterator E = RegUnits[i].Fixed->end();
169 if (I == E)
170 continue;
171 SlotIndex StartI = I->start;
172 if (StartI >= Stop)
173 continue;
174 if (!BI->First.isValid() || StartI < BI->First)
175 BI->First = StartI;
176 }
177
Jakob Stoklund Olesen6ef7da02012-02-10 18:58:34 +0000178 // Also check for register mask interference.
179 RegMaskSlots = LIS->getRegMaskSlotsInBlock(MBBNum);
180 RegMaskBits = LIS->getRegMaskBitsInBlock(MBBNum);
181 SlotIndex Limit = BI->First.isValid() ? BI->First : Stop;
182 for (unsigned i = 0, e = RegMaskSlots.size();
183 i != e && RegMaskSlots[i] < Limit; ++i)
Jakob Stoklund Olesen93820082012-02-10 19:23:53 +0000184 if (MachineOperand::clobbersPhysReg(RegMaskBits[i], PhysReg)) {
Jakob Stoklund Olesen6ef7da02012-02-10 18:58:34 +0000185 // Register mask i clobbers PhysReg before the LIU interference.
186 BI->First = RegMaskSlots[i];
187 break;
188 }
189
Jakob Stoklund Olesen9d29cba2011-04-09 02:59:05 +0000190 PrevPos = Stop;
191 if (BI->First.isValid())
192 break;
193
194 // No interference in this block? Go ahead and precompute the next block.
195 if (++MFI == MF->end())
196 return;
197 MBBNum = MFI->getNumber();
198 BI = &Blocks[MBBNum];
199 if (BI->Tag == Tag)
200 return;
Stephen Hines36b56882014-04-23 16:57:46 -0700201 std::tie(Start, Stop) = Indexes->getMBBRange(MBBNum);
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +0000202 }
203
Jakob Stoklund Olesen9d29cba2011-04-09 02:59:05 +0000204 // Check for last interference in block.
Jakob Stoklund Olesen042888d2012-06-20 22:52:26 +0000205 for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) {
206 LiveIntervalUnion::SegmentIter &I = RegUnits[i].VirtI;
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +0000207 if (!I.valid() || I.start() >= Stop)
208 continue;
209 I.advanceTo(Stop);
Jakob Stoklund Olesenf34ae322011-04-07 17:27:50 +0000210 bool Backup = !I.valid() || I.start() >= Stop;
211 if (Backup)
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +0000212 --I;
213 SlotIndex StopI = I.stop();
214 if (!BI->Last.isValid() || StopI > BI->Last)
215 BI->Last = StopI;
Jakob Stoklund Olesenf34ae322011-04-07 17:27:50 +0000216 if (Backup)
217 ++I;
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +0000218 }
Jakob Stoklund Olesen6ef7da02012-02-10 18:58:34 +0000219
Jakob Stoklund Olesen042888d2012-06-20 22:52:26 +0000220 // Fixed interference.
221 for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) {
222 LiveInterval::iterator &I = RegUnits[i].FixedI;
Matthias Braun4f3b5e82013-10-10 21:29:02 +0000223 LiveRange *LR = RegUnits[i].Fixed;
224 if (I == LR->end() || I->start >= Stop)
Jakob Stoklund Olesen042888d2012-06-20 22:52:26 +0000225 continue;
Matthias Braun4f3b5e82013-10-10 21:29:02 +0000226 I = LR->advanceTo(I, Stop);
227 bool Backup = I == LR->end() || I->start >= Stop;
Jakob Stoklund Olesen042888d2012-06-20 22:52:26 +0000228 if (Backup)
229 --I;
230 SlotIndex StopI = I->end;
231 if (!BI->Last.isValid() || StopI > BI->Last)
232 BI->Last = StopI;
233 if (Backup)
234 ++I;
235 }
236
Jakob Stoklund Olesen6ef7da02012-02-10 18:58:34 +0000237 // Also check for register mask interference.
238 SlotIndex Limit = BI->Last.isValid() ? BI->Last : Start;
Jakob Stoklund Olesend5d61ed2012-02-14 23:53:23 +0000239 for (unsigned i = RegMaskSlots.size();
240 i && RegMaskSlots[i-1].getDeadSlot() > Limit; --i)
Jakob Stoklund Olesen93820082012-02-10 19:23:53 +0000241 if (MachineOperand::clobbersPhysReg(RegMaskBits[i-1], PhysReg)) {
Jakob Stoklund Olesen6ef7da02012-02-10 18:58:34 +0000242 // Register mask i-1 clobbers PhysReg after the LIU interference.
243 // Model the regmask clobber as a dead def.
244 BI->Last = RegMaskSlots[i-1].getDeadSlot();
245 break;
246 }
Jakob Stoklund Olesen5907d862011-04-02 06:03:35 +0000247}