blob: 4306caacb8da6949a7e5a5129781b41662e2237d [file] [log] [blame]
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +00001//===-- llvm/CodeGen/VirtRegMap.cpp - Virtual Register Map ----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000010// This file implements the virtual register map. It also implements
11// the eliminateVirtRegs() function that given a virtual register map
12// and a machine function it eliminates all virtual references by
13// replacing them with physical register references and adds spill
14// code as necessary.
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000015//
16//===----------------------------------------------------------------------===//
17
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000018#define DEBUG_TYPE "regalloc"
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000019#include "VirtRegMap.h"
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000020#include "llvm/Function.h"
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000021#include "llvm/CodeGen/MachineFrameInfo.h"
Alkis Evlogimenos5f375022004-03-01 20:05:10 +000022#include "llvm/CodeGen/MachineInstr.h"
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000023#include "llvm/Target/TargetMachine.h"
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000024#include "llvm/Target/TargetInstrInfo.h"
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +000025#include "Support/CommandLine.h"
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000026#include "Support/Debug.h"
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +000027#include "Support/DenseMap.h"
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +000028#include "Support/Statistic.h"
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000029#include "Support/STLExtras.h"
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000030#include <iostream>
31
32using namespace llvm;
33
34namespace {
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000035 Statistic<> numSpills("spiller", "Number of register spills");
36 Statistic<> numStores("spiller", "Number of stores added");
37 Statistic<> numLoads ("spiller", "Number of loads added");
38
Alkis Evlogimenos499b2ba2004-03-06 22:38:29 +000039 enum SpillerName { simple, local };
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +000040
41 cl::opt<SpillerName>
42 SpillerOpt("spiller",
43 cl::desc("Spiller to use: (default: local)"),
44 cl::Prefix,
Alkis Evlogimenos499b2ba2004-03-06 22:38:29 +000045 cl::values(clEnumVal(simple, " simple spiller"),
46 clEnumVal(local, " local spiller"),
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +000047 0),
Alkis Evlogimenos499b2ba2004-03-06 22:38:29 +000048// cl::init(local));
49 cl::init(simple));
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000050}
51
52int VirtRegMap::assignVirt2StackSlot(unsigned virtReg)
53{
54 assert(MRegisterInfo::isVirtualRegister(virtReg));
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000055 assert(v2ssMap_[virtReg] == NO_STACK_SLOT &&
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000056 "attempt to assign stack slot to already spilled register");
57 const TargetRegisterClass* rc =
58 mf_->getSSARegMap()->getRegClass(virtReg);
59 int frameIndex = mf_->getFrameInfo()->CreateStackObject(rc);
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000060 v2ssMap_[virtReg] = frameIndex;
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000061 ++numSpills;
62 return frameIndex;
63}
64
Alkis Evlogimenos5f375022004-03-01 20:05:10 +000065void VirtRegMap::virtFolded(unsigned virtReg,
66 MachineInstr* oldMI,
67 MachineInstr* newMI)
68{
69 // move previous memory references folded to new instruction
70 MI2VirtMap::iterator i, e;
71 std::vector<MI2VirtMap::mapped_type> regs;
72 for (tie(i, e) = mi2vMap_.equal_range(oldMI); i != e; ) {
73 regs.push_back(i->second);
74 mi2vMap_.erase(i++);
75 }
76 for (unsigned i = 0, e = regs.size(); i != e; ++i)
77 mi2vMap_.insert(std::make_pair(newMI, i));
78
79 // add new memory reference
80 mi2vMap_.insert(std::make_pair(newMI, virtReg));
81}
82
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000083std::ostream& llvm::operator<<(std::ostream& os, const VirtRegMap& vrm)
84{
85 const MRegisterInfo* mri = vrm.mf_->getTarget().getRegisterInfo();
86
87 std::cerr << "********** REGISTER MAP **********\n";
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000088 for (unsigned i = MRegisterInfo::FirstVirtualRegister,
89 e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000090 if (vrm.v2pMap_[i] != VirtRegMap::NO_PHYS_REG)
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000091 std::cerr << "[reg" << i << " -> "
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000092 << mri->getName(vrm.v2pMap_[i]) << "]\n";
93 }
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000094 for (unsigned i = MRegisterInfo::FirstVirtualRegister,
95 e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000096 if (vrm.v2ssMap_[i] != VirtRegMap::NO_STACK_SLOT)
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000097 std::cerr << "[reg" << i << " -> fi#"
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000098 << vrm.v2ssMap_[i] << "]\n";
99 }
100 return std::cerr << '\n';
101}
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000102
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000103Spiller::~Spiller()
104{
105
106}
107
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000108namespace {
109
Alkis Evlogimenos499b2ba2004-03-06 22:38:29 +0000110 class SimpleSpiller : public Spiller {
111 public:
112 bool runOnMachineFunction(MachineFunction& mf, const VirtRegMap& vrm) {
113 DEBUG(std::cerr << "********** REWRITE MACHINE CODE **********\n");
114 DEBUG(std::cerr << "********** Function: "
115 << mf.getFunction()->getName() << '\n');
116 const TargetMachine& tm = mf.getTarget();
117 const MRegisterInfo& mri = *tm.getRegisterInfo();
118
119 typedef DenseMap<bool, VirtReg2IndexFunctor> Loaded;
120 Loaded loaded;
121
122 for (MachineFunction::iterator mbbi = mf.begin(),
123 mbbe = mf.end(); mbbi != mbbe; ++mbbi) {
124 DEBUG(std::cerr << mbbi->getBasicBlock()->getName() << ":\n");
125 for (MachineBasicBlock::iterator mii = mbbi->begin(),
126 mie = mbbi->end(); mii != mie; ++mii) {
127 loaded.grow(mf.getSSARegMap()->getLastVirtReg());
128 for (unsigned i = 0,e = mii->getNumOperands(); i != e; ++i){
129 MachineOperand& mop = mii->getOperand(i);
130 if (mop.isRegister() && mop.getReg() &&
131 MRegisterInfo::isVirtualRegister(mop.getReg())) {
132 unsigned virtReg = mop.getReg();
133 unsigned physReg = vrm.getPhys(virtReg);
134 if (mop.isUse() &&
135 vrm.hasStackSlot(mop.getReg()) &&
136 !loaded[virtReg]) {
137 mri.loadRegFromStackSlot(
138 *mbbi,
139 mii,
140 physReg,
141 vrm.getStackSlot(virtReg),
142 mf.getSSARegMap()->getRegClass(virtReg));
143 loaded[virtReg] = true;
144 DEBUG(std::cerr << '\t';
145 prior(mii)->print(std::cerr, tm));
146 ++numLoads;
147 }
148 if (mop.isDef() &&
149 vrm.hasStackSlot(mop.getReg())) {
150 mri.storeRegToStackSlot(
151 *mbbi,
152 next(mii),
153 physReg,
154 vrm.getStackSlot(virtReg),
155 mf.getSSARegMap()->getRegClass(virtReg));
156 ++numStores;
157 }
158 mii->SetMachineOperandReg(i, physReg);
159 }
160 }
161 DEBUG(std::cerr << '\t'; mii->print(std::cerr, tm));
162 loaded.clear();
163 }
164 }
165 return true;
166 }
167 };
168
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000169 class LocalSpiller : public Spiller {
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000170 typedef std::vector<unsigned> Phys2VirtMap;
171 typedef std::vector<bool> PhysFlag;
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000172 typedef DenseMap<MachineInstr*, VirtReg2IndexFunctor> Virt2MI;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000173
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000174 MachineFunction* mf_;
175 const TargetMachine* tm_;
176 const TargetInstrInfo* tii_;
177 const MRegisterInfo* mri_;
178 const VirtRegMap* vrm_;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000179 Phys2VirtMap p2vMap_;
180 PhysFlag dirty_;
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000181 Virt2MI lastDef_;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000182
183 public:
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000184 bool runOnMachineFunction(MachineFunction& mf, const VirtRegMap& vrm) {
185 mf_ = &mf;
186 tm_ = &mf_->getTarget();
187 tii_ = &tm_->getInstrInfo();
188 mri_ = tm_->getRegisterInfo();
189 vrm_ = &vrm;
190 p2vMap_.assign(mri_->getNumRegs(), 0);
191 dirty_.assign(mri_->getNumRegs(), false);
192
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000193 DEBUG(std::cerr << "********** REWRITE MACHINE CODE **********\n");
194 DEBUG(std::cerr << "********** Function: "
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000195 << mf_->getFunction()->getName() << '\n');
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000196
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000197 for (MachineFunction::iterator mbbi = mf_->begin(),
198 mbbe = mf_->end(); mbbi != mbbe; ++mbbi) {
199 lastDef_.grow(mf_->getSSARegMap()->getLastVirtReg());
Alkis Evlogimenos8fa16e42004-02-26 23:22:23 +0000200 DEBUG(std::cerr << mbbi->getBasicBlock()->getName() << ":\n");
201 eliminateVirtRegsInMbb(*mbbi);
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000202 // clear map, dirty flag and last ref
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000203 p2vMap_.assign(p2vMap_.size(), 0);
204 dirty_.assign(dirty_.size(), false);
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000205 lastDef_.clear();
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000206 }
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000207 return true;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000208 }
209
210 private:
211 void vacateJustPhysReg(MachineBasicBlock& mbb,
212 MachineBasicBlock::iterator mii,
213 unsigned physReg) {
214 unsigned virtReg = p2vMap_[physReg];
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000215 if (dirty_[physReg] && vrm_->hasStackSlot(virtReg)) {
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000216 assert(lastDef_[virtReg] && "virtual register is mapped "
217 "to a register and but was not defined!");
218 MachineBasicBlock::iterator lastDef = lastDef_[virtReg];
219 MachineBasicBlock::iterator nextLastRef = next(lastDef);
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000220 mri_->storeRegToStackSlot(*lastDef->getParent(),
Alkis Evlogimenos499b2ba2004-03-06 22:38:29 +0000221 nextLastRef,
222 physReg,
223 vrm_->getStackSlot(virtReg),
224 mri_->getRegClass(physReg));
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000225 ++numStores;
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000226 DEBUG(std::cerr << "added: ";
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000227 prior(nextLastRef)->print(std::cerr, *tm_);
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000228 std::cerr << "after: ";
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000229 lastDef->print(std::cerr, *tm_));
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000230 lastDef_[virtReg] = 0;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000231 }
232 p2vMap_[physReg] = 0;
233 dirty_[physReg] = false;
234 }
235
236 void vacatePhysReg(MachineBasicBlock& mbb,
237 MachineBasicBlock::iterator mii,
238 unsigned physReg) {
239 vacateJustPhysReg(mbb, mii, physReg);
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000240 for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as)
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000241 vacateJustPhysReg(mbb, mii, *as);
242 }
243
244 void handleUse(MachineBasicBlock& mbb,
245 MachineBasicBlock::iterator mii,
246 unsigned virtReg,
247 unsigned physReg) {
248 // check if we are replacing a previous mapping
249 if (p2vMap_[physReg] != virtReg) {
250 vacatePhysReg(mbb, mii, physReg);
251 p2vMap_[physReg] = virtReg;
252 // load if necessary
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000253 if (vrm_->hasStackSlot(virtReg)) {
254 mri_->loadRegFromStackSlot(mbb, mii, physReg,
Alkis Evlogimenos499b2ba2004-03-06 22:38:29 +0000255 vrm_->getStackSlot(virtReg),
256 mri_->getRegClass(physReg));
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000257 ++numLoads;
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000258 DEBUG(std::cerr << "added: ";
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000259 prior(mii)->print(std::cerr, *tm_));
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000260 lastDef_[virtReg] = mii;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000261 }
262 }
263 }
264
265 void handleDef(MachineBasicBlock& mbb,
266 MachineBasicBlock::iterator mii,
267 unsigned virtReg,
268 unsigned physReg) {
269 // check if we are replacing a previous mapping
270 if (p2vMap_[physReg] != virtReg)
271 vacatePhysReg(mbb, mii, physReg);
272
273 p2vMap_[physReg] = virtReg;
274 dirty_[physReg] = true;
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000275 lastDef_[virtReg] = mii;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000276 }
277
278 void eliminateVirtRegsInMbb(MachineBasicBlock& mbb) {
279 for (MachineBasicBlock::iterator mii = mbb.begin(),
280 mie = mbb.end(); mii != mie; ++mii) {
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000281
282 // if we have references to memory operands make sure
283 // we clear all physical registers that may contain
284 // the value of the spilled virtual register
285 VirtRegMap::MI2VirtMap::const_iterator i, e;
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000286 for (tie(i, e) = vrm_->getFoldedVirts(mii); i != e; ++i) {
287 unsigned physReg = vrm_->getPhys(i->second);
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000288 if (physReg) vacateJustPhysReg(mbb, mii, physReg);
289 }
290
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000291 // rewrite all used operands
292 for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
293 MachineOperand& op = mii->getOperand(i);
Alkis Evlogimenose3fcabe2004-02-25 23:21:52 +0000294 if (op.isRegister() && op.getReg() && op.isUse() &&
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000295 MRegisterInfo::isVirtualRegister(op.getReg())) {
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000296 unsigned virtReg = op.getReg();
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000297 unsigned physReg = vrm_->getPhys(virtReg);
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000298 handleUse(mbb, mii, virtReg, physReg);
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000299 mii->SetMachineOperandReg(i, physReg);
300 // mark as dirty if this is def&use
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000301 if (op.isDef()) {
302 dirty_[physReg] = true;
303 lastDef_[virtReg] = mii;
304 }
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000305 }
306 }
307
308 // spill implicit defs
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000309 const TargetInstrDescriptor& tid = tii_->get(mii->getOpcode());
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000310 for (const unsigned* id = tid.ImplicitDefs; *id; ++id)
311 vacatePhysReg(mbb, mii, *id);
312
313 // rewrite def operands (def&use was handled with the
314 // uses so don't check for those here)
315 for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
316 MachineOperand& op = mii->getOperand(i);
Alkis Evlogimenose3fcabe2004-02-25 23:21:52 +0000317 if (op.isRegister() && op.getReg() && !op.isUse())
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000318 if (MRegisterInfo::isPhysicalRegister(op.getReg()))
319 vacatePhysReg(mbb, mii, op.getReg());
320 else {
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000321 unsigned physReg = vrm_->getPhys(op.getReg());
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000322 handleDef(mbb, mii, op.getReg(), physReg);
323 mii->SetMachineOperandReg(i, physReg);
324 }
325 }
326
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000327 DEBUG(std::cerr << '\t'; mii->print(std::cerr, *tm_));
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000328 }
329
330 for (unsigned i = 1, e = p2vMap_.size(); i != e; ++i)
331 vacateJustPhysReg(mbb, mbb.getFirstTerminator(), i);
332
333 }
334 };
335}
336
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000337llvm::Spiller* llvm::createSpiller()
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000338{
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000339 switch (SpillerOpt) {
340 default:
341 std::cerr << "no spiller selected";
342 abort();
343 case local:
344 return new LocalSpiller();
Alkis Evlogimenos499b2ba2004-03-06 22:38:29 +0000345 case simple:
346 return new SimpleSpiller();
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000347 }
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000348}