1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
|
//===-- RegAllocBase.cpp - Register Allocator Base Class ------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the RegAllocBase class which provides comon functionality
// for LiveIntervalUnion-based register allocators.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "regalloc"
#include "RegAllocBase.h"
#include "LiveRangeEdit.h"
#include "Spiller.h"
#include "VirtRegMap.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
#ifndef NDEBUG
#include "llvm/ADT/SparseBitVector.h"
#endif
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Timer.h"
using namespace llvm;
STATISTIC(NumAssigned , "Number of registers assigned");
STATISTIC(NumUnassigned , "Number of registers unassigned");
STATISTIC(NumNewQueued , "Number of new live ranges queued");
// Temporary verification option until we can put verification inside
// MachineVerifier.
static cl::opt<bool, true>
VerifyRegAlloc("verify-regalloc", cl::location(RegAllocBase::VerifyEnabled),
cl::desc("Verify during register allocation"));
const char *RegAllocBase::TimerGroupName = "Register Allocation";
bool RegAllocBase::VerifyEnabled = false;
#ifndef NDEBUG
// Verify each LiveIntervalUnion.
void RegAllocBase::verify() {
LiveVirtRegBitSet VisitedVRegs;
OwningArrayPtr<LiveVirtRegBitSet>
unionVRegs(new LiveVirtRegBitSet[PhysReg2LiveUnion.numRegs()]);
// Verify disjoint unions.
for (unsigned PhysReg = 0; PhysReg < PhysReg2LiveUnion.numRegs(); ++PhysReg) {
DEBUG(PhysReg2LiveUnion[PhysReg].print(dbgs(), TRI));
LiveVirtRegBitSet &VRegs = unionVRegs[PhysReg];
PhysReg2LiveUnion[PhysReg].verify(VRegs);
// Union + intersection test could be done efficiently in one pass, but
// don't add a method to SparseBitVector unless we really need it.
assert(!VisitedVRegs.intersects(VRegs) && "vreg in multiple unions");
VisitedVRegs |= VRegs;
}
// Verify vreg coverage.
for (LiveIntervals::iterator liItr = LIS->begin(), liEnd = LIS->end();
liItr != liEnd; ++liItr) {
unsigned reg = liItr->first;
if (TargetRegisterInfo::isPhysicalRegister(reg)) continue;
if (!VRM->hasPhys(reg)) continue; // spilled?
unsigned PhysReg = VRM->getPhys(reg);
if (!unionVRegs[PhysReg].test(reg)) {
dbgs() << "LiveVirtReg " << reg << " not in union " <<
TRI->getName(PhysReg) << "\n";
llvm_unreachable("unallocated live vreg");
}
}
// FIXME: I'm not sure how to verify spilled intervals.
}
#endif //!NDEBUG
//===----------------------------------------------------------------------===//
// RegAllocBase Implementation
//===----------------------------------------------------------------------===//
// Instantiate a LiveIntervalUnion for each physical register.
void RegAllocBase::LiveUnionArray::init(LiveIntervalUnion::Allocator &allocator,
unsigned NRegs) {
NumRegs = NRegs;
Array =
static_cast<LiveIntervalUnion*>(malloc(sizeof(LiveIntervalUnion)*NRegs));
for (unsigned r = 0; r != NRegs; ++r)
new(Array + r) LiveIntervalUnion(r, allocator);
}
void RegAllocBase::init(VirtRegMap &vrm, LiveIntervals &lis) {
NamedRegionTimer T("Initialize", TimerGroupName, TimePassesIsEnabled);
TRI = &vrm.getTargetRegInfo();
MRI = &vrm.getRegInfo();
VRM = &vrm;
LIS = &lis;
MRI->freezeReservedRegs(vrm.getMachineFunction());
RegClassInfo.runOnMachineFunction(vrm.getMachineFunction());
const unsigned NumRegs = TRI->getNumRegs();
if (NumRegs != PhysReg2LiveUnion.numRegs()) {
PhysReg2LiveUnion.init(UnionAllocator, NumRegs);
// Cache an interferece query for each physical reg
Queries.reset(new LiveIntervalUnion::Query[PhysReg2LiveUnion.numRegs()]);
}
}
void RegAllocBase::LiveUnionArray::clear() {
if (!Array)
return;
for (unsigned r = 0; r != NumRegs; ++r)
Array[r].~LiveIntervalUnion();
free(Array);
NumRegs = 0;
Array = 0;
}
void RegAllocBase::releaseMemory() {
for (unsigned r = 0, e = PhysReg2LiveUnion.numRegs(); r != e; ++r)
PhysReg2LiveUnion[r].clear();
}
// Visit all the live registers. If they are already assigned to a physical
// register, unify them with the corresponding LiveIntervalUnion, otherwise push
// them on the priority queue for later assignment.
void RegAllocBase::seedLiveRegs() {
NamedRegionTimer T("Seed Live Regs", TimerGroupName, TimePassesIsEnabled);
for (LiveIntervals::iterator I = LIS->begin(), E = LIS->end(); I != E; ++I) {
unsigned RegNum = I->first;
LiveInterval &VirtReg = *I->second;
if (TargetRegisterInfo::isPhysicalRegister(RegNum))
PhysReg2LiveUnion[RegNum].unify(VirtReg);
else
enqueue(&VirtReg);
}
}
void RegAllocBase::assign(LiveInterval &VirtReg, unsigned PhysReg) {
DEBUG(dbgs() << "assigning " << PrintReg(VirtReg.reg, TRI)
<< " to " << PrintReg(PhysReg, TRI) << '\n');
assert(!VRM->hasPhys(VirtReg.reg) && "Duplicate VirtReg assignment");
VRM->assignVirt2Phys(VirtReg.reg, PhysReg);
MRI->setPhysRegUsed(PhysReg);
PhysReg2LiveUnion[PhysReg].unify(VirtReg);
++NumAssigned;
}
void RegAllocBase::unassign(LiveInterval &VirtReg, unsigned PhysReg) {
DEBUG(dbgs() << "unassigning " << PrintReg(VirtReg.reg, TRI)
<< " from " << PrintReg(PhysReg, TRI) << '\n');
assert(VRM->getPhys(VirtReg.reg) == PhysReg && "Inconsistent unassign");
PhysReg2LiveUnion[PhysReg].extract(VirtReg);
VRM->clearVirt(VirtReg.reg);
++NumUnassigned;
}
// Top-level driver to manage the queue of unassigned VirtRegs and call the
// selectOrSplit implementation.
void RegAllocBase::allocatePhysRegs() {
seedLiveRegs();
// Continue assigning vregs one at a time to available physical registers.
while (LiveInterval *VirtReg = dequeue()) {
assert(!VRM->hasPhys(VirtReg->reg) && "Register already assigned");
// Unused registers can appear when the spiller coalesces snippets.
if (MRI->reg_nodbg_empty(VirtReg->reg)) {
DEBUG(dbgs() << "Dropping unused " << *VirtReg << '\n');
LIS->removeInterval(VirtReg->reg);
continue;
}
// Invalidate all interference queries, live ranges could have changed.
invalidateVirtRegs();
// selectOrSplit requests the allocator to return an available physical
// register if possible and populate a list of new live intervals that
// result from splitting.
DEBUG(dbgs() << "\nselectOrSplit "
<< MRI->getRegClass(VirtReg->reg)->getName()
<< ':' << *VirtReg << '\n');
typedef SmallVector<LiveInterval*, 4> VirtRegVec;
VirtRegVec SplitVRegs;
unsigned AvailablePhysReg = selectOrSplit(*VirtReg, SplitVRegs);
if (AvailablePhysReg == ~0u) {
// selectOrSplit failed to find a register!
const char *Msg = "ran out of registers during register allocation";
// Probably caused by an inline asm.
MachineInstr *MI;
for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(VirtReg->reg);
(MI = I.skipInstruction());)
if (MI->isInlineAsm())
break;
if (MI)
MI->emitError(Msg);
else
report_fatal_error(Msg);
// Keep going after reporting the error.
VRM->assignVirt2Phys(VirtReg->reg,
RegClassInfo.getOrder(MRI->getRegClass(VirtReg->reg)).front());
continue;
}
if (AvailablePhysReg)
assign(*VirtReg, AvailablePhysReg);
for (VirtRegVec::iterator I = SplitVRegs.begin(), E = SplitVRegs.end();
I != E; ++I) {
LiveInterval *SplitVirtReg = *I;
assert(!VRM->hasPhys(SplitVirtReg->reg) && "Register already assigned");
if (MRI->reg_nodbg_empty(SplitVirtReg->reg)) {
DEBUG(dbgs() << "not queueing unused " << *SplitVirtReg << '\n');
LIS->removeInterval(SplitVirtReg->reg);
continue;
}
DEBUG(dbgs() << "queuing new interval: " << *SplitVirtReg << "\n");
assert(TargetRegisterInfo::isVirtualRegister(SplitVirtReg->reg) &&
"expect split value in virtual register");
enqueue(SplitVirtReg);
++NumNewQueued;
}
}
}
// Check if this live virtual register interferes with a physical register. If
// not, then check for interference on each register that aliases with the
// physical register. Return the interfering register.
unsigned RegAllocBase::checkPhysRegInterference(LiveInterval &VirtReg,
unsigned PhysReg) {
for (const unsigned *AliasI = TRI->getOverlaps(PhysReg); *AliasI; ++AliasI)
if (query(VirtReg, *AliasI).checkInterference())
return *AliasI;
return 0;
}
// Add newly allocated physical registers to the MBB live in sets.
void RegAllocBase::addMBBLiveIns(MachineFunction *MF) {
NamedRegionTimer T("MBB Live Ins", TimerGroupName, TimePassesIsEnabled);
SlotIndexes *Indexes = LIS->getSlotIndexes();
if (MF->size() <= 1)
return;
LiveIntervalUnion::SegmentIter SI;
for (unsigned PhysReg = 0; PhysReg < PhysReg2LiveUnion.numRegs(); ++PhysReg) {
LiveIntervalUnion &LiveUnion = PhysReg2LiveUnion[PhysReg];
if (LiveUnion.empty())
continue;
DEBUG(dbgs() << PrintReg(PhysReg, TRI) << " live-in:");
MachineFunction::iterator MBB = llvm::next(MF->begin());
MachineFunction::iterator MFE = MF->end();
SlotIndex Start, Stop;
tie(Start, Stop) = Indexes->getMBBRange(MBB);
SI.setMap(LiveUnion.getMap());
SI.find(Start);
while (SI.valid()) {
if (SI.start() <= Start) {
if (!MBB->isLiveIn(PhysReg))
MBB->addLiveIn(PhysReg);
DEBUG(dbgs() << "\tBB#" << MBB->getNumber() << ':'
<< PrintReg(SI.value()->reg, TRI));
} else if (SI.start() > Stop)
MBB = Indexes->getMBBFromIndex(SI.start().getPrevIndex());
if (++MBB == MFE)
break;
tie(Start, Stop) = Indexes->getMBBRange(MBB);
SI.advanceTo(Start);
}
DEBUG(dbgs() << '\n');
}
}
|