blob: 7a7c1c0bb9a8985c8b8e72662a231088d4c4d099 [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
179 void assignVirt2PhysReg(unsigned virtReg, unsigned physReg);
180
181 /// clearVirtReg - free the physical register associated with this
182 /// virtual register and disassociate virtual->physical and
183 /// physical->virtual mappings
184 void clearVirtReg(unsigned virtReg);
185
186 /// assignVirt2StackSlot - assigns this virtual register to a
187 /// stack slot
188 void assignVirt2StackSlot(unsigned virtReg);
189
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000190 /// getStackSlot - returns the offset of the specified
191 /// register on the stack
192 int getStackSlot(unsigned virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000193
194 /// spillVirtReg - spills the virtual register
195 void spillVirtReg(unsigned virtReg);
196
197 /// loadPhysReg - loads to the physical register the value of
198 /// the virtual register specifed. Virtual register must have
199 /// an assigned stack slot
200 void loadVirt2PhysReg(unsigned virtReg, unsigned physReg);
201
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000202 void printVirtRegAssignment() const {
203 std::cerr << "register assignment:\n";
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000204
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000205 for (Virt2PhysMap::const_iterator
206 i = v2pMap_.begin(), e = v2pMap_.end(); i != e; ++i) {
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000207 assert(i->second != 0);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000208 std::cerr << '[' << i->first << ','
209 << mri_->getName(i->second) << "]\n";
210 }
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000211 for (Virt2StackSlotMap::const_iterator
212 i = v2ssMap_.begin(), e = v2ssMap_.end(); i != e; ++i) {
213 std::cerr << '[' << i->first << ",ss#" << i->second << "]\n";
214 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000215 std::cerr << '\n';
216 }
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000217
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000218 void printIntervals(const char* const str,
219 RA::IntervalPtrs::const_iterator i,
220 RA::IntervalPtrs::const_iterator e) const {
221 if (str) std::cerr << str << " intervals:\n";
222 for (; i != e; ++i) {
223 std::cerr << "\t\t" << **i << " -> ";
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000224 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000225 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000226 Virt2PhysMap::const_iterator it = v2pMap_.find(reg);
227 reg = (it == v2pMap_.end() ? 0 : it->second);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000228 }
Alkis Evlogimenosa12c7bb2004-01-16 20:33:13 +0000229 std::cerr << mri_->getName(reg) << '\n';
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000230 }
231 }
Alkis Evlogimenosa6d8c3f2004-01-16 20:29:42 +0000232
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000233// void printFreeRegs(const char* const str,
234// const TargetRegisterClass* rc) const {
235// if (str) std::cerr << str << ':';
236// for (TargetRegisterClass::iterator i =
237// rc->allocation_order_begin(*mf_);
238// i != rc->allocation_order_end(*mf_); ++i) {
239// unsigned reg = *i;
240// if (!regUse_[reg]) {
241// std::cerr << ' ' << mri_->getName(reg);
242// if (reserved_[reg]) std::cerr << "*";
243// }
244// }
245// std::cerr << '\n';
246// }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000247 };
248}
249
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000250void RA::releaseMemory()
251{
252 v2pMap_.clear();
253 v2ssMap_.clear();
254 unhandled_.clear();
255 active_.clear();
256 inactive_.clear();
257 fixed_.clear();
258
259}
260
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000261bool RA::runOnMachineFunction(MachineFunction &fn) {
262 mf_ = &fn;
263 tm_ = &fn.getTarget();
264 mri_ = tm_->getRegisterInfo();
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000265 li_ = &getAnalysis<LiveIntervals>();
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000266 prt_ = PhysRegTracker(mf_);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000267
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000268 initIntervalSets(li_->getIntervals());
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000269
270 // FIXME: this will work only for the X86 backend. I need to
271 // device an algorthm to select the minimal (considering register
272 // aliasing) number of temp registers to reserve so that we have 2
273 // registers for each register class available.
274
Alkis Evlogimenos27490a62003-12-28 18:03:52 +0000275 // reserve R8: CH, CL
276 // R16: CX, DI,
277 // R32: ECX, EDI,
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000278 // RFP: FP5, FP6
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000279 prt_.reservePhysReg( 8); /* CH */
280 prt_.reservePhysReg( 9); /* CL */
281 prt_.reservePhysReg(10); /* CX */
282 prt_.reservePhysReg(12); /* DI */
283 prt_.reservePhysReg(18); /* ECX */
284 prt_.reservePhysReg(19); /* EDI */
285 prt_.reservePhysReg(28); /* FP5 */
286 prt_.reservePhysReg(29); /* FP6 */
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000287
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000288 // linear scan algorithm
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000289 DEBUG(std::cerr << "Machine Function\n");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000290
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000291 DEBUG(printIntervals("\tunhandled", unhandled_.begin(), unhandled_.end()));
292 DEBUG(printIntervals("\tfixed", fixed_.begin(), fixed_.end()));
293 DEBUG(printIntervals("\tactive", active_.begin(), active_.end()));
294 DEBUG(printIntervals("\tinactive", inactive_.begin(), inactive_.end()));
295
296 while (!unhandled_.empty() || !fixed_.empty()) {
297 // pick the interval with the earliest start point
298 IntervalPtrs::value_type cur;
299 if (fixed_.empty()) {
300 cur = unhandled_.front();
301 unhandled_.erase(unhandled_.begin());
302 }
303 else if (unhandled_.empty()) {
304 cur = fixed_.front();
305 fixed_.erase(fixed_.begin());
306 }
307 else if (unhandled_.front()->start() < fixed_.front()->start()) {
308 cur = unhandled_.front();
309 unhandled_.erase(unhandled_.begin());
310 }
311 else {
312 cur = fixed_.front();
313 fixed_.erase(fixed_.begin());
314 }
315
Alkis Evlogimenos5ab20272004-01-14 00:09:36 +0000316 DEBUG(std::cerr << *cur << '\n');
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000317
318 processActiveIntervals(cur);
319 processInactiveIntervals(cur);
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000320
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000321 // if this register is fixed we are done
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000322 if (MRegisterInfo::isPhysicalRegister(cur->reg)) {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000323 prt_.addPhysRegUse(cur->reg);
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000324 active_.push_back(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000325 }
326 // otherwise we are allocating a virtual register. try to find
327 // a free physical register or spill an interval in order to
328 // assign it one (we could spill the current though).
329 else {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000330 PhysRegTracker backupPrt = prt_;
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000331
332 // for every interval in inactive we overlap with, mark the
333 // register as not free
334 for (IntervalPtrs::const_iterator i = inactive_.begin(),
335 e = inactive_.end(); i != e; ++i) {
336 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000337 if (MRegisterInfo::isVirtualRegister(reg))
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000338 reg = v2pMap_[reg];
339
340 if (cur->overlaps(**i)) {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000341 prt_.addPhysRegUse(reg);
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000342 }
343 }
344
345 // for every interval in fixed we overlap with,
346 // mark the register as not free
347 for (IntervalPtrs::const_iterator i = fixed_.begin(),
348 e = fixed_.end(); i != e; ++i) {
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000349 assert(MRegisterInfo::isPhysicalRegister((*i)->reg) &&
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000350 "virtual register interval in fixed set?");
351 if (cur->overlaps(**i))
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000352 prt_.addPhysRegUse((*i)->reg);
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000353 }
354
355 DEBUG(std::cerr << "\tallocating current interval:\n");
356
357 unsigned physReg = getFreePhysReg(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000358 if (!physReg) {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000359 assignStackSlotAtInterval(cur, backupPrt);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000360 }
361 else {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000362 prt_ = backupPrt;
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000363 assignVirt2PhysReg(cur->reg, physReg);
364 active_.push_back(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000365 }
366 }
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000367
368 DEBUG(printIntervals("\tactive", active_.begin(), active_.end()));
369 DEBUG(printIntervals("\tinactive", inactive_.begin(), inactive_.end())); }
370
Alkis Evlogimenos7d65a122003-12-13 05:50:19 +0000371 // expire any remaining active intervals
372 for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) {
373 unsigned reg = (*i)->reg;
374 DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000375 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000376 reg = v2pMap_[reg];
Alkis Evlogimenos7d65a122003-12-13 05:50:19 +0000377 }
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000378 prt_.delPhysRegUse(reg);
Alkis Evlogimenos7d65a122003-12-13 05:50:19 +0000379 }
Alkis Evlogimenos4d7af652003-12-14 13:24:17 +0000380
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000381 typedef LiveIntervals::Reg2RegMap Reg2RegMap;
382 const Reg2RegMap& r2rMap = li_->getJoinedRegMap();
383
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000384 DEBUG(printVirtRegAssignment());
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000385 DEBUG(std::cerr << "Performing coalescing on joined intervals\n");
386 // perform coalescing if we were passed joined intervals
387 for(Reg2RegMap::const_iterator i = r2rMap.begin(), e = r2rMap.end();
388 i != e; ++i) {
389 unsigned reg = i->first;
390 unsigned rep = li_->rep(reg);
391
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000392 assert((MRegisterInfo::isPhysicalRegister(rep) ||
Alkis Evlogimenosf440cc12004-02-01 18:39:53 +0000393 v2pMap_.count(rep) || v2ssMap_.count(rep)) &&
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000394 "representative register is not allocated!");
395
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000396 assert(MRegisterInfo::isVirtualRegister(reg) &&
Alkis Evlogimenosf440cc12004-02-01 18:39:53 +0000397 !v2pMap_.count(reg) && !v2ssMap_.count(reg) &&
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000398 "coalesced register is already allocated!");
399
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000400 if (MRegisterInfo::isPhysicalRegister(rep)) {
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000401 v2pMap_.insert(std::make_pair(reg, rep));
402 }
403 else {
404 Virt2PhysMap::const_iterator pr = v2pMap_.find(rep);
405 if (pr != v2pMap_.end()) {
406 v2pMap_.insert(std::make_pair(reg, pr->second));
407 }
408 else {
409 Virt2StackSlotMap::const_iterator ss = v2ssMap_.find(rep);
410 assert(ss != v2ssMap_.end());
411 v2ssMap_.insert(std::make_pair(reg, ss->second));
412 }
413 }
414 }
415
416 DEBUG(printVirtRegAssignment());
417 DEBUG(std::cerr << "finished register allocation\n");
418
419 const TargetInstrInfo& tii = tm_->getInstrInfo();
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000420
421 DEBUG(std::cerr << "Rewrite machine code:\n");
Alkis Evlogimenos1283d862004-01-07 05:31:12 +0000422 for (currentMbb_ = mf_->begin(); currentMbb_ != mf_->end(); ++currentMbb_) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000423 instrAdded_ = 0;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000424
425 for (currentInstr_ = currentMbb_->begin();
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000426 currentInstr_ != currentMbb_->end(); ) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000427 DEBUG(std::cerr << "\tinstruction: ";
428 (*currentInstr_)->print(std::cerr, *tm_););
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000429
430 // use our current mapping and actually replace and
431 // virtual register with its allocated physical registers
432 DEBUG(std::cerr << "\t\treplacing virtual registers with mapped "
433 "physical registers:\n");
434 for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
435 i != e; ++i) {
436 MachineOperand& op = (*currentInstr_)->getOperand(i);
437 if (op.isVirtualRegister()) {
438 unsigned virtReg = op.getAllocatedRegNum();
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000439 Virt2PhysMap::const_iterator it = v2pMap_.find(virtReg);
440 if (it != v2pMap_.end()) {
Alkis Evlogimenoscc6a1292004-02-02 22:00:32 +0000441 DEBUG(std::cerr << "\t\t\t%reg" << it->first
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000442 << " -> " << mri_->getName(it->second) << '\n');
443 (*currentInstr_)->SetMachineOperandReg(i, it->second);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000444 }
445 }
446 }
447
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000448 unsigned srcReg, dstReg;
449 if (tii.isMoveInstr(**currentInstr_, srcReg, dstReg) &&
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000450 ((MRegisterInfo::isPhysicalRegister(srcReg) &&
451 MRegisterInfo::isPhysicalRegister(dstReg) &&
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000452 srcReg == dstReg) ||
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000453 (MRegisterInfo::isVirtualRegister(srcReg) &&
454 MRegisterInfo::isVirtualRegister(dstReg) &&
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000455 v2ssMap_[srcReg] == v2ssMap_[dstReg]))) {
456 delete *currentInstr_;
457 currentInstr_ = currentMbb_->erase(currentInstr_);
458 ++numPeep;
459 DEBUG(std::cerr << "\t\tdeleting instruction\n");
460 continue;
461 }
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000462
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000463 typedef std::vector<unsigned> Regs;
464 Regs toClear;
465 Regs toSpill;
466
467 const unsigned numOperands = (*currentInstr_)->getNumOperands();
468
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000469 DEBUG(std::cerr << "\t\tloading temporarily used operands to "
470 "registers:\n");
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000471 for (unsigned i = 0; i != numOperands; ++i) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000472 MachineOperand& op = (*currentInstr_)->getOperand(i);
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000473 if (op.isVirtualRegister() && op.isUse()) {
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);
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000483 // we will clear uses that are not also defs
484 // before we allocate registers the defs
485 if (op.isDef())
486 toSpill.push_back(virtReg);
487 else
488 toClear.push_back(virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000489 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000490 (*currentInstr_)->SetMachineOperandReg(i, physReg);
491 }
492 }
493
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000494 DEBUG(std::cerr << "\t\tclearing temporarily used but not defined "
495 "operands:\n");
496 std::for_each(toClear.begin(), toClear.end(),
497 std::bind1st(std::mem_fun(&RA::clearVirtReg), this));
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000498
499 DEBUG(std::cerr << "\t\tassigning temporarily defined operands to "
500 "registers:\n");
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000501 for (unsigned i = 0; i != numOperands; ++i) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000502 MachineOperand& op = (*currentInstr_)->getOperand(i);
Alkis Evlogimenos4e785442004-02-03 01:13:07 +0000503 if (op.isVirtualRegister()) {
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000504 assert(!op.isUse() && "we should not have uses here!");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000505 unsigned virtReg = op.getAllocatedRegNum();
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000506 unsigned physReg = 0;
507 Virt2PhysMap::const_iterator it = v2pMap_.find(virtReg);
508 if (it != v2pMap_.end()) {
509 physReg = it->second;
510 }
511 else {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000512 physReg = getFreeTempPhysReg(virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000513 assignVirt2PhysReg(virtReg, physReg);
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000514 // need to spill this after we are done with
515 // this instruction
516 toSpill.push_back(virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000517 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000518 (*currentInstr_)->SetMachineOperandReg(i, physReg);
519 }
520 }
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000521 ++currentInstr_; // spills will go after this instruction
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000522
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000523 DEBUG(std::cerr << "\t\tspilling temporarily defined operands:\n");
524 std::for_each(toSpill.begin(), toSpill.end(),
525 std::bind1st(std::mem_fun(&RA::spillVirtReg), this));
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000526 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000527 }
528
529 return true;
530}
531
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000532void RA::initIntervalSets(const LiveIntervals::Intervals& li)
533{
534 assert(unhandled_.empty() && fixed_.empty() &&
535 active_.empty() && inactive_.empty() &&
536 "interval sets should be empty on initialization");
537
538 for (LiveIntervals::Intervals::const_iterator i = li.begin(), e = li.end();
539 i != e; ++i) {
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000540 if (MRegisterInfo::isPhysicalRegister(i->reg))
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000541 fixed_.push_back(&*i);
542 else
543 unhandled_.push_back(&*i);
544 }
545}
546
547void RA::processActiveIntervals(IntervalPtrs::value_type cur)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000548{
549 DEBUG(std::cerr << "\tprocessing active intervals:\n");
550 for (IntervalPtrs::iterator i = active_.begin(); i != active_.end();) {
551 unsigned reg = (*i)->reg;
Alkis Evlogimenos3b02cbe2004-01-16 20:17:05 +0000552 // remove expired intervals
553 if ((*i)->expiredAt(cur->start())) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000554 DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000555 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000556 reg = v2pMap_[reg];
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000557 }
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000558 prt_.delPhysRegUse(reg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000559 // remove from active
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000560 i = active_.erase(i);
561 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000562 // move inactive intervals to inactive list
563 else if (!(*i)->liveAt(cur->start())) {
564 DEBUG(std::cerr << "\t\t\tinterval " << **i << " inactive\n");
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000565 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000566 reg = v2pMap_[reg];
567 }
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000568 prt_.delPhysRegUse(reg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000569 // add to inactive
570 inactive_.push_back(*i);
571 // remove from active
572 i = active_.erase(i);
573 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000574 else {
575 ++i;
576 }
577 }
578}
579
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000580void RA::processInactiveIntervals(IntervalPtrs::value_type cur)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000581{
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000582 DEBUG(std::cerr << "\tprocessing inactive intervals:\n");
583 for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end();) {
584 unsigned reg = (*i)->reg;
585
Alkis Evlogimenos3b02cbe2004-01-16 20:17:05 +0000586 // remove expired intervals
587 if ((*i)->expiredAt(cur->start())) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000588 DEBUG(std::cerr << "\t\t\tinterval " << **i << " expired\n");
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000589 // remove from inactive
590 i = inactive_.erase(i);
591 }
592 // move re-activated intervals in active list
593 else if ((*i)->liveAt(cur->start())) {
594 DEBUG(std::cerr << "\t\t\tinterval " << **i << " active\n");
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000595 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000596 reg = v2pMap_[reg];
597 }
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000598 prt_.addPhysRegUse(reg);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000599 // add to active
600 active_.push_back(*i);
601 // remove from inactive
602 i = inactive_.erase(i);
603 }
604 else {
605 ++i;
606 }
607 }
608}
609
610namespace {
Alkis Evlogimenos6b4edba2003-12-21 20:19:10 +0000611 template <typename T>
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000612 void updateWeight(std::vector<T>& rw, int reg, T w)
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000613 {
Alkis Evlogimenos6b4edba2003-12-21 20:19:10 +0000614 if (rw[reg] == std::numeric_limits<T>::max() ||
615 w == std::numeric_limits<T>::max())
616 rw[reg] = std::numeric_limits<T>::max();
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000617 else
618 rw[reg] += w;
619 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000620}
621
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000622void RA::assignStackSlotAtInterval(IntervalPtrs::value_type cur,
623 const PhysRegTracker& backupPrt)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000624{
625 DEBUG(std::cerr << "\t\tassigning stack slot at interval "
626 << *cur << ":\n");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000627
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000628 std::vector<float> regWeight(mri_->getNumRegs(), 0.0);
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000629
Alkis Evlogimenos84dc5fb2004-01-22 20:07:18 +0000630 // for each interval in active
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000631 for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
632 i != e; ++i) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000633 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000634 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000635 reg = v2pMap_[reg];
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000636 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000637 updateWeight(regWeight, reg, (*i)->weight);
638 for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
639 updateWeight(regWeight, *as, (*i)->weight);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000640 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000641
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000642 // for each interval in inactive that overlaps
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000643 for (IntervalPtrs::const_iterator i = inactive_.begin(),
644 e = inactive_.end(); i != e; ++i) {
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000645 if (!cur->overlaps(**i))
646 continue;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000647
648 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000649 if (MRegisterInfo::isVirtualRegister(reg)) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000650 reg = v2pMap_[reg];
651 }
652 updateWeight(regWeight, reg, (*i)->weight);
653 for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
654 updateWeight(regWeight, *as, (*i)->weight);
655 }
656
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000657 // for each fixed interval that overlaps
658 for (IntervalPtrs::const_iterator i = fixed_.begin(), e = fixed_.end();
659 i != e; ++i) {
Alkis Evlogimenosb7be1152004-01-13 20:42:08 +0000660 if (!cur->overlaps(**i))
661 continue;
Alkis Evlogimenosf7df173e2004-01-13 20:37:01 +0000662
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000663 assert(MRegisterInfo::isPhysicalRegister((*i)->reg) &&
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000664 "virtual register interval in fixed set?");
665 updateWeight(regWeight, (*i)->reg, (*i)->weight);
666 for (const unsigned* as = mri_->getAliasSet((*i)->reg); *as; ++as)
667 updateWeight(regWeight, *as, (*i)->weight);
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000668 }
669
Alkis Evlogimenos6b4edba2003-12-21 20:19:10 +0000670 float minWeight = std::numeric_limits<float>::max();
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000671 unsigned minReg = 0;
672 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
673 for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
674 i != rc->allocation_order_end(*mf_); ++i) {
675 unsigned reg = *i;
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000676 if (!prt_.isPhysRegReserved(reg) && minWeight > regWeight[reg]) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000677 minWeight = regWeight[reg];
678 minReg = reg;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000679 }
680 }
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000681 DEBUG(std::cerr << "\t\t\tregister with min weight: "
682 << mri_->getName(minReg) << " (" << minWeight << ")\n");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000683
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000684 if (cur->weight < minWeight) {
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000685 prt_ = backupPrt;
Alkis Evlogimenos5ab20272004-01-14 00:09:36 +0000686 DEBUG(std::cerr << "\t\t\t\tspilling: " << *cur << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000687 assignVirt2StackSlot(cur->reg);
688 }
689 else {
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000690 std::vector<bool> toSpill(mri_->getNumRegs(), false);
691 toSpill[minReg] = true;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000692 for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000693 toSpill[*as] = true;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000694
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000695 std::vector<unsigned> spilled;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000696 for (IntervalPtrs::iterator i = active_.begin();
697 i != active_.end(); ) {
698 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000699 if (MRegisterInfo::isVirtualRegister(reg) &&
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000700 toSpill[v2pMap_[reg]] &&
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000701 cur->overlaps(**i)) {
702 spilled.push_back(v2pMap_[reg]);
Alkis Evlogimenos843397c2003-12-24 18:53:31 +0000703 DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000704 assignVirt2StackSlot(reg);
705 i = active_.erase(i);
706 }
707 else {
708 ++i;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000709 }
710 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000711 for (IntervalPtrs::iterator i = inactive_.begin();
712 i != inactive_.end(); ) {
713 unsigned reg = (*i)->reg;
Alkis Evlogimenos4f67b862004-02-01 01:27:01 +0000714 if (MRegisterInfo::isVirtualRegister(reg) &&
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000715 toSpill[v2pMap_[reg]] &&
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000716 cur->overlaps(**i)) {
Alkis Evlogimenos843397c2003-12-24 18:53:31 +0000717 DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000718 assignVirt2StackSlot(reg);
719 i = inactive_.erase(i);
720 }
721 else {
722 ++i;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000723 }
724 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000725
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000726 unsigned physReg = getFreePhysReg(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000727 assert(physReg && "no free physical register after spill?");
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000728
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000729 prt_ = backupPrt;
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000730 for (unsigned i = 0; i < spilled.size(); ++i)
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000731 prt_.delPhysRegUse(spilled[i]);
Alkis Evlogimenos3bf564a2003-12-23 18:00:33 +0000732
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000733 assignVirt2PhysReg(cur->reg, physReg);
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000734 active_.push_back(cur);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000735 }
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000736}
737
Alkis Evlogimenos7d629b52004-01-07 09:20:58 +0000738unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur)
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000739{
740 DEBUG(std::cerr << "\t\tgetting free physical register: ");
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000741 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
Alkis Evlogimenos26bfc082003-12-28 17:58:18 +0000742
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000743 for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
744 i != rc->allocation_order_end(*mf_); ++i) {
745 unsigned reg = *i;
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000746 if (prt_.isPhysRegAvail(reg)) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000747 DEBUG(std::cerr << mri_->getName(reg) << '\n');
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000748 return reg;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000749 }
750 }
751
752 DEBUG(std::cerr << "no free register\n");
753 return 0;
754}
755
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000756unsigned RA::getFreeTempPhysReg(unsigned virtReg)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000757{
758 DEBUG(std::cerr << "\t\tgetting free temporary physical register: ");
759
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000760 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
761 // go in reverse allocation order for the temp registers
Alkis Evlogimenos04667292004-02-01 20:13:26 +0000762 typedef std::reverse_iterator<TargetRegisterClass::iterator> TRCRevIter;
763 for (TRCRevIter
764 i(rc->allocation_order_end(*mf_)),
765 e(rc->allocation_order_begin(*mf_)); i != e; ++i) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000766 unsigned reg = *i;
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000767 if (prt_.isReservedPhysRegAvail(reg)) {
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000768 DEBUG(std::cerr << mri_->getName(reg) << '\n');
769 return reg;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000770 }
771 }
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +0000772
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000773 assert(0 && "no free temporary physical register?");
774 return 0;
775}
776
777void RA::assignVirt2PhysReg(unsigned virtReg, unsigned physReg)
778{
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000779 bool inserted = v2pMap_.insert(std::make_pair(virtReg, physReg)).second;
780 assert(inserted && "attempting to assign a virt->phys mapping to an "
781 "already mapped register");
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000782 prt_.addPhysRegUse(physReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000783}
784
785void RA::clearVirtReg(unsigned virtReg)
786{
787 Virt2PhysMap::iterator it = v2pMap_.find(virtReg);
788 assert(it != v2pMap_.end() &&
789 "attempting to clear a not allocated virtual register");
790 unsigned physReg = it->second;
Alkis Evlogimenos22b7e442004-02-02 07:30:36 +0000791 prt_.delPhysRegUse(physReg);
Alkis Evlogimenosce501152004-01-22 19:24:43 +0000792 v2pMap_.erase(it);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000793 DEBUG(std::cerr << "\t\t\tcleared register " << mri_->getName(physReg)
794 << "\n");
795}
796
797void RA::assignVirt2StackSlot(unsigned virtReg)
798{
799 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
800 int frameIndex = mf_->getFrameInfo()->CreateStackObject(rc);
801
802 bool inserted = v2ssMap_.insert(std::make_pair(virtReg, frameIndex)).second;
803 assert(inserted &&
804 "attempt to assign stack slot to already assigned register?");
805 // if the virtual register was previously assigned clear the mapping
806 // and free the virtual register
Alkis Evlogimenosf440cc12004-02-01 18:39:53 +0000807 if (v2pMap_.count(virtReg)) {
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000808 clearVirtReg(virtReg);
809 }
810}
811
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000812int RA::getStackSlot(unsigned virtReg)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000813{
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000814 Virt2StackSlotMap::iterator it = v2ssMap_.find(virtReg);
815 assert(it != v2ssMap_.end() &&
816 "attempt to get stack slot on register that does not live on the stack");
817 return it->second;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000818}
819
820void RA::spillVirtReg(unsigned virtReg)
821{
822 DEBUG(std::cerr << "\t\t\tspilling register: " << virtReg);
823 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000824 int frameIndex = getStackSlot(virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000825 DEBUG(std::cerr << " to stack slot #" << frameIndex << '\n');
826 ++numSpilled;
827 instrAdded_ += mri_->storeRegToStackSlot(*currentMbb_, currentInstr_,
828 v2pMap_[virtReg], frameIndex, rc);
829 clearVirtReg(virtReg);
830}
831
832void RA::loadVirt2PhysReg(unsigned virtReg, unsigned physReg)
833{
834 DEBUG(std::cerr << "\t\t\tloading register: " << virtReg);
835 const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
Alkis Evlogimenos69546d52003-12-04 03:57:28 +0000836 int frameIndex = getStackSlot(virtReg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000837 DEBUG(std::cerr << " from stack slot #" << frameIndex << '\n');
Chris Lattner5e46b512003-12-18 20:25:31 +0000838 ++numReloaded;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000839 instrAdded_ += mri_->loadRegFromStackSlot(*currentMbb_, currentInstr_,
840 physReg, frameIndex, rc);
841 assignVirt2PhysReg(virtReg, physReg);
842}
843
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000844FunctionPass* llvm::createLinearScanRegisterAllocator() {
845 return new RA();
846}