blob: 69c3120275e9486190094b44a500643aa96f8ccc [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 Evlogimenose88280a2004-01-22 23:08:45 +000035 Statistic<> numPeep ("ra-linearscan",
36 "Number of identity moves eliminated");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000037
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +000038 class PhysRegTracker {
39 private:
40 const MRegisterInfo* mri_;
41 std::vector<bool> reserved_;
42 std::vector<unsigned> regUse_;
43
44 public:
45 PhysRegTracker(MachineFunction* mf)
46 : mri_(mf ? mf->getTarget().getRegisterInfo() : NULL) {
47 if (mri_) {
48 reserved_.assign(mri_->getNumRegs(), false);
49 regUse_.assign(mri_->getNumRegs(), 0);
50 }
51 }
52
53 PhysRegTracker(const PhysRegTracker& rhs)
54 : mri_(rhs.mri_),
55 reserved_(rhs.reserved_),
56 regUse_(rhs.regUse_) {
57 }
58
59 const PhysRegTracker& operator=(const PhysRegTracker& rhs) {
60 mri_ = rhs.mri_;
61 reserved_ = rhs.reserved_;
62 regUse_ = rhs.regUse_;
63 return *this;
64 }
65
66 void reservePhysReg(unsigned physReg) {
67 reserved_[physReg] = true;
68 }
69
70 void addPhysRegUse(unsigned physReg) {
71 ++regUse_[physReg];
72 for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as) {
73 physReg = *as;
74 ++regUse_[physReg];
75 }
76 }
77
78 void delPhysRegUse(unsigned physReg) {
79 assert(regUse_[physReg] != 0);
80 --regUse_[physReg];
81 for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as) {
82 physReg = *as;
83 assert(regUse_[physReg] != 0);
84 --regUse_[physReg];
85 }
86 }
87
88 bool isPhysRegReserved(unsigned physReg) const {
89 return reserved_[physReg];
90 }
91
92 bool isPhysRegAvail(unsigned physReg) const {
93 return regUse_[physReg] == 0 && !isPhysRegReserved(physReg);
94 }
95
96 bool isReservedPhysRegAvail(unsigned physReg) const {
97 return regUse_[physReg] == 0 && isPhysRegReserved(physReg);
98 }
99 };
100
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000101 class RA : public MachineFunctionPass {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000102 private:
103 MachineFunction* mf_;
104 const TargetMachine* tm_;
105 const MRegisterInfo* mri_;
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000106 LiveIntervals* li_;
Alkis Evlogimenos1283d862004-01-07 05:31:12 +0000107 MachineFunction::iterator currentMbb_;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000108 MachineBasicBlock::iterator currentInstr_;
Alkis Evlogimenos1283d862004-01-07 05:31:12 +0000109 typedef std::vector<const LiveIntervals::Interval*> IntervalPtrs;
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000110 IntervalPtrs unhandled_, fixed_, active_, inactive_;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000111
112 typedef std::vector<unsigned> Regs;
113 Regs tempUseOperands_;
114 Regs tempDefOperands_;
115
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000116 PhysRegTracker prt_;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000117
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000118 typedef std::map<unsigned, unsigned> Virt2PhysMap;
119 Virt2PhysMap v2pMap_;
120
121 typedef std::map<unsigned, int> Virt2StackSlotMap;
122 Virt2StackSlotMap v2ssMap_;
123
124 int instrAdded_;
125
126 public:
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000127 RA()
128 : prt_(NULL) {
129
130 }
131
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000132 virtual const char* getPassName() const {
133 return "Linear Scan Register Allocator";
134 }
135
136 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
137 AU.addRequired<LiveVariables>();
138 AU.addRequired<LiveIntervals>();
139 MachineFunctionPass::getAnalysisUsage(AU);
140 }
141
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000142 /// runOnMachineFunction - register allocate the whole function
143 bool runOnMachineFunction(MachineFunction&);
144
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000145 void releaseMemory();
146
147 private:
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000148 /// initIntervalSets - initializa the four interval sets:
149 /// unhandled, fixed, active and inactive
150 void initIntervalSets(const LiveIntervals::Intervals& li);
151
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000152 /// processActiveIntervals - expire old intervals and move
153 /// non-overlapping ones to the incative list
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000154 void processActiveIntervals(IntervalPtrs::value_type cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000155
156 /// processInactiveIntervals - expire old intervals and move
157 /// overlapping ones to the active list
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000158 void processInactiveIntervals(IntervalPtrs::value_type cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000159
160 /// assignStackSlotAtInterval - choose and spill
161 /// interval. Currently we spill the interval with the last
162 /// end point in the active and inactive lists and the current
163 /// interval
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000164 void assignStackSlotAtInterval(IntervalPtrs::value_type cur,
165 const PhysRegTracker& backupPtr);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000166
167 ///
168 /// register handling helpers
169 ///
170
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000171 /// getFreePhysReg - return a free physical register for this
172 /// virtual register interval if we have one, otherwise return
173 /// 0
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000174 unsigned getFreePhysReg(IntervalPtrs::value_type cur);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000175
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000176 /// getFreeTempPhysReg - return a free temprorary physical
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000177 /// register for this virtual register if we have one (should
178 /// never return 0)
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000179 unsigned getFreeTempPhysReg(unsigned virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000180
181 /// assignVirt2PhysReg - assigns the free physical register to
182 /// the virtual register passed as arguments
183 void assignVirt2PhysReg(unsigned virtReg, unsigned physReg);
184
185 /// clearVirtReg - free the physical register associated with this
186 /// virtual register and disassociate virtual->physical and
187 /// physical->virtual mappings
188 void clearVirtReg(unsigned virtReg);
189
190 /// assignVirt2StackSlot - assigns this virtual register to a
191 /// stack slot
192 void assignVirt2StackSlot(unsigned virtReg);
193
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000194 /// getStackSlot - returns the offset of the specified
195 /// register on the stack
196 int getStackSlot(unsigned virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000197
198 /// spillVirtReg - spills the virtual register
199 void spillVirtReg(unsigned virtReg);
200
201 /// loadPhysReg - loads to the physical register the value of
202 /// the virtual register specifed. Virtual register must have
203 /// an assigned stack slot
204 void loadVirt2PhysReg(unsigned virtReg, unsigned physReg);
205
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000206 void printVirtRegAssignment() const {
207 std::cerr << "register assignment:\n";
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000208
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000209 for (Virt2PhysMap::const_iterator
210 i = v2pMap_.begin(), e = v2pMap_.end(); i != e; ++i) {
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000211 assert(i->second != 0);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000212 std::cerr << '[' << i->first << ','
213 << mri_->getName(i->second) << "]\n";
214 }
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000215 for (Virt2StackSlotMap::const_iterator
216 i = v2ssMap_.begin(), e = v2ssMap_.end(); i != e; ++i) {
217 std::cerr << '[' << i->first << ",ss#" << i->second << "]\n";
218 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000219 std::cerr << '\n';
220 }
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000221
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000222 void printIntervals(const char* const str,
223 RA::IntervalPtrs::const_iterator i,
224 RA::IntervalPtrs::const_iterator e) const {
225 if (str) std::cerr << str << " intervals:\n";
226 for (; i != e; ++i) {
227 std::cerr << "\t\t" << **i << " -> ";
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000228 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000229 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000230 Virt2PhysMap::const_iterator it = v2pMap_.find(reg);
231 reg = (it == v2pMap_.end() ? 0 : it->second);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000232 }
Alkis Evlogimenosa12c7bb2004-01-16 20:33:13 +0000233 std::cerr << mri_->getName(reg) << '\n';
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000234 }
235 }
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000236
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000237// void printFreeRegs(const char* const str,
238// const TargetRegisterClass* rc) const {
239// if (str) std::cerr << str << ':';
240// for (TargetRegisterClass::iterator i =
241// rc->allocation_order_begin(*mf_);
242// i != rc->allocation_order_end(*mf_); ++i) {
243// unsigned reg = *i;
244// if (!regUse_[reg]) {
245// std::cerr << ' ' << mri_->getName(reg);
246// if (reserved_[reg]) std::cerr << "*";
247// }
248// }
249// std::cerr << '\n';
250// }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000251 };
252}
253
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000254void RA::releaseMemory()
255{
256 v2pMap_.clear();
257 v2ssMap_.clear();
258 unhandled_.clear();
259 active_.clear();
260 inactive_.clear();
261 fixed_.clear();
262
263}
264
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000265bool RA::runOnMachineFunction(MachineFunction &fn) {
266 mf_ = &fn;
267 tm_ = &fn.getTarget();
268 mri_ = tm_->getRegisterInfo();
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000269 li_ = &getAnalysis<LiveIntervals>();
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000270 prt_ = PhysRegTracker(mf_);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000271
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000272 initIntervalSets(li_->getIntervals());
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000273
274 // FIXME: this will work only for the X86 backend. I need to
275 // device an algorthm to select the minimal (considering register
276 // aliasing) number of temp registers to reserve so that we have 2
277 // registers for each register class available.
278
Alkis Evlogimenos27490a62003-12-28 18:03:52 +0000279 // reserve R8: CH, CL
280 // R16: CX, DI,
281 // R32: ECX, EDI,
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000282 // RFP: FP5, FP6
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000283 prt_.reservePhysReg( 8); /* CH */
284 prt_.reservePhysReg( 9); /* CL */
285 prt_.reservePhysReg(10); /* CX */
286 prt_.reservePhysReg(12); /* DI */
287 prt_.reservePhysReg(18); /* ECX */
288 prt_.reservePhysReg(19); /* EDI */
289 prt_.reservePhysReg(28); /* FP5 */
290 prt_.reservePhysReg(29); /* FP6 */
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000291
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000292 // linear scan algorithm
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000293 DEBUG(std::cerr << "Machine Function\n");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000294
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000295 DEBUG(printIntervals("\tunhandled", unhandled_.begin(), unhandled_.end()));
296 DEBUG(printIntervals("\tfixed", fixed_.begin(), fixed_.end()));
297 DEBUG(printIntervals("\tactive", active_.begin(), active_.end()));
298 DEBUG(printIntervals("\tinactive", inactive_.begin(), inactive_.end()));
299
300 while (!unhandled_.empty() || !fixed_.empty()) {
301 // pick the interval with the earliest start point
302 IntervalPtrs::value_type cur;
303 if (fixed_.empty()) {
304 cur = unhandled_.front();
305 unhandled_.erase(unhandled_.begin());
306 }
307 else if (unhandled_.empty()) {
308 cur = fixed_.front();
309 fixed_.erase(fixed_.begin());
310 }
311 else if (unhandled_.front()->start() < fixed_.front()->start()) {
312 cur = unhandled_.front();
313 unhandled_.erase(unhandled_.begin());
314 }
315 else {
316 cur = fixed_.front();
317 fixed_.erase(fixed_.begin());
318 }
319
Alkis Evlogimenos5ab20272004-01-14 00:09:36 +0000320 DEBUG(std::cerr << *cur << '\n');
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000321
322 processActiveIntervals(cur);
323 processInactiveIntervals(cur);
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000324
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000325 // if this register is fixed we are done
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000326 if (MRegisterInfo::isPhysicalRegister(cur->reg)) {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000327 prt_.addPhysRegUse(cur->reg);
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000328 active_.push_back(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000329 }
330 // otherwise we are allocating a virtual register. try to find
331 // a free physical register or spill an interval in order to
332 // assign it one (we could spill the current though).
333 else {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000334 PhysRegTracker backupPrt = prt_;
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000335
336 // for every interval in inactive we overlap with, mark the
337 // register as not free
338 for (IntervalPtrs::const_iterator i = inactive_.begin(),
339 e = inactive_.end(); i != e; ++i) {
340 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000341 if (MRegisterInfo::isVirtualRegister(reg))
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000342 reg = v2pMap_[reg];
343
344 if (cur->overlaps(**i)) {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000345 prt_.addPhysRegUse(reg);
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000346 }
347 }
348
349 // for every interval in fixed we overlap with,
350 // mark the register as not free
351 for (IntervalPtrs::const_iterator i = fixed_.begin(),
352 e = fixed_.end(); i != e; ++i) {
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000353 assert(MRegisterInfo::isPhysicalRegister((*i)->reg) &&
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000354 "virtual register interval in fixed set?");
355 if (cur->overlaps(**i))
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000356 prt_.addPhysRegUse((*i)->reg);
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000357 }
358
359 DEBUG(std::cerr << "\tallocating current interval:\n");
360
361 unsigned physReg = getFreePhysReg(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000362 if (!physReg) {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000363 assignStackSlotAtInterval(cur, backupPrt);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000364 }
365 else {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000366 prt_ = backupPrt;
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000367 assignVirt2PhysReg(cur->reg, physReg);
368 active_.push_back(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000369 }
370 }
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000371
372 DEBUG(printIntervals("\tactive", active_.begin(), active_.end()));
373 DEBUG(printIntervals("\tinactive", inactive_.begin(), inactive_.end())); }
374
Alkis Evlogimenos7d65a122003-12-13 05:50:19 +0000375 // expire any remaining active intervals
376 for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) {
377 unsigned reg = (*i)->reg;
378 DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000379 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000380 reg = v2pMap_[reg];
Alkis Evlogimenos7d65a122003-12-13 05:50:19 +0000381 }
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000382 prt_.delPhysRegUse(reg);
Alkis Evlogimenos7d65a122003-12-13 05:50:19 +0000383 }
Alkis Evlogimenos4d7af652003-12-14 13:24:17 +0000384
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000385 typedef LiveIntervals::Reg2RegMap Reg2RegMap;
386 const Reg2RegMap& r2rMap = li_->getJoinedRegMap();
387
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000388 DEBUG(printVirtRegAssignment());
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000389 DEBUG(std::cerr << "Performing coalescing on joined intervals\n");
390 // perform coalescing if we were passed joined intervals
391 for(Reg2RegMap::const_iterator i = r2rMap.begin(), e = r2rMap.end();
392 i != e; ++i) {
393 unsigned reg = i->first;
394 unsigned rep = li_->rep(reg);
395
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000396 assert((MRegisterInfo::isPhysicalRegister(rep) ||
Alkis Evlogimenosf440cc12004-02-01 18:39:53 +0000397 v2pMap_.count(rep) || v2ssMap_.count(rep)) &&
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000398 "representative register is not allocated!");
399
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000400 assert(MRegisterInfo::isVirtualRegister(reg) &&
Alkis Evlogimenosf440cc12004-02-01 18:39:53 +0000401 !v2pMap_.count(reg) && !v2ssMap_.count(reg) &&
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000402 "coalesced register is already allocated!");
403
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000404 if (MRegisterInfo::isPhysicalRegister(rep)) {
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000405 v2pMap_.insert(std::make_pair(reg, rep));
406 }
407 else {
408 Virt2PhysMap::const_iterator pr = v2pMap_.find(rep);
409 if (pr != v2pMap_.end()) {
410 v2pMap_.insert(std::make_pair(reg, pr->second));
411 }
412 else {
413 Virt2StackSlotMap::const_iterator ss = v2ssMap_.find(rep);
414 assert(ss != v2ssMap_.end());
415 v2ssMap_.insert(std::make_pair(reg, ss->second));
416 }
417 }
418 }
419
420 DEBUG(printVirtRegAssignment());
421 DEBUG(std::cerr << "finished register allocation\n");
422
423 const TargetInstrInfo& tii = tm_->getInstrInfo();
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000424
425 DEBUG(std::cerr << "Rewrite machine code:\n");
Alkis Evlogimenos1283d862004-01-07 05:31:12 +0000426 for (currentMbb_ = mf_->begin(); currentMbb_ != mf_->end(); ++currentMbb_) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000427 instrAdded_ = 0;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000428
429 for (currentInstr_ = currentMbb_->begin();
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000430 currentInstr_ != currentMbb_->end(); ) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000431
432 DEBUG(std::cerr << "\tinstruction: ";
433 (*currentInstr_)->print(std::cerr, *tm_););
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000434
435 // use our current mapping and actually replace and
436 // virtual register with its allocated physical registers
437 DEBUG(std::cerr << "\t\treplacing virtual registers with mapped "
438 "physical registers:\n");
439 for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
440 i != e; ++i) {
441 MachineOperand& op = (*currentInstr_)->getOperand(i);
442 if (op.isVirtualRegister()) {
443 unsigned virtReg = op.getAllocatedRegNum();
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000444 Virt2PhysMap::const_iterator it = v2pMap_.find(virtReg);
445 if (it != v2pMap_.end()) {
446 DEBUG(std::cerr << "\t\t\t%reg" << it->second
447 << " -> " << mri_->getName(it->second) << '\n');
448 (*currentInstr_)->SetMachineOperandReg(i, it->second);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000449 }
450 }
451 }
452
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000453 unsigned srcReg, dstReg;
454 if (tii.isMoveInstr(**currentInstr_, srcReg, dstReg) &&
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000455 ((MRegisterInfo::isPhysicalRegister(srcReg) &&
456 MRegisterInfo::isPhysicalRegister(dstReg) &&
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000457 srcReg == dstReg) ||
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000458 (MRegisterInfo::isVirtualRegister(srcReg) &&
459 MRegisterInfo::isVirtualRegister(dstReg) &&
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000460 v2ssMap_[srcReg] == v2ssMap_[dstReg]))) {
461 delete *currentInstr_;
462 currentInstr_ = currentMbb_->erase(currentInstr_);
463 ++numPeep;
464 DEBUG(std::cerr << "\t\tdeleting instruction\n");
465 continue;
466 }
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000467
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000468 DEBUG(std::cerr << "\t\tloading temporarily used operands to "
469 "registers:\n");
470 for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
471 i != e; ++i) {
472 MachineOperand& op = (*currentInstr_)->getOperand(i);
Alkis Evlogimenosa71e05a2003-12-18 13:15:02 +0000473 if (op.isVirtualRegister() && op.isUse() && !op.isDef()) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000474 unsigned virtReg = op.getAllocatedRegNum();
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000475 unsigned physReg = 0;
476 Virt2PhysMap::const_iterator it = v2pMap_.find(virtReg);
477 if (it != v2pMap_.end()) {
478 physReg = it->second;
479 }
480 else {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000481 physReg = getFreeTempPhysReg(virtReg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000482 loadVirt2PhysReg(virtReg, physReg);
483 tempUseOperands_.push_back(virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000484 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000485 (*currentInstr_)->SetMachineOperandReg(i, physReg);
486 }
487 }
488
489 DEBUG(std::cerr << "\t\tclearing temporarily used operands:\n");
490 for (unsigned i = 0, e = tempUseOperands_.size(); i != e; ++i) {
491 clearVirtReg(tempUseOperands_[i]);
492 }
493 tempUseOperands_.clear();
494
495 DEBUG(std::cerr << "\t\tassigning temporarily defined operands to "
496 "registers:\n");
497 for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
498 i != e; ++i) {
499 MachineOperand& op = (*currentInstr_)->getOperand(i);
Alkis Evlogimenos4d7af652003-12-14 13:24:17 +0000500 if (op.isVirtualRegister() && op.isDef()) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000501 unsigned virtReg = op.getAllocatedRegNum();
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000502 unsigned physReg = 0;
503 Virt2PhysMap::const_iterator it = v2pMap_.find(virtReg);
504 if (it != v2pMap_.end()) {
505 physReg = it->second;
506 }
507 else {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000508 physReg = getFreeTempPhysReg(virtReg);
509 }
Alkis Evlogimenos4d7af652003-12-14 13:24:17 +0000510 if (op.isUse()) { // def and use
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000511 loadVirt2PhysReg(virtReg, physReg);
512 }
513 else {
514 assignVirt2PhysReg(virtReg, physReg);
515 }
516 tempDefOperands_.push_back(virtReg);
517 (*currentInstr_)->SetMachineOperandReg(i, physReg);
518 }
519 }
520
Alkis Evlogimenos58587072003-11-30 23:40:39 +0000521 DEBUG(std::cerr << "\t\tspilling temporarily defined operands "
522 "of this instruction:\n");
523 ++currentInstr_; // we want to insert after this instruction
524 for (unsigned i = 0, e = tempDefOperands_.size(); i != e; ++i) {
525 spillVirtReg(tempDefOperands_[i]);
526 }
527 --currentInstr_; // restore currentInstr_ iterator
528 tempDefOperands_.clear();
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000529 ++currentInstr_;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000530 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000531 }
532
533 return true;
534}
535
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000536void RA::initIntervalSets(const LiveIntervals::Intervals& li)
537{
538 assert(unhandled_.empty() && fixed_.empty() &&
539 active_.empty() && inactive_.empty() &&
540 "interval sets should be empty on initialization");
541
542 for (LiveIntervals::Intervals::const_iterator i = li.begin(), e = li.end();
543 i != e; ++i) {
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000544 if (MRegisterInfo::isPhysicalRegister(i->reg))
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000545 fixed_.push_back(&*i);
546 else
547 unhandled_.push_back(&*i);
548 }
549}
550
551void RA::processActiveIntervals(IntervalPtrs::value_type cur)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000552{
553 DEBUG(std::cerr << "\tprocessing active intervals:\n");
554 for (IntervalPtrs::iterator i = active_.begin(); i != active_.end();) {
555 unsigned reg = (*i)->reg;
Alkis Evlogimenos3b02cbe2004-01-16 20:17:05 +0000556 // remove expired intervals
557 if ((*i)->expiredAt(cur->start())) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000558 DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000559 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000560 reg = v2pMap_[reg];
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000561 }
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000562 prt_.delPhysRegUse(reg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000563 // remove from active
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000564 i = active_.erase(i);
565 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000566 // move inactive intervals to inactive list
567 else if (!(*i)->liveAt(cur->start())) {
568 DEBUG(std::cerr << "\t\t\tinterval " << **i << " inactive\n");
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000569 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000570 reg = v2pMap_[reg];
571 }
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000572 prt_.delPhysRegUse(reg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000573 // add to inactive
574 inactive_.push_back(*i);
575 // remove from active
576 i = active_.erase(i);
577 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000578 else {
579 ++i;
580 }
581 }
582}
583
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000584void RA::processInactiveIntervals(IntervalPtrs::value_type cur)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000585{
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000586 DEBUG(std::cerr << "\tprocessing inactive intervals:\n");
587 for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end();) {
588 unsigned reg = (*i)->reg;
589
Alkis Evlogimenos3b02cbe2004-01-16 20:17:05 +0000590 // remove expired intervals
591 if ((*i)->expiredAt(cur->start())) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000592 DEBUG(std::cerr << "\t\t\tinterval " << **i << " expired\n");
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000593 // remove from inactive
594 i = inactive_.erase(i);
595 }
596 // move re-activated intervals in active list
597 else if ((*i)->liveAt(cur->start())) {
598 DEBUG(std::cerr << "\t\t\tinterval " << **i << " active\n");
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000599 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000600 reg = v2pMap_[reg];
601 }
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000602 prt_.addPhysRegUse(reg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000603 // add to active
604 active_.push_back(*i);
605 // remove from inactive
606 i = inactive_.erase(i);
607 }
608 else {
609 ++i;
610 }
611 }
612}
613
614namespace {
Alkis Evlogimenos6b4edba2003-12-21 20:19:10 +0000615 template <typename T>
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000616 void updateWeight(std::vector<T>& rw, int reg, T w)
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000617 {
Alkis Evlogimenos6b4edba2003-12-21 20:19:10 +0000618 if (rw[reg] == std::numeric_limits<T>::max() ||
619 w == std::numeric_limits<T>::max())
620 rw[reg] = std::numeric_limits<T>::max();
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000621 else
622 rw[reg] += w;
623 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000624}
625
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000626void RA::assignStackSlotAtInterval(IntervalPtrs::value_type cur,
627 const PhysRegTracker& backupPrt)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000628{
629 DEBUG(std::cerr << "\t\tassigning stack slot at interval "
630 << *cur << ":\n");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000631
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000632 std::vector<float> regWeight(mri_->getNumRegs(), 0.0);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000633
Alkis Evlogimenos84dc5fb2004-01-22 20:07:18 +0000634 // for each interval in active
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000635 for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
636 i != e; ++i) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000637 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000638 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000639 reg = v2pMap_[reg];
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000640 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000641 updateWeight(regWeight, reg, (*i)->weight);
642 for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
643 updateWeight(regWeight, *as, (*i)->weight);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000644 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000645
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000646 // for each interval in inactive that overlaps
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000647 for (IntervalPtrs::const_iterator i = inactive_.begin(),
648 e = inactive_.end(); i != e; ++i) {
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000649 if (!cur->overlaps(**i))
650 continue;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000651
652 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000653 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000654 reg = v2pMap_[reg];
655 }
656 updateWeight(regWeight, reg, (*i)->weight);
657 for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
658 updateWeight(regWeight, *as, (*i)->weight);
659 }
660
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000661 // for each fixed interval that overlaps
662 for (IntervalPtrs::const_iterator i = fixed_.begin(), e = fixed_.end();
663 i != e; ++i) {
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000664 if (!cur->overlaps(**i))
665 continue;
Alkis Evlogimenosf7df173e2004-01-13 20:37:01 +0000666
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000667 assert(MRegisterInfo::isPhysicalRegister((*i)->reg) &&
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000668 "virtual register interval in fixed set?");
669 updateWeight(regWeight, (*i)->reg, (*i)->weight);
670 for (const unsigned* as = mri_->getAliasSet((*i)->reg); *as; ++as)
671 updateWeight(regWeight, *as, (*i)->weight);
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000672 }
673
Alkis Evlogimenos6b4edba2003-12-21 20:19:10 +0000674 float minWeight = std::numeric_limits<float>::max();
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000675 unsigned minReg = 0;
676 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
677 for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
678 i != rc->allocation_order_end(*mf_); ++i) {
679 unsigned reg = *i;
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000680 if (!prt_.isPhysRegReserved(reg) && minWeight > regWeight[reg]) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000681 minWeight = regWeight[reg];
682 minReg = reg;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000683 }
684 }
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000685 DEBUG(std::cerr << "\t\t\tregister with min weight: "
686 << mri_->getName(minReg) << " (" << minWeight << ")\n");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000687
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000688 if (cur->weight < minWeight) {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000689 prt_ = backupPrt;
Alkis Evlogimenos5ab20272004-01-14 00:09:36 +0000690 DEBUG(std::cerr << "\t\t\t\tspilling: " << *cur << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000691 assignVirt2StackSlot(cur->reg);
692 }
693 else {
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000694 std::vector<bool> toSpill(mri_->getNumRegs(), false);
695 toSpill[minReg] = true;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000696 for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000697 toSpill[*as] = true;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000698
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000699 std::vector<unsigned> spilled;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000700 for (IntervalPtrs::iterator i = active_.begin();
701 i != active_.end(); ) {
702 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000703 if (MRegisterInfo::isVirtualRegister(reg) &&
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000704 toSpill[v2pMap_[reg]] &&
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000705 cur->overlaps(**i)) {
706 spilled.push_back(v2pMap_[reg]);
Alkis Evlogimenos843397c2003-12-24 18:53:31 +0000707 DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000708 assignVirt2StackSlot(reg);
709 i = active_.erase(i);
710 }
711 else {
712 ++i;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000713 }
714 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000715 for (IntervalPtrs::iterator i = inactive_.begin();
716 i != inactive_.end(); ) {
717 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000718 if (MRegisterInfo::isVirtualRegister(reg) &&
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000719 toSpill[v2pMap_[reg]] &&
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000720 cur->overlaps(**i)) {
Alkis Evlogimenos843397c2003-12-24 18:53:31 +0000721 DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000722 assignVirt2StackSlot(reg);
723 i = inactive_.erase(i);
724 }
725 else {
726 ++i;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000727 }
728 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000729
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000730 unsigned physReg = getFreePhysReg(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000731 assert(physReg && "no free physical register after spill?");
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000732
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000733 prt_ = backupPrt;
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000734 for (unsigned i = 0; i < spilled.size(); ++i)
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000735 prt_.delPhysRegUse(spilled[i]);
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000736
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000737 assignVirt2PhysReg(cur->reg, physReg);
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000738 active_.push_back(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000739 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000740}
741
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000742unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur)
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000743{
744 DEBUG(std::cerr << "\t\tgetting free physical register: ");
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000745 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
Alkis Evlogimenos26bfc082003-12-28 17:58:18 +0000746
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000747 for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
748 i != rc->allocation_order_end(*mf_); ++i) {
749 unsigned reg = *i;
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000750 if (prt_.isPhysRegAvail(reg)) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000751 DEBUG(std::cerr << mri_->getName(reg) << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000752 return reg;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000753 }
754 }
755
756 DEBUG(std::cerr << "no free register\n");
757 return 0;
758}
759
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000760unsigned RA::getFreeTempPhysReg(unsigned virtReg)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000761{
762 DEBUG(std::cerr << "\t\tgetting free temporary physical register: ");
763
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000764 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
765 // go in reverse allocation order for the temp registers
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000766 typedef std::reverse_iterator<TargetRegisterClass::iterator> TRCRevIter;
767 for (TRCRevIter
768 i(rc->allocation_order_end(*mf_)),
769 e(rc->allocation_order_begin(*mf_)); i != e; ++i) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000770 unsigned reg = *i;
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000771 if (prt_.isReservedPhysRegAvail(reg)) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000772 DEBUG(std::cerr << mri_->getName(reg) << '\n');
773 return reg;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000774 }
775 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000776
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000777 assert(0 && "no free temporary physical register?");
778 return 0;
779}
780
781void RA::assignVirt2PhysReg(unsigned virtReg, unsigned physReg)
782{
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000783 bool inserted = v2pMap_.insert(std::make_pair(virtReg, physReg)).second;
784 assert(inserted && "attempting to assign a virt->phys mapping to an "
785 "already mapped register");
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000786 prt_.addPhysRegUse(physReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000787}
788
789void RA::clearVirtReg(unsigned virtReg)
790{
791 Virt2PhysMap::iterator it = v2pMap_.find(virtReg);
792 assert(it != v2pMap_.end() &&
793 "attempting to clear a not allocated virtual register");
794 unsigned physReg = it->second;
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000795 prt_.delPhysRegUse(physReg);
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000796 v2pMap_.erase(it);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000797 DEBUG(std::cerr << "\t\t\tcleared register " << mri_->getName(physReg)
798 << "\n");
799}
800
801void RA::assignVirt2StackSlot(unsigned virtReg)
802{
803 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
804 int frameIndex = mf_->getFrameInfo()->CreateStackObject(rc);
805
806 bool inserted = v2ssMap_.insert(std::make_pair(virtReg, frameIndex)).second;
807 assert(inserted &&
808 "attempt to assign stack slot to already assigned register?");
809 // if the virtual register was previously assigned clear the mapping
810 // and free the virtual register
Alkis Evlogimenosf440cc12004-02-01 18:39:53 +0000811 if (v2pMap_.count(virtReg)) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000812 clearVirtReg(virtReg);
813 }
814}
815
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000816int RA::getStackSlot(unsigned virtReg)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000817{
818 // use lower_bound so that we can do a possibly O(1) insert later
819 // if necessary
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000820 Virt2StackSlotMap::iterator it = v2ssMap_.find(virtReg);
821 assert(it != v2ssMap_.end() &&
822 "attempt to get stack slot on register that does not live on the stack");
823 return it->second;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000824}
825
826void RA::spillVirtReg(unsigned virtReg)
827{
828 DEBUG(std::cerr << "\t\t\tspilling register: " << virtReg);
829 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000830 int frameIndex = getStackSlot(virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000831 DEBUG(std::cerr << " to stack slot #" << frameIndex << '\n');
832 ++numSpilled;
833 instrAdded_ += mri_->storeRegToStackSlot(*currentMbb_, currentInstr_,
834 v2pMap_[virtReg], frameIndex, rc);
835 clearVirtReg(virtReg);
836}
837
838void RA::loadVirt2PhysReg(unsigned virtReg, unsigned physReg)
839{
840 DEBUG(std::cerr << "\t\t\tloading register: " << virtReg);
841 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000842 int frameIndex = getStackSlot(virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000843 DEBUG(std::cerr << " from stack slot #" << frameIndex << '\n');
Chris Lattner5e46b512003-12-18 20:25:31 +0000844 ++numReloaded;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000845 instrAdded_ += mri_->loadRegFromStackSlot(*currentMbb_, currentInstr_,
846 physReg, frameIndex, rc);
847 assignVirt2PhysReg(virtReg, physReg);
848}
849
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000850FunctionPass* llvm::createLinearScanRegisterAllocator() {
851 return new RA();
852}