blob: 2a5898a89d06479987a4b7c80e178e7cd6fcb537 [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//===----------------------------------------------------------------------===//
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000013
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000014#define DEBUG_TYPE "regalloc"
15#include "llvm/Function.h"
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000016#include "llvm/CodeGen/MachineFunctionPass.h"
17#include "llvm/CodeGen/MachineInstr.h"
18#include "llvm/CodeGen/Passes.h"
19#include "llvm/CodeGen/SSARegMap.h"
20#include "llvm/Target/MRegisterInfo.h"
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000021#include "llvm/Target/TargetMachine.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000022#include "llvm/Support/Debug.h"
23#include "llvm/ADT/Statistic.h"
24#include "llvm/ADT/STLExtras.h"
Chris Lattnera3b8b5c2004-07-23 17:56:30 +000025#include "LiveIntervalAnalysis.h"
Alkis Evlogimenos888b1a62004-02-23 00:53:31 +000026#include "PhysRegTracker.h"
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000027#include "VirtRegMap.h"
Alkis Evlogimenos843b1602004-02-15 10:24:21 +000028#include <algorithm>
Alkis Evlogimenos880e8e42004-05-08 03:50:03 +000029#include <cmath>
Alkis Evlogimenos26f5a692004-05-30 07:24:39 +000030#include <set>
Alkis Evlogimenos53eb3732004-07-22 08:14:44 +000031#include <queue>
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000032
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000033using namespace llvm;
34
35namespace {
Alkis Evlogimenosd55b2b12004-07-04 07:59:06 +000036
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000037 Statistic<double> efficiency
38 ("regalloc", "Ratio of intervals processed over total intervals");
Alkis Evlogimenosd55b2b12004-07-04 07:59:06 +000039
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000040 static unsigned numIterations = 0;
41 static unsigned numIntervals = 0;
Alkis Evlogimenosc1560952004-07-04 17:23:35 +000042
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000043 class RA : public MachineFunctionPass {
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000044 MachineFunction* mf_;
45 const TargetMachine* tm_;
46 const MRegisterInfo* mri_;
47 LiveIntervals* li_;
48 typedef std::vector<LiveInterval*> IntervalPtrs;
49 IntervalPtrs handled_, fixed_, active_, inactive_;
50 typedef std::priority_queue<LiveInterval*,
51 IntervalPtrs,
52 greater_ptr<LiveInterval> > IntervalHeap;
53 IntervalHeap unhandled_;
54 std::auto_ptr<PhysRegTracker> prt_;
55 std::auto_ptr<VirtRegMap> vrm_;
56 std::auto_ptr<Spiller> spiller_;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000057
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000058 typedef std::vector<float> SpillWeights;
59 SpillWeights spillWeights_;
Alkis Evlogimenosf5eaf162004-02-06 18:08:18 +000060
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000061 public:
62 virtual const char* getPassName() const {
63 return "Linear Scan Register Allocator";
64 }
65
66 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000067 AU.addRequired<LiveIntervals>();
68 MachineFunctionPass::getAnalysisUsage(AU);
69 }
70
71 /// runOnMachineFunction - register allocate the whole function
72 bool runOnMachineFunction(MachineFunction&);
73
74 void releaseMemory();
75
76 private:
77 /// linearScan - the linear scan algorithm
78 void linearScan();
79
80 /// initIntervalSets - initializa the four interval sets:
81 /// unhandled, fixed, active and inactive
82 void initIntervalSets();
83
84 /// processActiveIntervals - expire old intervals and move
85 /// non-overlapping ones to the incative list
86 void processActiveIntervals(LiveInterval* cur);
87
88 /// processInactiveIntervals - expire old intervals and move
89 /// overlapping ones to the active list
90 void processInactiveIntervals(LiveInterval* cur);
91
92 /// updateSpillWeights - updates the spill weights of the
93 /// specifed physical register and its weight
94 void updateSpillWeights(unsigned reg, SpillWeights::value_type weight);
95
96 /// assignRegOrStackSlotAtInterval - assign a register if one
97 /// is available, or spill.
98 void assignRegOrStackSlotAtInterval(LiveInterval* cur);
99
100 ///
101 /// register handling helpers
102 ///
103
104 /// getFreePhysReg - return a free physical register for this
105 /// virtual register interval if we have one, otherwise return
106 /// 0
107 unsigned getFreePhysReg(LiveInterval* cur);
108
109 /// assignVirt2StackSlot - assigns this virtual register to a
110 /// stack slot. returns the stack slot
111 int assignVirt2StackSlot(unsigned virtReg);
112
113 template <typename ItTy>
114 void printIntervals(const char* const str, ItTy i, ItTy e) const {
115 if (str) std::cerr << str << " intervals:\n";
116 for (; i != e; ++i) {
117 std::cerr << "\t" << **i << " -> ";
118 unsigned reg = (*i)->reg;
119 if (MRegisterInfo::isVirtualRegister(reg)) {
120 reg = vrm_->getPhys(reg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000121 }
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000122 std::cerr << mri_->getName(reg) << '\n';
123 }
124 }
125 };
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000126}
127
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000128void RA::releaseMemory()
129{
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000130 while (!unhandled_.empty()) unhandled_.pop();
131 fixed_.clear();
132 active_.clear();
133 inactive_.clear();
134 handled_.clear();
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000135}
136
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000137bool RA::runOnMachineFunction(MachineFunction &fn) {
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000138 mf_ = &fn;
139 tm_ = &fn.getTarget();
140 mri_ = tm_->getRegisterInfo();
141 li_ = &getAnalysis<LiveIntervals>();
142 if (!prt_.get()) prt_.reset(new PhysRegTracker(*mri_));
143 vrm_.reset(new VirtRegMap(*mf_));
144 if (!spiller_.get()) spiller_.reset(createSpiller());
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000145
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000146 initIntervalSets();
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000147
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000148 linearScan();
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000149
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000150 spiller_->runOnMachineFunction(*mf_, *vrm_);
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000151
Chris Lattner510a3ea2004-09-30 02:02:33 +0000152 vrm_.reset(); // Free the VirtRegMap
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000153 return true;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000154}
155
156void RA::linearScan()
157{
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000158 // linear scan algorithm
159 DEBUG(std::cerr << "********** LINEAR SCAN **********\n");
160 DEBUG(std::cerr << "********** Function: "
161 << mf_->getFunction()->getName() << '\n');
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000162
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000163 // DEBUG(printIntervals("unhandled", unhandled_.begin(), unhandled_.end()));
164 DEBUG(printIntervals("fixed", fixed_.begin(), fixed_.end()));
165 DEBUG(printIntervals("active", active_.begin(), active_.end()));
166 DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
167
168 while (!unhandled_.empty()) {
169 // pick the interval with the earliest start point
170 LiveInterval* cur = unhandled_.top();
171 unhandled_.pop();
172 ++numIterations;
173 DEBUG(std::cerr << "\n*** CURRENT ***: " << *cur << '\n');
174
175 processActiveIntervals(cur);
176 processInactiveIntervals(cur);
177
178 // if this register is fixed we are done
179 if (MRegisterInfo::isPhysicalRegister(cur->reg)) {
180 prt_->addRegUse(cur->reg);
181 active_.push_back(cur);
182 handled_.push_back(cur);
183 }
184 // otherwise we are allocating a virtual register. try to find
185 // a free physical register or spill an interval in order to
186 // assign it one (we could spill the current though).
187 else {
188 assignRegOrStackSlotAtInterval(cur);
189 }
190
Alkis Evlogimenos39a0d5c2004-02-20 06:15:40 +0000191 DEBUG(printIntervals("active", active_.begin(), active_.end()));
192 DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000193 }
194 numIntervals += li_->getNumIntervals();
195 efficiency = double(numIterations) / double(numIntervals);
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000196
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000197 // expire any remaining active intervals
198 for (IntervalPtrs::reverse_iterator
199 i = active_.rbegin(); i != active_.rend(); ) {
200 unsigned reg = (*i)->reg;
201 DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
202 if (MRegisterInfo::isVirtualRegister(reg))
203 reg = vrm_->getPhys(reg);
204 prt_->delRegUse(reg);
205 i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
206 }
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000207
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000208 // expire any remaining inactive intervals
209 for (IntervalPtrs::reverse_iterator
210 i = inactive_.rbegin(); i != inactive_.rend(); ) {
211 DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
212 i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
213 }
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000214
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000215 DEBUG(std::cerr << *vrm_);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000216}
217
Chris Lattner4df98e52004-07-24 03:32:06 +0000218void RA::initIntervalSets()
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000219{
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000220 assert(unhandled_.empty() && fixed_.empty() &&
221 active_.empty() && inactive_.empty() &&
222 "interval sets should be empty on initialization");
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000223
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000224 for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){
225 unhandled_.push(&i->second);
226 if (MRegisterInfo::isPhysicalRegister(i->second.reg))
227 fixed_.push_back(&i->second);
228 }
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000229}
230
231void RA::processActiveIntervals(IntervalPtrs::value_type cur)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000232{
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000233 DEBUG(std::cerr << "\tprocessing active intervals:\n");
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000234 IntervalPtrs::iterator ii = active_.begin(), ie = active_.end();
235 while (ii != ie) {
236 LiveInterval* i = *ii;
237 unsigned reg = i->reg;
238
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000239 // remove expired intervals
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000240 if (i->expiredAt(cur->start())) {
241 DEBUG(std::cerr << "\t\tinterval " << *i << " expired\n");
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000242 if (MRegisterInfo::isVirtualRegister(reg))
243 reg = vrm_->getPhys(reg);
244 prt_->delRegUse(reg);
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000245 // swap with last element and move end iterator back one position
246 std::iter_swap(ii, --ie);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000247 }
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000248 // move inactive intervals to inactive list
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000249 else if (!i->liveAt(cur->start())) {
250 DEBUG(std::cerr << "\t\tinterval " << *i << " inactive\n");
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000251 if (MRegisterInfo::isVirtualRegister(reg))
252 reg = vrm_->getPhys(reg);
253 prt_->delRegUse(reg);
254 // add to inactive
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000255 inactive_.push_back(i);
256 // swap with last element and move end iterator back one postion
257 std::iter_swap(ii, --ie);
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000258 }
259 else {
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000260 ++ii;
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000261 }
262 }
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000263 active_.erase(ie, active_.end());
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000264}
265
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000266void RA::processInactiveIntervals(IntervalPtrs::value_type cur)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000267{
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000268 DEBUG(std::cerr << "\tprocessing inactive intervals:\n");
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000269 IntervalPtrs::iterator ii = inactive_.begin(), ie = inactive_.end();
270 while (ii != ie) {
271 LiveInterval* i = *ii;
272 unsigned reg = i->reg;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000273
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000274 // remove expired intervals
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000275 if (i->expiredAt(cur->start())) {
276 DEBUG(std::cerr << "\t\tinterval " << *i << " expired\n");
277 // swap with last element and move end iterator back one position
278 std::iter_swap(ii, --ie);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000279 }
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000280 // move re-activated intervals in active list
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000281 else if (i->liveAt(cur->start())) {
282 DEBUG(std::cerr << "\t\tinterval " << *i << " active\n");
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000283 if (MRegisterInfo::isVirtualRegister(reg))
284 reg = vrm_->getPhys(reg);
285 prt_->addRegUse(reg);
286 // add to active
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000287 active_.push_back(i);
288 // swap with last element and move end iterator back one position
289 std::iter_swap(ii, --ie);
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000290 }
291 else {
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000292 ++ii;
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000293 }
294 }
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000295 inactive_.erase(ie, inactive_.end());
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000296}
297
Alkis Evlogimenosf5eaf162004-02-06 18:08:18 +0000298void RA::updateSpillWeights(unsigned reg, SpillWeights::value_type weight)
299{
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000300 spillWeights_[reg] += weight;
301 for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
302 spillWeights_[*as] += weight;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000303}
304
Alkis Evlogimenos53eb3732004-07-22 08:14:44 +0000305void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000306{
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000307 DEBUG(std::cerr << "\tallocating current interval: ");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000308
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000309 PhysRegTracker backupPrt = *prt_;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000310
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000311 spillWeights_.assign(mri_->getNumRegs(), 0.0);
Alkis Evlogimenosf5eaf162004-02-06 18:08:18 +0000312
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000313 // for each interval in active update spill weights
314 for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
315 i != e; ++i) {
316 unsigned reg = (*i)->reg;
317 if (MRegisterInfo::isVirtualRegister(reg))
318 reg = vrm_->getPhys(reg);
319 updateSpillWeights(reg, (*i)->weight);
320 }
321
322 // for every interval in inactive we overlap with, mark the
323 // register as not free and update spill weights
324 for (IntervalPtrs::const_iterator i = inactive_.begin(),
325 e = inactive_.end(); i != e; ++i) {
326 if (cur->overlaps(**i)) {
327 unsigned reg = (*i)->reg;
328 if (MRegisterInfo::isVirtualRegister(reg))
329 reg = vrm_->getPhys(reg);
330 prt_->addRegUse(reg);
331 updateSpillWeights(reg, (*i)->weight);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000332 }
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000333 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000334
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000335 // for every interval in fixed we overlap with,
336 // mark the register as not free and update spill weights
337 for (IntervalPtrs::const_iterator i = fixed_.begin(),
338 e = fixed_.end(); i != e; ++i) {
339 if (cur->overlaps(**i)) {
340 unsigned reg = (*i)->reg;
341 prt_->addRegUse(reg);
342 updateSpillWeights(reg, (*i)->weight);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000343 }
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000344 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000345
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000346 unsigned physReg = getFreePhysReg(cur);
347 // restore the physical register tracker
348 *prt_ = backupPrt;
349 // if we find a free register, we are done: assign this virtual to
350 // the free physical register and add this interval to the active
351 // list.
352 if (physReg) {
353 DEBUG(std::cerr << mri_->getName(physReg) << '\n');
354 vrm_->assignVirt2Phys(cur->reg, physReg);
355 prt_->addRegUse(physReg);
356 active_.push_back(cur);
357 handled_.push_back(cur);
358 return;
359 }
360 DEBUG(std::cerr << "no free registers\n");
361
362 DEBUG(std::cerr << "\tassigning stack slot at interval "<< *cur << ":\n");
363
364 float minWeight = HUGE_VAL;
365 unsigned minReg = 0;
366 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
367 for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
368 i != rc->allocation_order_end(*mf_); ++i) {
369 unsigned reg = *i;
370 if (minWeight > spillWeights_[reg]) {
371 minWeight = spillWeights_[reg];
372 minReg = reg;
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000373 }
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000374 }
375 DEBUG(std::cerr << "\t\tregister with min weight: "
376 << mri_->getName(minReg) << " (" << minWeight << ")\n");
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000377
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000378 // if the current has the minimum weight, we need to spill it and
379 // add any added intervals back to unhandled, and restart
380 // linearscan.
381 if (cur->weight <= minWeight) {
382 DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n';);
383 int slot = vrm_->assignVirt2StackSlot(cur->reg);
384 std::vector<LiveInterval*> added =
385 li_->addIntervalsForSpills(*cur, *vrm_, slot);
386 if (added.empty())
387 return; // Early exit if all spills were folded.
Alkis Evlogimenosf5eaf162004-02-06 18:08:18 +0000388
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000389 // Merge added with unhandled. Note that we know that
390 // addIntervalsForSpills returns intervals sorted by their starting
391 // point.
Alkis Evlogimenos53eb3732004-07-22 08:14:44 +0000392 for (unsigned i = 0, e = added.size(); i != e; ++i)
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000393 unhandled_.push(added[i]);
394 return;
395 }
396
397 // push the current interval back to unhandled since we are going
398 // to re-run at least this iteration. Since we didn't modify it it
399 // should go back right in the front of the list
400 unhandled_.push(cur);
401
402 // otherwise we spill all intervals aliasing the register with
403 // minimum weight, rollback to the interval with the earliest
404 // start point and let the linear scan algorithm run again
405 std::vector<LiveInterval*> added;
406 assert(MRegisterInfo::isPhysicalRegister(minReg) &&
407 "did not choose a register to spill?");
408 std::vector<bool> toSpill(mri_->getNumRegs(), false);
409 // we are going to spill minReg and all its aliases
410 toSpill[minReg] = true;
411 for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
412 toSpill[*as] = true;
413
414 // the earliest start of a spilled interval indicates up to where
415 // in handled we need to roll back
416 unsigned earliestStart = cur->start();
417
418 // set of spilled vregs (used later to rollback properly)
419 std::set<unsigned> spilled;
420
421 // spill live intervals of virtual regs mapped to the physical
422 // register we want to clear (and its aliases). we only spill
423 // those that overlap with the current interval as the rest do not
424 // affect its allocation. we also keep track of the earliest start
425 // of all spilled live intervals since this will mark our rollback
426 // point
427 for (IntervalPtrs::iterator
428 i = active_.begin(); i != active_.end(); ++i) {
429 unsigned reg = (*i)->reg;
430 if (MRegisterInfo::isVirtualRegister(reg) &&
431 toSpill[vrm_->getPhys(reg)] &&
432 cur->overlaps(**i)) {
433 DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n');
434 earliestStart = std::min(earliestStart, (*i)->start());
435 int slot = vrm_->assignVirt2StackSlot((*i)->reg);
436 std::vector<LiveInterval*> newIs =
437 li_->addIntervalsForSpills(**i, *vrm_, slot);
438 std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
439 spilled.insert(reg);
440 }
441 }
442 for (IntervalPtrs::iterator
443 i = inactive_.begin(); i != inactive_.end(); ++i) {
444 unsigned reg = (*i)->reg;
445 if (MRegisterInfo::isVirtualRegister(reg) &&
446 toSpill[vrm_->getPhys(reg)] &&
447 cur->overlaps(**i)) {
448 DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n');
449 earliestStart = std::min(earliestStart, (*i)->start());
450 int slot = vrm_->assignVirt2StackSlot((*i)->reg);
451 std::vector<LiveInterval*> newIs =
452 li_->addIntervalsForSpills(**i, *vrm_, slot);
453 std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
454 spilled.insert(reg);
455 }
456 }
457
458 DEBUG(std::cerr << "\t\trolling back to: " << earliestStart << '\n');
459 // scan handled in reverse order up to the earliaset start of a
460 // spilled live interval and undo each one, restoring the state of
461 // unhandled
462 while (!handled_.empty()) {
463 LiveInterval* i = handled_.back();
464 // if this interval starts before t we are done
465 if (i->start() < earliestStart)
466 break;
467 DEBUG(std::cerr << "\t\t\tundo changes for: " << *i << '\n');
468 handled_.pop_back();
469 // when undoing a live interval allocation we must know if it
470 // is active or inactive to properly update the PhysRegTracker
471 // and the VirtRegMap
472 IntervalPtrs::iterator it;
Alkis Evlogimenos20aa4742004-09-03 18:19:51 +0000473 if ((it = std::find(active_.begin(), active_.end(), i)) != active_.end()) {
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000474 active_.erase(it);
475 if (MRegisterInfo::isPhysicalRegister(i->reg)) {
476 prt_->delRegUse(i->reg);
477 unhandled_.push(i);
478 }
479 else {
480 if (!spilled.count(i->reg))
481 unhandled_.push(i);
482 prt_->delRegUse(vrm_->getPhys(i->reg));
483 vrm_->clearVirt(i->reg);
484 }
485 }
Alkis Evlogimenos20aa4742004-09-03 18:19:51 +0000486 else if ((it = std::find(inactive_.begin(), inactive_.end(), i)) != inactive_.end()) {
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000487 inactive_.erase(it);
488 if (MRegisterInfo::isPhysicalRegister(i->reg))
489 unhandled_.push(i);
490 else {
491 if (!spilled.count(i->reg))
492 unhandled_.push(i);
493 vrm_->clearVirt(i->reg);
494 }
495 }
496 else {
497 if (MRegisterInfo::isVirtualRegister(i->reg))
498 vrm_->clearVirt(i->reg);
499 unhandled_.push(i);
500 }
501 }
502
503 // scan the rest and undo each interval that expired after t and
504 // insert it in active (the next iteration of the algorithm will
505 // put it in inactive if required)
506 IntervalPtrs::iterator i = handled_.begin(), e = handled_.end();
507 for (; i != e; ++i) {
508 if (!(*i)->expiredAt(earliestStart) && (*i)->expiredAt(cur->start())) {
509 DEBUG(std::cerr << "\t\t\tundo changes for: " << **i << '\n');
510 active_.push_back(*i);
511 if (MRegisterInfo::isPhysicalRegister((*i)->reg))
512 prt_->addRegUse((*i)->reg);
513 else
514 prt_->addRegUse(vrm_->getPhys((*i)->reg));
515 }
516 }
517
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000518 // merge added with unhandled
519 for (unsigned i = 0, e = added.size(); i != e; ++i)
520 unhandled_.push(added[i]);
Alkis Evlogimenos843b1602004-02-15 10:24:21 +0000521}
Alkis Evlogimenosf5eaf162004-02-06 18:08:18 +0000522
Alkis Evlogimenos53eb3732004-07-22 08:14:44 +0000523unsigned RA::getFreePhysReg(LiveInterval* cur)
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000524{
Alkis Evlogimenos84f5bcb2004-09-02 21:23:32 +0000525 std::vector<unsigned> inactiveCounts(mri_->getNumRegs(), 0);
526 for (IntervalPtrs::iterator i = inactive_.begin(), e = inactive_.end();
527 i != e; ++i) {
528 unsigned reg = (*i)->reg;
529 if (MRegisterInfo::isVirtualRegister(reg))
530 reg = vrm_->getPhys(reg);
531 ++inactiveCounts[reg];
532 }
533
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000534 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
Alkis Evlogimenos26bfc082003-12-28 17:58:18 +0000535
Alkis Evlogimenos84f5bcb2004-09-02 21:23:32 +0000536 unsigned freeReg = 0;
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000537 for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
538 i != rc->allocation_order_end(*mf_); ++i) {
539 unsigned reg = *i;
Alkis Evlogimenos84f5bcb2004-09-02 21:23:32 +0000540 if (prt_->isRegAvail(reg) &&
541 (!freeReg || inactiveCounts[freeReg] < inactiveCounts[reg]))
542 freeReg = reg;
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000543 }
Alkis Evlogimenos84f5bcb2004-09-02 21:23:32 +0000544 return freeReg;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000545}
546
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000547FunctionPass* llvm::createLinearScanRegisterAllocator() {
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000548 return new RA();
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000549}