blob: 8712e98d850b139b79ab82fb359a27dfcb619861 [file] [log] [blame]
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +00001//===-- RegAllocLinearScan.cpp - Linear Scan register allocator -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements a linear scan register allocator.
11//
12//===----------------------------------------------------------------------===//
13#define DEBUG_TYPE "regalloc"
14#include "llvm/Function.h"
15#include "llvm/CodeGen/LiveIntervals.h"
16#include "llvm/CodeGen/LiveVariables.h"
17#include "llvm/CodeGen/MachineFrameInfo.h"
18#include "llvm/CodeGen/MachineFunctionPass.h"
19#include "llvm/CodeGen/MachineInstr.h"
20#include "llvm/CodeGen/Passes.h"
21#include "llvm/CodeGen/SSARegMap.h"
22#include "llvm/Target/MRegisterInfo.h"
23#include "llvm/Target/TargetInstrInfo.h"
24#include "llvm/Target/TargetMachine.h"
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000025#include "llvm/Support/CFG.h"
26#include "Support/Debug.h"
27#include "Support/DepthFirstIterator.h"
28#include "Support/Statistic.h"
29#include "Support/STLExtras.h"
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000030using namespace llvm;
31
32namespace {
33 Statistic<> numSpilled ("ra-linearscan", "Number of registers spilled");
Chris Lattner5e46b512003-12-18 20:25:31 +000034 Statistic<> numReloaded("ra-linearscan", "Number of registers reloaded");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000035
36 class RA : public MachineFunctionPass {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000037 private:
38 MachineFunction* mf_;
39 const TargetMachine* tm_;
40 const MRegisterInfo* mri_;
Alkis Evlogimenos1283d862004-01-07 05:31:12 +000041 MachineFunction::iterator currentMbb_;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000042 MachineBasicBlock::iterator currentInstr_;
Alkis Evlogimenos1283d862004-01-07 05:31:12 +000043 typedef std::vector<const LiveIntervals::Interval*> IntervalPtrs;
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +000044 IntervalPtrs unhandled_, fixed_, active_, inactive_;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000045
46 typedef std::vector<unsigned> Regs;
47 Regs tempUseOperands_;
48 Regs tempDefOperands_;
49
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +000050 typedef std::vector<bool> RegMask;
51 RegMask reserved_;
52
53 unsigned regUse_[MRegisterInfo::FirstVirtualRegister];
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +000054 unsigned regUseBackup_[MRegisterInfo::FirstVirtualRegister];
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000055
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000056 typedef std::map<unsigned, unsigned> Virt2PhysMap;
57 Virt2PhysMap v2pMap_;
58
59 typedef std::map<unsigned, int> Virt2StackSlotMap;
60 Virt2StackSlotMap v2ssMap_;
61
62 int instrAdded_;
63
64 public:
65 virtual const char* getPassName() const {
66 return "Linear Scan Register Allocator";
67 }
68
69 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
70 AU.addRequired<LiveVariables>();
71 AU.addRequired<LiveIntervals>();
72 MachineFunctionPass::getAnalysisUsage(AU);
73 }
74
75 private:
76 /// runOnMachineFunction - register allocate the whole function
77 bool runOnMachineFunction(MachineFunction&);
78
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +000079 /// initIntervalSets - initializa the four interval sets:
80 /// unhandled, fixed, active and inactive
81 void initIntervalSets(const LiveIntervals::Intervals& li);
82
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000083 /// processActiveIntervals - expire old intervals and move
84 /// non-overlapping ones to the incative list
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +000085 void processActiveIntervals(IntervalPtrs::value_type cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000086
87 /// processInactiveIntervals - expire old intervals and move
88 /// overlapping ones to the active list
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +000089 void processInactiveIntervals(IntervalPtrs::value_type cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000090
91 /// assignStackSlotAtInterval - choose and spill
92 /// interval. Currently we spill the interval with the last
93 /// end point in the active and inactive lists and the current
94 /// interval
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +000095 void assignStackSlotAtInterval(IntervalPtrs::value_type cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000096
97 ///
98 /// register handling helpers
99 ///
100
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000101 /// getFreePhysReg - return a free physical register for this
102 /// virtual register interval if we have one, otherwise return
103 /// 0
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000104 unsigned getFreePhysReg(IntervalPtrs::value_type cur);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000105
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000106 /// physRegAvailable - returns true if the specifed physical
107 /// register is available
108 bool physRegAvailable(unsigned physReg);
109
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000110 /// tempPhysRegAvailable - returns true if the specifed
111 /// temporary physical register is available
112 bool tempPhysRegAvailable(unsigned physReg);
113
114 /// getFreeTempPhysReg - return a free temprorary physical
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000115 /// register for this virtual register if we have one (should
116 /// never return 0)
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000117 unsigned getFreeTempPhysReg(unsigned virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000118
119 /// assignVirt2PhysReg - assigns the free physical register to
120 /// the virtual register passed as arguments
121 void assignVirt2PhysReg(unsigned virtReg, unsigned physReg);
122
123 /// clearVirtReg - free the physical register associated with this
124 /// virtual register and disassociate virtual->physical and
125 /// physical->virtual mappings
126 void clearVirtReg(unsigned virtReg);
127
128 /// assignVirt2StackSlot - assigns this virtual register to a
129 /// stack slot
130 void assignVirt2StackSlot(unsigned virtReg);
131
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000132 /// getStackSlot - returns the offset of the specified
133 /// register on the stack
134 int getStackSlot(unsigned virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000135
136 /// spillVirtReg - spills the virtual register
137 void spillVirtReg(unsigned virtReg);
138
139 /// loadPhysReg - loads to the physical register the value of
140 /// the virtual register specifed. Virtual register must have
141 /// an assigned stack slot
142 void loadVirt2PhysReg(unsigned virtReg, unsigned physReg);
143
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000144 void markPhysRegFree(unsigned physReg);
145 void markPhysRegNotFree(unsigned physReg);
146
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000147 void backupRegUse() {
148 memcpy(regUseBackup_, regUse_, sizeof(regUseBackup_));
149 }
150
151 void restoreRegUse() {
152 memcpy(regUse_, regUseBackup_, sizeof(regUseBackup_));
153 }
154
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000155 void printVirt2PhysMap() const {
156 std::cerr << "allocated registers:\n";
157 for (Virt2PhysMap::const_iterator
158 i = v2pMap_.begin(), e = v2pMap_.end(); i != e; ++i) {
159 std::cerr << '[' << i->first << ','
160 << mri_->getName(i->second) << "]\n";
161 }
162 std::cerr << '\n';
163 }
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000164
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000165 void printIntervals(const char* const str,
166 RA::IntervalPtrs::const_iterator i,
167 RA::IntervalPtrs::const_iterator e) const {
168 if (str) std::cerr << str << " intervals:\n";
169 for (; i != e; ++i) {
170 std::cerr << "\t\t" << **i << " -> ";
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000171 unsigned reg = (*i)->reg;
172 if (reg >= MRegisterInfo::FirstVirtualRegister) {
173 Virt2PhysMap::const_iterator it = v2pMap_.find(reg);
174 reg = (it == v2pMap_.end() ? 0 : it->second);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000175 }
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000176 std::cerr << mri_->getName((*i)->reg) << '\n';
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000177 }
178 }
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000179
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000180 void printFreeRegs(const char* const str,
181 const TargetRegisterClass* rc) const {
182 if (str) std::cerr << str << ':';
183 for (TargetRegisterClass::iterator i =
184 rc->allocation_order_begin(*mf_);
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000185 i != rc->allocation_order_end(*mf_); ++i) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000186 unsigned reg = *i;
187 if (!regUse_[reg]) {
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000188 std::cerr << ' ' << mri_->getName(reg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000189 if (reserved_[reg]) std::cerr << "*";
190 }
191 }
192 std::cerr << '\n';
193 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000194 };
195}
196
197bool RA::runOnMachineFunction(MachineFunction &fn) {
198 mf_ = &fn;
199 tm_ = &fn.getTarget();
200 mri_ = tm_->getRegisterInfo();
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000201
202 initIntervalSets(getAnalysis<LiveIntervals>().getIntervals());
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000203
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000204 v2pMap_.clear();
205 v2ssMap_.clear();
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000206 memset(regUse_, 0, sizeof(regUse_));
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000207 memset(regUseBackup_, 0, sizeof(regUseBackup_));
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000208
209 // FIXME: this will work only for the X86 backend. I need to
210 // device an algorthm to select the minimal (considering register
211 // aliasing) number of temp registers to reserve so that we have 2
212 // registers for each register class available.
213
Alkis Evlogimenos27490a62003-12-28 18:03:52 +0000214 // reserve R8: CH, CL
215 // R16: CX, DI,
216 // R32: ECX, EDI,
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000217 // RFP: FP5, FP6
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000218 reserved_.assign(MRegisterInfo::FirstVirtualRegister, false);
Alkis Evlogimenos27490a62003-12-28 18:03:52 +0000219 reserved_[ 8] = true; /* CH */
220 reserved_[ 9] = true; /* CL */
221 reserved_[10] = true; /* CX */
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000222 reserved_[12] = true; /* DI */
Alkis Evlogimenos27490a62003-12-28 18:03:52 +0000223 reserved_[18] = true; /* ECX */
224 reserved_[19] = true; /* EDI */
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000225 reserved_[28] = true; /* FP5 */
226 reserved_[29] = true; /* FP6 */
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000227
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000228 // linear scan algorithm
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000229
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000230 DEBUG(printIntervals("\tunhandled", unhandled_.begin(), unhandled_.end()));
231 DEBUG(printIntervals("\tfixed", fixed_.begin(), fixed_.end()));
232 DEBUG(printIntervals("\tactive", active_.begin(), active_.end()));
233 DEBUG(printIntervals("\tinactive", inactive_.begin(), inactive_.end()));
234
235 while (!unhandled_.empty() || !fixed_.empty()) {
236 // pick the interval with the earliest start point
237 IntervalPtrs::value_type cur;
238 if (fixed_.empty()) {
239 cur = unhandled_.front();
240 unhandled_.erase(unhandled_.begin());
241 }
242 else if (unhandled_.empty()) {
243 cur = fixed_.front();
244 fixed_.erase(fixed_.begin());
245 }
246 else if (unhandled_.front()->start() < fixed_.front()->start()) {
247 cur = unhandled_.front();
248 unhandled_.erase(unhandled_.begin());
249 }
250 else {
251 cur = fixed_.front();
252 fixed_.erase(fixed_.begin());
253 }
254
Alkis Evlogimenos5ab20272004-01-14 00:09:36 +0000255 DEBUG(std::cerr << *cur << '\n');
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000256
257 processActiveIntervals(cur);
258 processInactiveIntervals(cur);
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000259
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000260 // if this register is fixed we are done
261 if (cur->reg < MRegisterInfo::FirstVirtualRegister) {
262 markPhysRegNotFree(cur->reg);
263 active_.push_back(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000264 }
265 // otherwise we are allocating a virtual register. try to find
266 // a free physical register or spill an interval in order to
267 // assign it one (we could spill the current though).
268 else {
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000269 backupRegUse();
270
271 // for every interval in inactive we overlap with, mark the
272 // register as not free
273 for (IntervalPtrs::const_iterator i = inactive_.begin(),
274 e = inactive_.end(); i != e; ++i) {
275 unsigned reg = (*i)->reg;
276 if (reg >= MRegisterInfo::FirstVirtualRegister)
277 reg = v2pMap_[reg];
278
279 if (cur->overlaps(**i)) {
280 markPhysRegNotFree(reg);
281 }
282 }
283
284 // for every interval in fixed we overlap with,
285 // mark the register as not free
286 for (IntervalPtrs::const_iterator i = fixed_.begin(),
287 e = fixed_.end(); i != e; ++i) {
288 assert((*i)->reg < MRegisterInfo::FirstVirtualRegister &&
289 "virtual register interval in fixed set?");
290 if (cur->overlaps(**i))
291 markPhysRegNotFree((*i)->reg);
292 }
293
294 DEBUG(std::cerr << "\tallocating current interval:\n");
295
296 unsigned physReg = getFreePhysReg(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000297 if (!physReg) {
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000298 assignStackSlotAtInterval(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000299 }
300 else {
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000301 restoreRegUse();
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000302 assignVirt2PhysReg(cur->reg, physReg);
303 active_.push_back(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000304 }
305 }
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000306
307 DEBUG(printIntervals("\tactive", active_.begin(), active_.end()));
308 DEBUG(printIntervals("\tinactive", inactive_.begin(), inactive_.end())); }
309
Alkis Evlogimenos7d65a122003-12-13 05:50:19 +0000310 // expire any remaining active intervals
311 for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) {
312 unsigned reg = (*i)->reg;
313 DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000314 if (reg >= MRegisterInfo::FirstVirtualRegister) {
315 reg = v2pMap_[reg];
Alkis Evlogimenos7d65a122003-12-13 05:50:19 +0000316 }
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000317 markPhysRegFree(reg);
Alkis Evlogimenos7d65a122003-12-13 05:50:19 +0000318 }
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000319 active_.clear();
320 inactive_.clear();
Alkis Evlogimenos4d7af652003-12-14 13:24:17 +0000321
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000322 DEBUG(std::cerr << "finished register allocation\n");
323 DEBUG(printVirt2PhysMap());
324
325 DEBUG(std::cerr << "Rewrite machine code:\n");
Alkis Evlogimenos1283d862004-01-07 05:31:12 +0000326 for (currentMbb_ = mf_->begin(); currentMbb_ != mf_->end(); ++currentMbb_) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000327 instrAdded_ = 0;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000328
329 for (currentInstr_ = currentMbb_->begin();
330 currentInstr_ != currentMbb_->end(); ++currentInstr_) {
331
332 DEBUG(std::cerr << "\tinstruction: ";
333 (*currentInstr_)->print(std::cerr, *tm_););
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000334
335 // use our current mapping and actually replace and
336 // virtual register with its allocated physical registers
337 DEBUG(std::cerr << "\t\treplacing virtual registers with mapped "
338 "physical registers:\n");
339 for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
340 i != e; ++i) {
341 MachineOperand& op = (*currentInstr_)->getOperand(i);
342 if (op.isVirtualRegister()) {
343 unsigned virtReg = op.getAllocatedRegNum();
344 unsigned physReg = v2pMap_[virtReg];
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000345 if (physReg) {
346 DEBUG(std::cerr << "\t\t\t%reg" << virtReg
347 << " -> " << mri_->getName(physReg) << '\n');
348 (*currentInstr_)->SetMachineOperandReg(i, physReg);
349 }
350 }
351 }
352
353 DEBUG(std::cerr << "\t\tloading temporarily used operands to "
354 "registers:\n");
355 for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
356 i != e; ++i) {
357 MachineOperand& op = (*currentInstr_)->getOperand(i);
Alkis Evlogimenosa71e05a2003-12-18 13:15:02 +0000358 if (op.isVirtualRegister() && op.isUse() && !op.isDef()) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000359 unsigned virtReg = op.getAllocatedRegNum();
360 unsigned physReg = v2pMap_[virtReg];
361 if (!physReg) {
362 physReg = getFreeTempPhysReg(virtReg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000363 loadVirt2PhysReg(virtReg, physReg);
364 tempUseOperands_.push_back(virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000365 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000366 (*currentInstr_)->SetMachineOperandReg(i, physReg);
367 }
368 }
369
370 DEBUG(std::cerr << "\t\tclearing temporarily used operands:\n");
371 for (unsigned i = 0, e = tempUseOperands_.size(); i != e; ++i) {
372 clearVirtReg(tempUseOperands_[i]);
373 }
374 tempUseOperands_.clear();
375
376 DEBUG(std::cerr << "\t\tassigning temporarily defined operands to "
377 "registers:\n");
378 for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
379 i != e; ++i) {
380 MachineOperand& op = (*currentInstr_)->getOperand(i);
Alkis Evlogimenos4d7af652003-12-14 13:24:17 +0000381 if (op.isVirtualRegister() && op.isDef()) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000382 unsigned virtReg = op.getAllocatedRegNum();
383 unsigned physReg = v2pMap_[virtReg];
384 if (!physReg) {
385 physReg = getFreeTempPhysReg(virtReg);
386 }
Alkis Evlogimenos4d7af652003-12-14 13:24:17 +0000387 if (op.isUse()) { // def and use
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000388 loadVirt2PhysReg(virtReg, physReg);
389 }
390 else {
391 assignVirt2PhysReg(virtReg, physReg);
392 }
393 tempDefOperands_.push_back(virtReg);
394 (*currentInstr_)->SetMachineOperandReg(i, physReg);
395 }
396 }
397
Alkis Evlogimenos58587072003-11-30 23:40:39 +0000398 DEBUG(std::cerr << "\t\tspilling temporarily defined operands "
399 "of this instruction:\n");
400 ++currentInstr_; // we want to insert after this instruction
401 for (unsigned i = 0, e = tempDefOperands_.size(); i != e; ++i) {
402 spillVirtReg(tempDefOperands_[i]);
403 }
404 --currentInstr_; // restore currentInstr_ iterator
405 tempDefOperands_.clear();
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000406 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000407 }
408
409 return true;
410}
411
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000412void RA::initIntervalSets(const LiveIntervals::Intervals& li)
413{
414 assert(unhandled_.empty() && fixed_.empty() &&
415 active_.empty() && inactive_.empty() &&
416 "interval sets should be empty on initialization");
417
418 for (LiveIntervals::Intervals::const_iterator i = li.begin(), e = li.end();
419 i != e; ++i) {
420 if (i->reg < MRegisterInfo::FirstVirtualRegister)
421 fixed_.push_back(&*i);
422 else
423 unhandled_.push_back(&*i);
424 }
425}
426
427void RA::processActiveIntervals(IntervalPtrs::value_type cur)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000428{
429 DEBUG(std::cerr << "\tprocessing active intervals:\n");
430 for (IntervalPtrs::iterator i = active_.begin(); i != active_.end();) {
431 unsigned reg = (*i)->reg;
Alkis Evlogimenos3b02cbe2004-01-16 20:17:05 +0000432 // remove expired intervals
433 if ((*i)->expiredAt(cur->start())) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000434 DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000435 if (reg >= MRegisterInfo::FirstVirtualRegister) {
436 reg = v2pMap_[reg];
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000437 }
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000438 markPhysRegFree(reg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000439 // remove from active
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000440 i = active_.erase(i);
441 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000442 // move inactive intervals to inactive list
443 else if (!(*i)->liveAt(cur->start())) {
444 DEBUG(std::cerr << "\t\t\tinterval " << **i << " inactive\n");
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000445 if (reg >= MRegisterInfo::FirstVirtualRegister) {
446 reg = v2pMap_[reg];
447 }
448 markPhysRegFree(reg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000449 // add to inactive
450 inactive_.push_back(*i);
451 // remove from active
452 i = active_.erase(i);
453 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000454 else {
455 ++i;
456 }
457 }
458}
459
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000460void RA::processInactiveIntervals(IntervalPtrs::value_type cur)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000461{
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000462 DEBUG(std::cerr << "\tprocessing inactive intervals:\n");
463 for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end();) {
464 unsigned reg = (*i)->reg;
465
Alkis Evlogimenos3b02cbe2004-01-16 20:17:05 +0000466 // remove expired intervals
467 if ((*i)->expiredAt(cur->start())) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000468 DEBUG(std::cerr << "\t\t\tinterval " << **i << " expired\n");
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000469 // remove from inactive
470 i = inactive_.erase(i);
471 }
472 // move re-activated intervals in active list
473 else if ((*i)->liveAt(cur->start())) {
474 DEBUG(std::cerr << "\t\t\tinterval " << **i << " active\n");
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000475 if (reg >= MRegisterInfo::FirstVirtualRegister) {
476 reg = v2pMap_[reg];
477 }
478 markPhysRegNotFree(reg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000479 // add to active
480 active_.push_back(*i);
481 // remove from inactive
482 i = inactive_.erase(i);
483 }
484 else {
485 ++i;
486 }
487 }
488}
489
490namespace {
Alkis Evlogimenos6b4edba2003-12-21 20:19:10 +0000491 template <typename T>
492 void updateWeight(T rw[], int reg, T w)
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000493 {
Alkis Evlogimenos6b4edba2003-12-21 20:19:10 +0000494 if (rw[reg] == std::numeric_limits<T>::max() ||
495 w == std::numeric_limits<T>::max())
496 rw[reg] = std::numeric_limits<T>::max();
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000497 else
498 rw[reg] += w;
499 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000500}
501
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000502void RA::assignStackSlotAtInterval(IntervalPtrs::value_type cur)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000503{
504 DEBUG(std::cerr << "\t\tassigning stack slot at interval "
505 << *cur << ":\n");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000506
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000507 // set all weights to zero
Alkis Evlogimenos6b4edba2003-12-21 20:19:10 +0000508 float regWeight[MRegisterInfo::FirstVirtualRegister];
509 for (unsigned i = 0; i < MRegisterInfo::FirstVirtualRegister; ++i)
510 regWeight[i] = 0.0F;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000511
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000512 // for each interval in active that overlaps
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000513 for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
514 i != e; ++i) {
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000515 if (!cur->overlaps(**i))
516 continue;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000517
518 unsigned reg = (*i)->reg;
519 if (reg >= MRegisterInfo::FirstVirtualRegister) {
520 reg = v2pMap_[reg];
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000521 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000522 updateWeight(regWeight, reg, (*i)->weight);
523 for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
524 updateWeight(regWeight, *as, (*i)->weight);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000525 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000526
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000527 // for each interval in inactive that overlaps
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000528 for (IntervalPtrs::const_iterator i = inactive_.begin(),
529 e = inactive_.end(); i != e; ++i) {
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000530 if (!cur->overlaps(**i))
531 continue;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000532
533 unsigned reg = (*i)->reg;
534 if (reg >= MRegisterInfo::FirstVirtualRegister) {
535 reg = v2pMap_[reg];
536 }
537 updateWeight(regWeight, reg, (*i)->weight);
538 for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
539 updateWeight(regWeight, *as, (*i)->weight);
540 }
541
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000542 // for each fixed interval that overlaps
543 for (IntervalPtrs::const_iterator i = fixed_.begin(), e = fixed_.end();
544 i != e; ++i) {
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000545 if (!cur->overlaps(**i))
546 continue;
Alkis Evlogimenosf7df173e2004-01-13 20:37:01 +0000547
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000548 assert((*i)->reg < MRegisterInfo::FirstVirtualRegister &&
549 "virtual register interval in fixed set?");
550 updateWeight(regWeight, (*i)->reg, (*i)->weight);
551 for (const unsigned* as = mri_->getAliasSet((*i)->reg); *as; ++as)
552 updateWeight(regWeight, *as, (*i)->weight);
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000553 }
554
Alkis Evlogimenos6b4edba2003-12-21 20:19:10 +0000555 float minWeight = std::numeric_limits<float>::max();
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000556 unsigned minReg = 0;
557 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
558 for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
559 i != rc->allocation_order_end(*mf_); ++i) {
560 unsigned reg = *i;
561 if (!reserved_[reg] && minWeight > regWeight[reg]) {
562 minWeight = regWeight[reg];
563 minReg = reg;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000564 }
565 }
566
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000567 if (cur->weight < minWeight) {
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000568 restoreRegUse();
Alkis Evlogimenos5ab20272004-01-14 00:09:36 +0000569 DEBUG(std::cerr << "\t\t\t\tspilling: " << *cur << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000570 assignVirt2StackSlot(cur->reg);
571 }
572 else {
Alkis Evlogimenos5ab20272004-01-14 00:09:36 +0000573 DEBUG(std::cerr << "\t\t\t\tfreeing: " << mri_->getName(minReg) << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000574 std::set<unsigned> toSpill;
575 toSpill.insert(minReg);
576 for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
577 toSpill.insert(*as);
578
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000579 std::vector<unsigned> spilled;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000580 for (IntervalPtrs::iterator i = active_.begin();
581 i != active_.end(); ) {
582 unsigned reg = (*i)->reg;
583 if (reg >= MRegisterInfo::FirstVirtualRegister &&
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000584 toSpill.find(v2pMap_[reg]) != toSpill.end() &&
585 cur->overlaps(**i)) {
586 spilled.push_back(v2pMap_[reg]);
Alkis Evlogimenos843397c2003-12-24 18:53:31 +0000587 DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000588 assignVirt2StackSlot(reg);
589 i = active_.erase(i);
590 }
591 else {
592 ++i;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000593 }
594 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000595 for (IntervalPtrs::iterator i = inactive_.begin();
596 i != inactive_.end(); ) {
597 unsigned reg = (*i)->reg;
598 if (reg >= MRegisterInfo::FirstVirtualRegister &&
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000599 toSpill.find(v2pMap_[reg]) != toSpill.end() &&
600 cur->overlaps(**i)) {
Alkis Evlogimenos843397c2003-12-24 18:53:31 +0000601 DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000602 assignVirt2StackSlot(reg);
603 i = inactive_.erase(i);
604 }
605 else {
606 ++i;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000607 }
608 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000609
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000610 unsigned physReg = getFreePhysReg(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000611 assert(physReg && "no free physical register after spill?");
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000612
613 restoreRegUse();
614 for (unsigned i = 0; i < spilled.size(); ++i)
615 markPhysRegFree(spilled[i]);
616
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000617 assignVirt2PhysReg(cur->reg, physReg);
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000618 active_.push_back(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000619 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000620}
621
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000622bool RA::physRegAvailable(unsigned physReg)
623{
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000624 assert(!reserved_[physReg] &&
625 "cannot call this method with a reserved register");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000626
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000627 return !regUse_[physReg];
628}
629
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000630unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur)
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000631{
632 DEBUG(std::cerr << "\t\tgetting free physical register: ");
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000633 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
Alkis Evlogimenos26bfc082003-12-28 17:58:18 +0000634
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000635 for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
636 i != rc->allocation_order_end(*mf_); ++i) {
637 unsigned reg = *i;
638 if (!reserved_[reg] && !regUse_[reg]) {
639 DEBUG(std::cerr << mri_->getName(reg) << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000640 return reg;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000641 }
642 }
643
644 DEBUG(std::cerr << "no free register\n");
645 return 0;
646}
647
648bool RA::tempPhysRegAvailable(unsigned physReg)
649{
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000650 assert(reserved_[physReg] &&
651 "cannot call this method with a not reserved temp register");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000652
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000653 return !regUse_[physReg];
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000654}
655
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000656unsigned RA::getFreeTempPhysReg(unsigned virtReg)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000657{
658 DEBUG(std::cerr << "\t\tgetting free temporary physical register: ");
659
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000660 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
661 // go in reverse allocation order for the temp registers
662 for (TargetRegisterClass::iterator i = rc->allocation_order_end(*mf_) - 1;
663 i != rc->allocation_order_begin(*mf_) - 1; --i) {
664 unsigned reg = *i;
665 if (reserved_[reg] && !regUse_[reg]) {
666 DEBUG(std::cerr << mri_->getName(reg) << '\n');
667 return reg;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000668 }
669 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000670
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000671 assert(0 && "no free temporary physical register?");
672 return 0;
673}
674
675void RA::assignVirt2PhysReg(unsigned virtReg, unsigned physReg)
676{
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000677 v2pMap_[virtReg] = physReg;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000678 markPhysRegNotFree(physReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000679}
680
681void RA::clearVirtReg(unsigned virtReg)
682{
683 Virt2PhysMap::iterator it = v2pMap_.find(virtReg);
684 assert(it != v2pMap_.end() &&
685 "attempting to clear a not allocated virtual register");
686 unsigned physReg = it->second;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000687 markPhysRegFree(physReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000688 v2pMap_[virtReg] = 0; // this marks that this virtual register
689 // lives on the stack
690 DEBUG(std::cerr << "\t\t\tcleared register " << mri_->getName(physReg)
691 << "\n");
692}
693
694void RA::assignVirt2StackSlot(unsigned virtReg)
695{
696 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
697 int frameIndex = mf_->getFrameInfo()->CreateStackObject(rc);
698
699 bool inserted = v2ssMap_.insert(std::make_pair(virtReg, frameIndex)).second;
700 assert(inserted &&
701 "attempt to assign stack slot to already assigned register?");
702 // if the virtual register was previously assigned clear the mapping
703 // and free the virtual register
704 if (v2pMap_.find(virtReg) != v2pMap_.end()) {
705 clearVirtReg(virtReg);
706 }
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000707 else {
708 v2pMap_[virtReg] = 0; // this marks that this virtual register
709 // lives on the stack
710 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000711}
712
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000713int RA::getStackSlot(unsigned virtReg)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000714{
715 // use lower_bound so that we can do a possibly O(1) insert later
716 // if necessary
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000717 Virt2StackSlotMap::iterator it = v2ssMap_.find(virtReg);
718 assert(it != v2ssMap_.end() &&
719 "attempt to get stack slot on register that does not live on the stack");
720 return it->second;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000721}
722
723void RA::spillVirtReg(unsigned virtReg)
724{
725 DEBUG(std::cerr << "\t\t\tspilling register: " << virtReg);
726 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000727 int frameIndex = getStackSlot(virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000728 DEBUG(std::cerr << " to stack slot #" << frameIndex << '\n');
729 ++numSpilled;
730 instrAdded_ += mri_->storeRegToStackSlot(*currentMbb_, currentInstr_,
731 v2pMap_[virtReg], frameIndex, rc);
732 clearVirtReg(virtReg);
733}
734
735void RA::loadVirt2PhysReg(unsigned virtReg, unsigned physReg)
736{
737 DEBUG(std::cerr << "\t\t\tloading register: " << virtReg);
738 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000739 int frameIndex = getStackSlot(virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000740 DEBUG(std::cerr << " from stack slot #" << frameIndex << '\n');
Chris Lattner5e46b512003-12-18 20:25:31 +0000741 ++numReloaded;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000742 instrAdded_ += mri_->loadRegFromStackSlot(*currentMbb_, currentInstr_,
743 physReg, frameIndex, rc);
744 assignVirt2PhysReg(virtReg, physReg);
745}
746
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000747void RA::markPhysRegFree(unsigned physReg)
748{
749 assert(regUse_[physReg] != 0);
750 --regUse_[physReg];
751 for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as) {
752 physReg = *as;
753 assert(regUse_[physReg] != 0);
754 --regUse_[physReg];
755 }
756}
757
758void RA::markPhysRegNotFree(unsigned physReg)
759{
760 ++regUse_[physReg];
761 for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as) {
762 physReg = *as;
763 ++regUse_[physReg];
764 }
765}
766
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000767FunctionPass* llvm::createLinearScanRegisterAllocator() {
768 return new RA();
769}