blob: 0ebef5ef643a968dbfb97407c759c59806b73190 [file] [log] [blame]
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +00001//===-- RegAllocIterativeScan.cpp - Iterative 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//
Alkis Evlogimenos3b1af0b2004-07-21 08:28:39 +000010// This file implements an iterative scan register
11// allocator. Iterative scan is a linear scan variant with the
12// following difference:
13//
14// It performs linear scan and keeps a list of the registers it cannot
15// allocate. It then spills all those registers and repeats the
16// process until allocation succeeds.
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +000017//
18//===----------------------------------------------------------------------===//
19
20#define DEBUG_TYPE "regalloc"
21#include "llvm/Function.h"
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +000022#include "llvm/CodeGen/MachineFunctionPass.h"
23#include "llvm/CodeGen/MachineInstr.h"
24#include "llvm/CodeGen/Passes.h"
25#include "llvm/CodeGen/SSARegMap.h"
26#include "llvm/Target/MRegisterInfo.h"
27#include "llvm/Target/TargetMachine.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000028#include "llvm/Support/Debug.h"
29#include "llvm/ADT/Statistic.h"
30#include "llvm/ADT/STLExtras.h"
Chris Lattnera3b8b5c2004-07-23 17:56:30 +000031#include "LiveIntervalAnalysis.h"
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +000032#include "PhysRegTracker.h"
33#include "VirtRegMap.h"
34#include <algorithm>
35#include <cmath>
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +000036#include <set>
37
38using namespace llvm;
39
40namespace {
41
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000042 Statistic<double> efficiency
43 ("regalloc", "Ratio of intervals processed over total intervals");
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +000044
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000045 static unsigned numIterations = 0;
46 static unsigned numIntervals = 0;
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +000047
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000048 class RA : public MachineFunctionPass {
49 private:
50 MachineFunction* mf_;
51 const TargetMachine* tm_;
52 const MRegisterInfo* mri_;
53 LiveIntervals* li_;
Chris Lattnerb0f31bf2005-01-23 22:45:13 +000054 bool *PhysRegsUsed;
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000055 typedef std::vector<LiveInterval*> IntervalPtrs;
56 IntervalPtrs unhandled_, fixed_, active_, inactive_, handled_, spilled_;
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +000057
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000058 std::auto_ptr<PhysRegTracker> prt_;
59 std::auto_ptr<VirtRegMap> vrm_;
60 std::auto_ptr<Spiller> spiller_;
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +000061
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000062 typedef std::vector<float> SpillWeights;
63 SpillWeights spillWeights_;
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +000064
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000065 public:
66 virtual const char* getPassName() const {
67 return "Iterative Scan Register Allocator";
68 }
69
70 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +000071 AU.addRequired<LiveIntervals>();
72 MachineFunctionPass::getAnalysisUsage(AU);
73 }
74
75 /// runOnMachineFunction - register allocate the whole function
76 bool runOnMachineFunction(MachineFunction&);
77
78 void releaseMemory();
79
80 private:
81 /// linearScan - the linear scan algorithm. Returns a boolean
82 /// indicating if there were any spills
83 bool linearScan();
84
85 /// initIntervalSets - initializes the four interval sets:
86 /// unhandled, fixed, active and inactive
87 void initIntervalSets();
88
89 /// processActiveIntervals - expire old intervals and move
90 /// non-overlapping ones to the incative list
91 void processActiveIntervals(IntervalPtrs::value_type cur);
92
93 /// processInactiveIntervals - expire old intervals and move
94 /// overlapping ones to the active list
95 void processInactiveIntervals(IntervalPtrs::value_type cur);
96
97 /// updateSpillWeights - updates the spill weights of the
98 /// specifed physical register and its weight
99 void updateSpillWeights(unsigned reg, SpillWeights::value_type weight);
100
101 /// assignRegOrStackSlotAtInterval - assign a register if one
102 /// is available, or spill.
103 void assignRegOrSpillAtInterval(IntervalPtrs::value_type cur);
104
105 ///
106 /// register handling helpers
107 ///
108
109 /// getFreePhysReg - return a free physical register for this
110 /// virtual register interval if we have one, otherwise return
111 /// 0
112 unsigned getFreePhysReg(IntervalPtrs::value_type cur);
113
114 /// assignVirt2StackSlot - assigns this virtual register to a
115 /// stack slot. returns the stack slot
116 int assignVirt2StackSlot(unsigned virtReg);
117
118 void printIntervals(const char* const str,
119 RA::IntervalPtrs::const_iterator i,
120 RA::IntervalPtrs::const_iterator e) const {
121 if (str) std::cerr << str << " intervals:\n";
122 for (; i != e; ++i) {
123 std::cerr << "\t" << **i << " -> ";
124 unsigned reg = (*i)->reg;
125 if (MRegisterInfo::isVirtualRegister(reg)) {
126 reg = vrm_->getPhys(reg);
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000127 }
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000128 std::cerr << mri_->getName(reg) << '\n';
129 }
130 }
131 };
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000132}
133
134void RA::releaseMemory()
135{
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000136 unhandled_.clear();
137 fixed_.clear();
138 active_.clear();
139 inactive_.clear();
140 handled_.clear();
141 spilled_.clear();
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000142}
143
144bool RA::runOnMachineFunction(MachineFunction &fn) {
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000145 mf_ = &fn;
146 tm_ = &fn.getTarget();
147 mri_ = tm_->getRegisterInfo();
148 li_ = &getAnalysis<LiveIntervals>();
Chris Lattnerb0f31bf2005-01-23 22:45:13 +0000149
150 PhysRegsUsed = new bool[mri_->getNumRegs()];
151 std::fill(PhysRegsUsed, PhysRegsUsed+mri_->getNumRegs(), false);
152 fn.setUsedPhysRegs(PhysRegsUsed);
153
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000154 if (!prt_.get()) prt_.reset(new PhysRegTracker(*mri_));
155 vrm_.reset(new VirtRegMap(*mf_));
156 if (!spiller_.get()) spiller_.reset(createSpiller());
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000157
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000158 initIntervalSets();
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000159
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000160 numIntervals += li_->getNumIntervals();
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000161
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000162 while (linearScan()) {
163 // we spilled some registers, so we need to add intervals for
164 // the spill code and restart the algorithm
165 std::set<unsigned> spilledRegs;
166 for (IntervalPtrs::iterator
167 i = spilled_.begin(); i != spilled_.end(); ++i) {
168 int slot = vrm_->assignVirt2StackSlot((*i)->reg);
169 std::vector<LiveInterval*> added =
170 li_->addIntervalsForSpills(**i, *vrm_, slot);
171 std::copy(added.begin(), added.end(), std::back_inserter(handled_));
172 spilledRegs.insert((*i)->reg);
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000173 }
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000174 spilled_.clear();
175 for (IntervalPtrs::iterator
176 i = handled_.begin(); i != handled_.end(); )
177 if (spilledRegs.count((*i)->reg))
178 i = handled_.erase(i);
179 else
180 ++i;
181 handled_.swap(unhandled_);
182 vrm_->clearAllVirt();
183 }
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000184
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000185 efficiency = double(numIterations) / double(numIntervals);
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000186
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000187 DEBUG(std::cerr << *vrm_);
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000188
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000189 spiller_->runOnMachineFunction(*mf_, *vrm_);
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000190
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000191 return true;
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000192}
193
194bool RA::linearScan()
195{
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000196 // linear scan algorithm
197 DEBUG(std::cerr << "********** LINEAR SCAN **********\n");
198 DEBUG(std::cerr << "********** Function: "
199 << mf_->getFunction()->getName() << '\n');
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000200
201
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000202 std::sort(unhandled_.begin(), unhandled_.end(),
203 greater_ptr<LiveInterval>());
204 DEBUG(printIntervals("unhandled", unhandled_.begin(), unhandled_.end()));
205 DEBUG(printIntervals("fixed", fixed_.begin(), fixed_.end()));
206 DEBUG(printIntervals("active", active_.begin(), active_.end()));
207 DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
208
209 while (!unhandled_.empty()) {
210 // pick the interval with the earliest start point
211 IntervalPtrs::value_type cur = unhandled_.back();
212 unhandled_.pop_back();
213 ++numIterations;
214 DEBUG(std::cerr << "\n*** CURRENT ***: " << *cur << '\n');
215
216 processActiveIntervals(cur);
217 processInactiveIntervals(cur);
218
219 // if this register is fixed we are done
220 if (MRegisterInfo::isPhysicalRegister(cur->reg)) {
221 prt_->addRegUse(cur->reg);
222 active_.push_back(cur);
223 handled_.push_back(cur);
224 }
225 // otherwise we are allocating a virtual register. try to find
226 // a free physical register or spill an interval in order to
227 // assign it one (we could spill the current though).
228 else {
229 assignRegOrSpillAtInterval(cur);
230 }
231
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000232 DEBUG(printIntervals("active", active_.begin(), active_.end()));
233 DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000234 }
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000235
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000236 // expire any remaining active intervals
237 for (IntervalPtrs::reverse_iterator
238 i = active_.rbegin(); i != active_.rend(); ) {
239 unsigned reg = (*i)->reg;
240 DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
241 if (MRegisterInfo::isVirtualRegister(reg))
242 reg = vrm_->getPhys(reg);
243 prt_->delRegUse(reg);
244 i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
245 }
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000246
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000247 // expire any remaining inactive intervals
248 for (IntervalPtrs::reverse_iterator
249 i = inactive_.rbegin(); i != inactive_.rend(); ) {
250 DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
251 i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
252 }
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000253
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000254 // return true if we spilled anything
255 return !spilled_.empty();
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000256}
257
Chris Lattner4df98e52004-07-24 03:32:06 +0000258void RA::initIntervalSets() {
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000259 assert(unhandled_.empty() && fixed_.empty() &&
260 active_.empty() && inactive_.empty() &&
261 "interval sets should be empty on initialization");
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000262
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000263 for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){
264 unhandled_.push_back(&i->second);
Chris Lattnerb0f31bf2005-01-23 22:45:13 +0000265 if (MRegisterInfo::isPhysicalRegister(i->second.reg)) {
266 PhysRegsUsed[i->second.reg] = true;
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000267 fixed_.push_back(&i->second);
Chris Lattnerb0f31bf2005-01-23 22:45:13 +0000268 }
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000269 }
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000270}
271
272void RA::processActiveIntervals(IntervalPtrs::value_type cur)
273{
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000274 DEBUG(std::cerr << "\tprocessing active intervals:\n");
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000275 IntervalPtrs::iterator ii = active_.begin(), ie = active_.end();
276 while (ii != ie) {
277 LiveInterval* i = *ii;
278 unsigned reg = i->reg;
279
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000280 // remove expired intervals
Chris Lattner23b71c12004-11-18 01:29:39 +0000281 if (i->expiredAt(cur->beginNumber())) {
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000282 DEBUG(std::cerr << "\t\tinterval " << *i << " expired\n");
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000283 if (MRegisterInfo::isVirtualRegister(reg))
284 reg = vrm_->getPhys(reg);
285 prt_->delRegUse(reg);
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000286 // swap with last element and move end iterator back one position
287 std::iter_swap(ii, --ie);
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000288 }
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000289 // move inactive intervals to inactive list
Chris Lattner23b71c12004-11-18 01:29:39 +0000290 else if (!i->liveAt(cur->beginNumber())) {
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000291 DEBUG(std::cerr << "\t\tinterval " << *i << " inactive\n");
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000292 if (MRegisterInfo::isVirtualRegister(reg))
293 reg = vrm_->getPhys(reg);
294 prt_->delRegUse(reg);
295 // add to inactive
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000296 inactive_.push_back(i);
297 // swap with last element and move end iterator back one postion
298 std::iter_swap(ii, --ie);
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000299 }
300 else {
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000301 ++ii;
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000302 }
303 }
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000304 active_.erase(ie, active_.end());
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000305}
306
307void RA::processInactiveIntervals(IntervalPtrs::value_type cur)
308{
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000309 DEBUG(std::cerr << "\tprocessing inactive intervals:\n");
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000310 IntervalPtrs::iterator ii = inactive_.begin(), ie = inactive_.end();
311 while (ii != ie) {
312 LiveInterval* i = *ii;
313 unsigned reg = i->reg;
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000314
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000315 // remove expired intervals
Chris Lattner23b71c12004-11-18 01:29:39 +0000316 if (i->expiredAt(cur->beginNumber())) {
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000317 DEBUG(std::cerr << "\t\tinterval " << *i << " expired\n");
318 // swap with last element and move end iterator back one position
319 std::iter_swap(ii, --ie);
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000320 }
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000321 // move re-activated intervals in active list
Chris Lattner23b71c12004-11-18 01:29:39 +0000322 else if (i->liveAt(cur->beginNumber())) {
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000323 DEBUG(std::cerr << "\t\tinterval " << *i << " active\n");
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000324 if (MRegisterInfo::isVirtualRegister(reg))
325 reg = vrm_->getPhys(reg);
326 prt_->addRegUse(reg);
327 // add to active
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000328 active_.push_back(i);
329 // swap with last element and move end iterator back one position
330 std::iter_swap(ii, --ie);
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000331 }
332 else {
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000333 ++ii;
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000334 }
335 }
Alkis Evlogimenosed543732004-09-01 22:52:29 +0000336 inactive_.erase(ie, inactive_.end());
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000337}
338
339void RA::updateSpillWeights(unsigned reg, SpillWeights::value_type weight)
340{
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000341 spillWeights_[reg] += weight;
342 for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
343 spillWeights_[*as] += weight;
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000344}
345
346void RA::assignRegOrSpillAtInterval(IntervalPtrs::value_type cur)
347{
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000348 DEBUG(std::cerr << "\tallocating current interval: ");
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000349
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000350 PhysRegTracker backupPrt = *prt_;
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000351
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000352 spillWeights_.assign(mri_->getNumRegs(), 0.0);
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000353
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000354 // for each interval in active update spill weights
355 for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
356 i != e; ++i) {
357 unsigned reg = (*i)->reg;
358 if (MRegisterInfo::isVirtualRegister(reg))
359 reg = vrm_->getPhys(reg);
360 updateSpillWeights(reg, (*i)->weight);
361 }
362
363 // for every interval in inactive we overlap with, mark the
364 // register as not free and update spill weights
365 for (IntervalPtrs::const_iterator i = inactive_.begin(),
366 e = inactive_.end(); i != e; ++i) {
367 if (cur->overlaps(**i)) {
368 unsigned reg = (*i)->reg;
369 if (MRegisterInfo::isVirtualRegister(reg))
370 reg = vrm_->getPhys(reg);
371 prt_->addRegUse(reg);
372 updateSpillWeights(reg, (*i)->weight);
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000373 }
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000374 }
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000375
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000376 // for every interval in fixed we overlap with,
377 // mark the register as not free and update spill weights
378 for (IntervalPtrs::const_iterator i = fixed_.begin(),
379 e = fixed_.end(); i != e; ++i) {
380 if (cur->overlaps(**i)) {
381 unsigned reg = (*i)->reg;
382 prt_->addRegUse(reg);
383 updateSpillWeights(reg, (*i)->weight);
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000384 }
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000385 }
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000386
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000387 unsigned physReg = getFreePhysReg(cur);
388 // restore the physical register tracker
389 *prt_ = backupPrt;
390 // if we find a free register, we are done: assign this virtual to
391 // the free physical register and add this interval to the active
392 // list.
393 if (physReg) {
394 DEBUG(std::cerr << mri_->getName(physReg) << '\n');
395 vrm_->assignVirt2Phys(cur->reg, physReg);
396 prt_->addRegUse(physReg);
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000397 active_.push_back(cur);
398 handled_.push_back(cur);
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000399 return;
400 }
401 DEBUG(std::cerr << "no free registers\n");
402
403 DEBUG(std::cerr << "\tassigning stack slot at interval "<< *cur << ":\n");
404
Chris Lattner5e5fb942005-01-08 19:53:50 +0000405 float minWeight = (float)HUGE_VAL;
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000406 unsigned minReg = 0;
407 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
Chris Lattner5b210342004-12-15 07:04:32 +0000408 for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_),
409 e = rc->allocation_order_end(*mf_); i != e; ++i) {
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000410 unsigned reg = *i;
411 if (minWeight > spillWeights_[reg]) {
412 minWeight = spillWeights_[reg];
413 minReg = reg;
414 }
415 }
416 DEBUG(std::cerr << "\t\tregister with min weight: "
417 << mri_->getName(minReg) << " (" << minWeight << ")\n");
418
419 // if the current has the minimum weight, we spill it and move on
420 if (cur->weight <= minWeight) {
421 DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n');
422 spilled_.push_back(cur);
423 return;
424 }
425
426 // otherwise we spill all intervals aliasing the register with
427 // minimum weight, assigned the newly cleared register to the
428 // current interval and continue
429 assert(MRegisterInfo::isPhysicalRegister(minReg) &&
430 "did not choose a register to spill?");
431 std::vector<bool> toSpill(mri_->getNumRegs(), false);
432 toSpill[minReg] = true;
433 for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
434 toSpill[*as] = true;
Chris Lattner23b71c12004-11-18 01:29:39 +0000435 unsigned earliestStart = cur->beginNumber();
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000436
437 std::set<unsigned> spilled;
438
439 for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ) {
440 unsigned reg = (*i)->reg;
441 if (MRegisterInfo::isVirtualRegister(reg) &&
442 toSpill[vrm_->getPhys(reg)] &&
443 cur->overlaps(**i)) {
444 DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n');
445 spilled_.push_back(*i);
446 prt_->delRegUse(vrm_->getPhys(reg));
447 vrm_->clearVirt(reg);
448 i = active_.erase(i);
449 }
450 else
451 ++i;
452 }
453 for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end(); ) {
454 unsigned reg = (*i)->reg;
455 if (MRegisterInfo::isVirtualRegister(reg) &&
456 toSpill[vrm_->getPhys(reg)] &&
457 cur->overlaps(**i)) {
458 DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n');
459 spilled_.push_back(*i);
460 vrm_->clearVirt(reg);
461 i = inactive_.erase(i);
462 }
463 else
464 ++i;
465 }
466
467 vrm_->assignVirt2Phys(cur->reg, minReg);
468 prt_->addRegUse(minReg);
469 active_.push_back(cur);
470 handled_.push_back(cur);
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000471
472}
473
Alkis Evlogimenos70619fa2004-09-02 21:24:33 +0000474unsigned RA::getFreePhysReg(LiveInterval* cur)
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000475{
Alkis Evlogimenos70619fa2004-09-02 21:24:33 +0000476 std::vector<unsigned> inactiveCounts(mri_->getNumRegs(), 0);
477 for (IntervalPtrs::iterator i = inactive_.begin(), e = inactive_.end();
478 i != e; ++i) {
479 unsigned reg = (*i)->reg;
480 if (MRegisterInfo::isVirtualRegister(reg))
481 reg = vrm_->getPhys(reg);
482 ++inactiveCounts[reg];
483 }
484
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000485 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000486
Alkis Evlogimenos70619fa2004-09-02 21:24:33 +0000487 unsigned freeReg = 0;
Chris Lattner5b210342004-12-15 07:04:32 +0000488 for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_),
489 e = rc->allocation_order_end(*mf_); i != e; ++i) {
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000490 unsigned reg = *i;
Alkis Evlogimenos70619fa2004-09-02 21:24:33 +0000491 if (prt_->isRegAvail(reg) &&
492 (!freeReg || inactiveCounts[freeReg] < inactiveCounts[reg]))
493 freeReg = reg;
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000494 }
Alkis Evlogimenos70619fa2004-09-02 21:24:33 +0000495 return freeReg;
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000496}
497
498FunctionPass* llvm::createIterativeScanRegisterAllocator() {
Alkis Evlogimenos1a8ea012004-08-04 09:46:26 +0000499 return new RA();
Alkis Evlogimenos910d0d62004-07-21 08:24:35 +0000500}