blob: e94e341324549271372a1f9aeee1f0122d263a92 [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
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000112 PhysRegTracker prt_;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000113
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000114 typedef std::map<unsigned, unsigned> Virt2PhysMap;
115 Virt2PhysMap v2pMap_;
116
117 typedef std::map<unsigned, int> Virt2StackSlotMap;
118 Virt2StackSlotMap v2ssMap_;
119
120 int instrAdded_;
121
122 public:
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000123 RA()
124 : prt_(NULL) {
125
126 }
127
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000128 virtual const char* getPassName() const {
129 return "Linear Scan Register Allocator";
130 }
131
132 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
133 AU.addRequired<LiveVariables>();
134 AU.addRequired<LiveIntervals>();
135 MachineFunctionPass::getAnalysisUsage(AU);
136 }
137
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000138 /// runOnMachineFunction - register allocate the whole function
139 bool runOnMachineFunction(MachineFunction&);
140
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000141 void releaseMemory();
142
143 private:
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000144 /// initIntervalSets - initializa the four interval sets:
145 /// unhandled, fixed, active and inactive
146 void initIntervalSets(const LiveIntervals::Intervals& li);
147
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000148 /// processActiveIntervals - expire old intervals and move
149 /// non-overlapping ones to the incative list
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000150 void processActiveIntervals(IntervalPtrs::value_type cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000151
152 /// processInactiveIntervals - expire old intervals and move
153 /// overlapping ones to the active list
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000154 void processInactiveIntervals(IntervalPtrs::value_type cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000155
156 /// assignStackSlotAtInterval - choose and spill
157 /// interval. Currently we spill the interval with the last
158 /// end point in the active and inactive lists and the current
159 /// interval
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000160 void assignStackSlotAtInterval(IntervalPtrs::value_type cur,
161 const PhysRegTracker& backupPtr);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000162
163 ///
164 /// register handling helpers
165 ///
166
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000167 /// getFreePhysReg - return a free physical register for this
168 /// virtual register interval if we have one, otherwise return
169 /// 0
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000170 unsigned getFreePhysReg(IntervalPtrs::value_type cur);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000171
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000172 /// getFreeTempPhysReg - return a free temprorary physical
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000173 /// register for this virtual register if we have one (should
174 /// never return 0)
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000175 unsigned getFreeTempPhysReg(unsigned virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000176
177 /// assignVirt2PhysReg - assigns the free physical register to
178 /// the virtual register passed as arguments
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000179 Virt2PhysMap::iterator
180 assignVirt2PhysReg(unsigned virtReg, unsigned physReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000181
182 /// clearVirtReg - free the physical register associated with this
183 /// virtual register and disassociate virtual->physical and
184 /// physical->virtual mappings
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000185 void clearVirtReg(Virt2PhysMap::iterator it);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000186
187 /// assignVirt2StackSlot - assigns this virtual register to a
188 /// stack slot
189 void assignVirt2StackSlot(unsigned virtReg);
190
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000191 /// getStackSlot - returns the offset of the specified
192 /// register on the stack
193 int getStackSlot(unsigned virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000194
195 /// spillVirtReg - spills the virtual register
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000196 void spillVirtReg(Virt2PhysMap::iterator it);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000197
198 /// loadPhysReg - loads to the physical register the value of
199 /// the virtual register specifed. Virtual register must have
200 /// an assigned stack slot
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000201 Virt2PhysMap::iterator
202 loadVirt2PhysReg(unsigned virtReg, unsigned physReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000203
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000204 void printVirtRegAssignment() const {
205 std::cerr << "register assignment:\n";
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000206
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000207 for (Virt2PhysMap::const_iterator
208 i = v2pMap_.begin(), e = v2pMap_.end(); i != e; ++i) {
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000209 assert(i->second != 0);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000210 std::cerr << '[' << i->first << ','
211 << mri_->getName(i->second) << "]\n";
212 }
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000213 for (Virt2StackSlotMap::const_iterator
214 i = v2ssMap_.begin(), e = v2ssMap_.end(); i != e; ++i) {
215 std::cerr << '[' << i->first << ",ss#" << i->second << "]\n";
216 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000217 std::cerr << '\n';
218 }
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000219
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000220 void printIntervals(const char* const str,
221 RA::IntervalPtrs::const_iterator i,
222 RA::IntervalPtrs::const_iterator e) const {
223 if (str) std::cerr << str << " intervals:\n";
224 for (; i != e; ++i) {
225 std::cerr << "\t\t" << **i << " -> ";
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000226 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000227 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000228 Virt2PhysMap::const_iterator it = v2pMap_.find(reg);
229 reg = (it == v2pMap_.end() ? 0 : it->second);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000230 }
Alkis Evlogimenosa12c7bb2004-01-16 20:33:13 +0000231 std::cerr << mri_->getName(reg) << '\n';
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000232 }
233 }
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000234
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000235// void printFreeRegs(const char* const str,
236// const TargetRegisterClass* rc) const {
237// if (str) std::cerr << str << ':';
238// for (TargetRegisterClass::iterator i =
239// rc->allocation_order_begin(*mf_);
240// i != rc->allocation_order_end(*mf_); ++i) {
241// unsigned reg = *i;
242// if (!regUse_[reg]) {
243// std::cerr << ' ' << mri_->getName(reg);
244// if (reserved_[reg]) std::cerr << "*";
245// }
246// }
247// std::cerr << '\n';
248// }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000249 };
250}
251
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000252void RA::releaseMemory()
253{
254 v2pMap_.clear();
255 v2ssMap_.clear();
256 unhandled_.clear();
257 active_.clear();
258 inactive_.clear();
259 fixed_.clear();
260
261}
262
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000263bool RA::runOnMachineFunction(MachineFunction &fn) {
264 mf_ = &fn;
265 tm_ = &fn.getTarget();
266 mri_ = tm_->getRegisterInfo();
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000267 li_ = &getAnalysis<LiveIntervals>();
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000268 prt_ = PhysRegTracker(mf_);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000269
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000270 initIntervalSets(li_->getIntervals());
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000271
272 // FIXME: this will work only for the X86 backend. I need to
273 // device an algorthm to select the minimal (considering register
274 // aliasing) number of temp registers to reserve so that we have 2
275 // registers for each register class available.
276
Alkis Evlogimenos27490a62003-12-28 18:03:52 +0000277 // reserve R8: CH, CL
278 // R16: CX, DI,
279 // R32: ECX, EDI,
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000280 // RFP: FP5, FP6
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000281 prt_.reservePhysReg( 8); /* CH */
282 prt_.reservePhysReg( 9); /* CL */
283 prt_.reservePhysReg(10); /* CX */
284 prt_.reservePhysReg(12); /* DI */
285 prt_.reservePhysReg(18); /* ECX */
286 prt_.reservePhysReg(19); /* EDI */
287 prt_.reservePhysReg(28); /* FP5 */
288 prt_.reservePhysReg(29); /* FP6 */
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000289
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000290 // linear scan algorithm
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000291 DEBUG(std::cerr << "Machine Function\n");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000292
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000293 DEBUG(printIntervals("\tunhandled", unhandled_.begin(), unhandled_.end()));
294 DEBUG(printIntervals("\tfixed", fixed_.begin(), fixed_.end()));
295 DEBUG(printIntervals("\tactive", active_.begin(), active_.end()));
296 DEBUG(printIntervals("\tinactive", inactive_.begin(), inactive_.end()));
297
298 while (!unhandled_.empty() || !fixed_.empty()) {
299 // pick the interval with the earliest start point
300 IntervalPtrs::value_type cur;
301 if (fixed_.empty()) {
302 cur = unhandled_.front();
303 unhandled_.erase(unhandled_.begin());
304 }
305 else if (unhandled_.empty()) {
306 cur = fixed_.front();
307 fixed_.erase(fixed_.begin());
308 }
309 else if (unhandled_.front()->start() < fixed_.front()->start()) {
310 cur = unhandled_.front();
311 unhandled_.erase(unhandled_.begin());
312 }
313 else {
314 cur = fixed_.front();
315 fixed_.erase(fixed_.begin());
316 }
317
Alkis Evlogimenos5ab20272004-01-14 00:09:36 +0000318 DEBUG(std::cerr << *cur << '\n');
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000319
320 processActiveIntervals(cur);
321 processInactiveIntervals(cur);
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000322
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000323 // if this register is fixed we are done
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000324 if (MRegisterInfo::isPhysicalRegister(cur->reg)) {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000325 prt_.addPhysRegUse(cur->reg);
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000326 active_.push_back(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000327 }
328 // otherwise we are allocating a virtual register. try to find
329 // a free physical register or spill an interval in order to
330 // assign it one (we could spill the current though).
331 else {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000332 PhysRegTracker backupPrt = prt_;
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000333
334 // for every interval in inactive we overlap with, mark the
335 // register as not free
336 for (IntervalPtrs::const_iterator i = inactive_.begin(),
337 e = inactive_.end(); i != e; ++i) {
338 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000339 if (MRegisterInfo::isVirtualRegister(reg))
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000340 reg = v2pMap_[reg];
341
342 if (cur->overlaps(**i)) {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000343 prt_.addPhysRegUse(reg);
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000344 }
345 }
346
347 // for every interval in fixed we overlap with,
348 // mark the register as not free
349 for (IntervalPtrs::const_iterator i = fixed_.begin(),
350 e = fixed_.end(); i != e; ++i) {
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000351 assert(MRegisterInfo::isPhysicalRegister((*i)->reg) &&
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000352 "virtual register interval in fixed set?");
353 if (cur->overlaps(**i))
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000354 prt_.addPhysRegUse((*i)->reg);
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000355 }
356
357 DEBUG(std::cerr << "\tallocating current interval:\n");
358
359 unsigned physReg = getFreePhysReg(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000360 if (!physReg) {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000361 assignStackSlotAtInterval(cur, backupPrt);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000362 }
363 else {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000364 prt_ = backupPrt;
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000365 assignVirt2PhysReg(cur->reg, physReg);
366 active_.push_back(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000367 }
368 }
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000369
370 DEBUG(printIntervals("\tactive", active_.begin(), active_.end()));
371 DEBUG(printIntervals("\tinactive", inactive_.begin(), inactive_.end())); }
372
Alkis Evlogimenos7d65a122003-12-13 05:50:19 +0000373 // expire any remaining active intervals
374 for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) {
375 unsigned reg = (*i)->reg;
376 DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000377 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000378 reg = v2pMap_[reg];
Alkis Evlogimenos7d65a122003-12-13 05:50:19 +0000379 }
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000380 prt_.delPhysRegUse(reg);
Alkis Evlogimenos7d65a122003-12-13 05:50:19 +0000381 }
Alkis Evlogimenos4d7af652003-12-14 13:24:17 +0000382
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000383 typedef LiveIntervals::Reg2RegMap Reg2RegMap;
384 const Reg2RegMap& r2rMap = li_->getJoinedRegMap();
385
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000386 DEBUG(printVirtRegAssignment());
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000387 DEBUG(std::cerr << "Performing coalescing on joined intervals\n");
388 // perform coalescing if we were passed joined intervals
389 for(Reg2RegMap::const_iterator i = r2rMap.begin(), e = r2rMap.end();
390 i != e; ++i) {
391 unsigned reg = i->first;
392 unsigned rep = li_->rep(reg);
393
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000394 assert((MRegisterInfo::isPhysicalRegister(rep) ||
Alkis Evlogimenosf440cc12004-02-01 18:39:53 +0000395 v2pMap_.count(rep) || v2ssMap_.count(rep)) &&
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000396 "representative register is not allocated!");
397
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000398 assert(MRegisterInfo::isVirtualRegister(reg) &&
Alkis Evlogimenosf440cc12004-02-01 18:39:53 +0000399 !v2pMap_.count(reg) && !v2ssMap_.count(reg) &&
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000400 "coalesced register is already allocated!");
401
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000402 if (MRegisterInfo::isPhysicalRegister(rep)) {
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000403 v2pMap_.insert(std::make_pair(reg, rep));
404 }
405 else {
406 Virt2PhysMap::const_iterator pr = v2pMap_.find(rep);
407 if (pr != v2pMap_.end()) {
408 v2pMap_.insert(std::make_pair(reg, pr->second));
409 }
410 else {
411 Virt2StackSlotMap::const_iterator ss = v2ssMap_.find(rep);
412 assert(ss != v2ssMap_.end());
413 v2ssMap_.insert(std::make_pair(reg, ss->second));
414 }
415 }
416 }
417
418 DEBUG(printVirtRegAssignment());
419 DEBUG(std::cerr << "finished register allocation\n");
420
421 const TargetInstrInfo& tii = tm_->getInstrInfo();
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000422
423 DEBUG(std::cerr << "Rewrite machine code:\n");
Alkis Evlogimenos1283d862004-01-07 05:31:12 +0000424 for (currentMbb_ = mf_->begin(); currentMbb_ != mf_->end(); ++currentMbb_) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000425 instrAdded_ = 0;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000426
427 for (currentInstr_ = currentMbb_->begin();
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000428 currentInstr_ != currentMbb_->end(); ) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000429 DEBUG(std::cerr << "\tinstruction: ";
430 (*currentInstr_)->print(std::cerr, *tm_););
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000431
432 // use our current mapping and actually replace and
433 // virtual register with its allocated physical registers
434 DEBUG(std::cerr << "\t\treplacing virtual registers with mapped "
435 "physical registers:\n");
436 for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
437 i != e; ++i) {
438 MachineOperand& op = (*currentInstr_)->getOperand(i);
439 if (op.isVirtualRegister()) {
440 unsigned virtReg = op.getAllocatedRegNum();
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000441 Virt2PhysMap::const_iterator it = v2pMap_.find(virtReg);
442 if (it != v2pMap_.end()) {
Alkis Evlogimenoscc6a1292004-02-02 22:00:32 +0000443 DEBUG(std::cerr << "\t\t\t%reg" << it->first
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000444 << " -> " << mri_->getName(it->second) << '\n');
445 (*currentInstr_)->SetMachineOperandReg(i, it->second);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000446 }
447 }
448 }
449
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000450 unsigned srcReg, dstReg;
451 if (tii.isMoveInstr(**currentInstr_, srcReg, dstReg) &&
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000452 ((MRegisterInfo::isPhysicalRegister(srcReg) &&
453 MRegisterInfo::isPhysicalRegister(dstReg) &&
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000454 srcReg == dstReg) ||
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000455 (MRegisterInfo::isVirtualRegister(srcReg) &&
456 MRegisterInfo::isVirtualRegister(dstReg) &&
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000457 v2ssMap_[srcReg] == v2ssMap_[dstReg]))) {
458 delete *currentInstr_;
459 currentInstr_ = currentMbb_->erase(currentInstr_);
460 ++numPeep;
461 DEBUG(std::cerr << "\t\tdeleting instruction\n");
462 continue;
463 }
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000464
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000465 typedef std::vector<Virt2PhysMap::iterator> Regs;
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000466 Regs toClear;
467 Regs toSpill;
468
469 const unsigned numOperands = (*currentInstr_)->getNumOperands();
470
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000471 DEBUG(std::cerr << "\t\tloading temporarily used operands to "
472 "registers:\n");
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000473 for (unsigned i = 0; i != numOperands; ++i) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000474 MachineOperand& op = (*currentInstr_)->getOperand(i);
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000475 if (op.isVirtualRegister() && op.isUse()) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000476 unsigned virtReg = op.getAllocatedRegNum();
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000477 unsigned physReg = 0;
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000478 Virt2PhysMap::iterator it = v2pMap_.find(virtReg);
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000479 if (it != v2pMap_.end()) {
480 physReg = it->second;
481 }
482 else {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000483 physReg = getFreeTempPhysReg(virtReg);
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000484 it = loadVirt2PhysReg(virtReg, physReg);
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000485 // we will clear uses that are not also defs
486 // before we allocate registers the defs
487 if (op.isDef())
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000488 toSpill.push_back(it);
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000489 else
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000490 toClear.push_back(it);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000491 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000492 (*currentInstr_)->SetMachineOperandReg(i, physReg);
493 }
494 }
495
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000496 DEBUG(std::cerr << "\t\tclearing temporarily used but not defined "
497 "operands:\n");
498 std::for_each(toClear.begin(), toClear.end(),
499 std::bind1st(std::mem_fun(&RA::clearVirtReg), this));
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000500
501 DEBUG(std::cerr << "\t\tassigning temporarily defined operands to "
502 "registers:\n");
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000503 for (unsigned i = 0; i != numOperands; ++i) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000504 MachineOperand& op = (*currentInstr_)->getOperand(i);
Alkis Evlogimenos4e785442004-02-03 01:13:07 +0000505 if (op.isVirtualRegister()) {
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000506 assert(!op.isUse() && "we should not have uses here!");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000507 unsigned virtReg = op.getAllocatedRegNum();
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000508 unsigned physReg = 0;
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000509 Virt2PhysMap::iterator it = v2pMap_.find(virtReg);
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000510 if (it != v2pMap_.end()) {
511 physReg = it->second;
512 }
513 else {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000514 physReg = getFreeTempPhysReg(virtReg);
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000515 it = assignVirt2PhysReg(virtReg, physReg);
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000516 // need to spill this after we are done with
517 // this instruction
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000518 toSpill.push_back(it);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000519 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000520 (*currentInstr_)->SetMachineOperandReg(i, physReg);
521 }
522 }
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000523 ++currentInstr_; // spills will go after this instruction
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000524
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000525 DEBUG(std::cerr << "\t\tspilling temporarily defined operands:\n");
526 std::for_each(toSpill.begin(), toSpill.end(),
527 std::bind1st(std::mem_fun(&RA::spillVirtReg), this));
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000528 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000529 }
530
531 return true;
532}
533
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000534void RA::initIntervalSets(const LiveIntervals::Intervals& li)
535{
536 assert(unhandled_.empty() && fixed_.empty() &&
537 active_.empty() && inactive_.empty() &&
538 "interval sets should be empty on initialization");
539
540 for (LiveIntervals::Intervals::const_iterator i = li.begin(), e = li.end();
541 i != e; ++i) {
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000542 if (MRegisterInfo::isPhysicalRegister(i->reg))
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000543 fixed_.push_back(&*i);
544 else
545 unhandled_.push_back(&*i);
546 }
547}
548
549void RA::processActiveIntervals(IntervalPtrs::value_type cur)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000550{
551 DEBUG(std::cerr << "\tprocessing active intervals:\n");
552 for (IntervalPtrs::iterator i = active_.begin(); i != active_.end();) {
553 unsigned reg = (*i)->reg;
Alkis Evlogimenos3b02cbe2004-01-16 20:17:05 +0000554 // remove expired intervals
555 if ((*i)->expiredAt(cur->start())) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000556 DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000557 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000558 reg = v2pMap_[reg];
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000559 }
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000560 prt_.delPhysRegUse(reg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000561 // remove from active
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000562 i = active_.erase(i);
563 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000564 // move inactive intervals to inactive list
565 else if (!(*i)->liveAt(cur->start())) {
566 DEBUG(std::cerr << "\t\t\tinterval " << **i << " inactive\n");
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000567 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000568 reg = v2pMap_[reg];
569 }
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000570 prt_.delPhysRegUse(reg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000571 // add to inactive
572 inactive_.push_back(*i);
573 // remove from active
574 i = active_.erase(i);
575 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000576 else {
577 ++i;
578 }
579 }
580}
581
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000582void RA::processInactiveIntervals(IntervalPtrs::value_type cur)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000583{
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000584 DEBUG(std::cerr << "\tprocessing inactive intervals:\n");
585 for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end();) {
586 unsigned reg = (*i)->reg;
587
Alkis Evlogimenos3b02cbe2004-01-16 20:17:05 +0000588 // remove expired intervals
589 if ((*i)->expiredAt(cur->start())) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000590 DEBUG(std::cerr << "\t\t\tinterval " << **i << " expired\n");
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000591 // remove from inactive
592 i = inactive_.erase(i);
593 }
594 // move re-activated intervals in active list
595 else if ((*i)->liveAt(cur->start())) {
596 DEBUG(std::cerr << "\t\t\tinterval " << **i << " active\n");
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000597 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000598 reg = v2pMap_[reg];
599 }
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000600 prt_.addPhysRegUse(reg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000601 // add to active
602 active_.push_back(*i);
603 // remove from inactive
604 i = inactive_.erase(i);
605 }
606 else {
607 ++i;
608 }
609 }
610}
611
612namespace {
Alkis Evlogimenos6b4edba2003-12-21 20:19:10 +0000613 template <typename T>
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000614 void updateWeight(std::vector<T>& rw, int reg, T w)
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000615 {
Alkis Evlogimenos6b4edba2003-12-21 20:19:10 +0000616 if (rw[reg] == std::numeric_limits<T>::max() ||
617 w == std::numeric_limits<T>::max())
618 rw[reg] = std::numeric_limits<T>::max();
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000619 else
620 rw[reg] += w;
621 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000622}
623
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000624void RA::assignStackSlotAtInterval(IntervalPtrs::value_type cur,
625 const PhysRegTracker& backupPrt)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000626{
627 DEBUG(std::cerr << "\t\tassigning stack slot at interval "
628 << *cur << ":\n");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000629
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000630 std::vector<float> regWeight(mri_->getNumRegs(), 0.0);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000631
Alkis Evlogimenos84dc5fb2004-01-22 20:07:18 +0000632 // for each interval in active
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000633 for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
634 i != e; ++i) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000635 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000636 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000637 reg = v2pMap_[reg];
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000638 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000639 updateWeight(regWeight, reg, (*i)->weight);
640 for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
641 updateWeight(regWeight, *as, (*i)->weight);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000642 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000643
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000644 // for each interval in inactive that overlaps
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000645 for (IntervalPtrs::const_iterator i = inactive_.begin(),
646 e = inactive_.end(); i != e; ++i) {
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000647 if (!cur->overlaps(**i))
648 continue;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000649
650 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000651 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000652 reg = v2pMap_[reg];
653 }
654 updateWeight(regWeight, reg, (*i)->weight);
655 for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
656 updateWeight(regWeight, *as, (*i)->weight);
657 }
658
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000659 // for each fixed interval that overlaps
660 for (IntervalPtrs::const_iterator i = fixed_.begin(), e = fixed_.end();
661 i != e; ++i) {
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000662 if (!cur->overlaps(**i))
663 continue;
Alkis Evlogimenosf7df173e2004-01-13 20:37:01 +0000664
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000665 assert(MRegisterInfo::isPhysicalRegister((*i)->reg) &&
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000666 "virtual register interval in fixed set?");
667 updateWeight(regWeight, (*i)->reg, (*i)->weight);
668 for (const unsigned* as = mri_->getAliasSet((*i)->reg); *as; ++as)
669 updateWeight(regWeight, *as, (*i)->weight);
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000670 }
671
Alkis Evlogimenos6b4edba2003-12-21 20:19:10 +0000672 float minWeight = std::numeric_limits<float>::max();
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000673 unsigned minReg = 0;
674 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
675 for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
676 i != rc->allocation_order_end(*mf_); ++i) {
677 unsigned reg = *i;
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000678 if (!prt_.isPhysRegReserved(reg) && minWeight > regWeight[reg]) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000679 minWeight = regWeight[reg];
680 minReg = reg;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000681 }
682 }
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000683 DEBUG(std::cerr << "\t\t\tregister with min weight: "
684 << mri_->getName(minReg) << " (" << minWeight << ")\n");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000685
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000686 if (cur->weight < minWeight) {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000687 prt_ = backupPrt;
Alkis Evlogimenos5ab20272004-01-14 00:09:36 +0000688 DEBUG(std::cerr << "\t\t\t\tspilling: " << *cur << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000689 assignVirt2StackSlot(cur->reg);
690 }
691 else {
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000692 std::vector<bool> toSpill(mri_->getNumRegs(), false);
693 toSpill[minReg] = true;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000694 for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000695 toSpill[*as] = true;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000696
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000697 std::vector<unsigned> spilled;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000698 for (IntervalPtrs::iterator i = active_.begin();
699 i != active_.end(); ) {
700 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000701 if (MRegisterInfo::isVirtualRegister(reg) &&
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000702 toSpill[v2pMap_[reg]] &&
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000703 cur->overlaps(**i)) {
704 spilled.push_back(v2pMap_[reg]);
Alkis Evlogimenos843397c2003-12-24 18:53:31 +0000705 DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000706 assignVirt2StackSlot(reg);
707 i = active_.erase(i);
708 }
709 else {
710 ++i;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000711 }
712 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000713 for (IntervalPtrs::iterator i = inactive_.begin();
714 i != inactive_.end(); ) {
715 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000716 if (MRegisterInfo::isVirtualRegister(reg) &&
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000717 toSpill[v2pMap_[reg]] &&
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000718 cur->overlaps(**i)) {
Alkis Evlogimenos843397c2003-12-24 18:53:31 +0000719 DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000720 assignVirt2StackSlot(reg);
721 i = inactive_.erase(i);
722 }
723 else {
724 ++i;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000725 }
726 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000727
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000728 unsigned physReg = getFreePhysReg(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000729 assert(physReg && "no free physical register after spill?");
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000730
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000731 prt_ = backupPrt;
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000732 for (unsigned i = 0; i < spilled.size(); ++i)
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000733 prt_.delPhysRegUse(spilled[i]);
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000734
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000735 assignVirt2PhysReg(cur->reg, physReg);
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000736 active_.push_back(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000737 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000738}
739
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000740unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur)
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000741{
742 DEBUG(std::cerr << "\t\tgetting free physical register: ");
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000743 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
Alkis Evlogimenos26bfc082003-12-28 17:58:18 +0000744
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000745 for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
746 i != rc->allocation_order_end(*mf_); ++i) {
747 unsigned reg = *i;
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000748 if (prt_.isPhysRegAvail(reg)) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000749 DEBUG(std::cerr << mri_->getName(reg) << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000750 return reg;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000751 }
752 }
753
754 DEBUG(std::cerr << "no free register\n");
755 return 0;
756}
757
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000758unsigned RA::getFreeTempPhysReg(unsigned virtReg)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000759{
760 DEBUG(std::cerr << "\t\tgetting free temporary physical register: ");
761
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000762 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
763 // go in reverse allocation order for the temp registers
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000764 typedef std::reverse_iterator<TargetRegisterClass::iterator> TRCRevIter;
765 for (TRCRevIter
766 i(rc->allocation_order_end(*mf_)),
767 e(rc->allocation_order_begin(*mf_)); i != e; ++i) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000768 unsigned reg = *i;
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000769 if (prt_.isReservedPhysRegAvail(reg)) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000770 DEBUG(std::cerr << mri_->getName(reg) << '\n');
771 return reg;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000772 }
773 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000774
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000775 assert(0 && "no free temporary physical register?");
776 return 0;
777}
778
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000779RA::Virt2PhysMap::iterator
780RA::assignVirt2PhysReg(unsigned virtReg, unsigned physReg)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000781{
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000782 bool inserted;
783 Virt2PhysMap::iterator it;
784 tie(it, inserted) = v2pMap_.insert(std::make_pair(virtReg, physReg));
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000785 assert(inserted && "attempting to assign a virt->phys mapping to an "
786 "already mapped register");
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000787 prt_.addPhysRegUse(physReg);
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000788 return it;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000789}
790
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000791void RA::clearVirtReg(Virt2PhysMap::iterator it)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000792{
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000793 assert(it != v2pMap_.end() &&
794 "attempting to clear a not allocated virtual register");
795 unsigned physReg = it->second;
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000796 prt_.delPhysRegUse(physReg);
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000797 v2pMap_.erase(it);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000798 DEBUG(std::cerr << "\t\t\tcleared register " << mri_->getName(physReg)
799 << "\n");
800}
801
802void RA::assignVirt2StackSlot(unsigned virtReg)
803{
804 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
805 int frameIndex = mf_->getFrameInfo()->CreateStackObject(rc);
806
807 bool inserted = v2ssMap_.insert(std::make_pair(virtReg, frameIndex)).second;
808 assert(inserted &&
809 "attempt to assign stack slot to already assigned register?");
810 // if the virtual register was previously assigned clear the mapping
811 // and free the virtual register
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000812 Virt2PhysMap::iterator it = v2pMap_.find(virtReg);
813 if (it != v2pMap_.end()) {
814 clearVirtReg(it);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000815 }
816}
817
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000818int RA::getStackSlot(unsigned virtReg)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000819{
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
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000826void RA::spillVirtReg(Virt2PhysMap::iterator it)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000827{
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000828 assert(it != v2pMap_.end() &&
829 "attempt to spill a not allocated virtual register");
830 unsigned virtReg = it->first;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000831 DEBUG(std::cerr << "\t\t\tspilling register: " << virtReg);
832 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000833 int frameIndex = getStackSlot(virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000834 DEBUG(std::cerr << " to stack slot #" << frameIndex << '\n');
835 ++numSpilled;
836 instrAdded_ += mri_->storeRegToStackSlot(*currentMbb_, currentInstr_,
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000837 it->second, frameIndex, rc);
838 clearVirtReg(it);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000839}
840
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000841RA::Virt2PhysMap::iterator
842RA::loadVirt2PhysReg(unsigned virtReg, unsigned physReg)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000843{
844 DEBUG(std::cerr << "\t\t\tloading register: " << virtReg);
845 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000846 int frameIndex = getStackSlot(virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000847 DEBUG(std::cerr << " from stack slot #" << frameIndex << '\n');
Chris Lattner5e46b512003-12-18 20:25:31 +0000848 ++numReloaded;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000849 instrAdded_ += mri_->loadRegFromStackSlot(*currentMbb_, currentInstr_,
850 physReg, frameIndex, rc);
Alkis Evlogimenos54d23c72004-02-06 03:15:40 +0000851 return assignVirt2PhysReg(virtReg, physReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000852}
853
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000854FunctionPass* llvm::createLinearScanRegisterAllocator() {
855 return new RA();
856}