blob: 1187fc26f19862e7591084a45f67795b70aeebb9 [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 Evlogimenosdd420e02004-03-01 23:18:15 +000039 enum SpillerName { local };
40
41 cl::opt<SpillerName>
42 SpillerOpt("spiller",
43 cl::desc("Spiller to use: (default: local)"),
44 cl::Prefix,
45 cl::values(clEnumVal(local, " local spiller"),
46 0),
47 cl::init(local));
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000048}
49
50int VirtRegMap::assignVirt2StackSlot(unsigned virtReg)
51{
52 assert(MRegisterInfo::isVirtualRegister(virtReg));
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000053 assert(v2ssMap_[virtReg] == NO_STACK_SLOT &&
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000054 "attempt to assign stack slot to already spilled register");
55 const TargetRegisterClass* rc =
56 mf_->getSSARegMap()->getRegClass(virtReg);
57 int frameIndex = mf_->getFrameInfo()->CreateStackObject(rc);
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000058 v2ssMap_[virtReg] = frameIndex;
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000059 ++numSpills;
60 return frameIndex;
61}
62
Alkis Evlogimenos5f375022004-03-01 20:05:10 +000063void VirtRegMap::virtFolded(unsigned virtReg,
64 MachineInstr* oldMI,
65 MachineInstr* newMI)
66{
67 // move previous memory references folded to new instruction
68 MI2VirtMap::iterator i, e;
69 std::vector<MI2VirtMap::mapped_type> regs;
70 for (tie(i, e) = mi2vMap_.equal_range(oldMI); i != e; ) {
71 regs.push_back(i->second);
72 mi2vMap_.erase(i++);
73 }
74 for (unsigned i = 0, e = regs.size(); i != e; ++i)
75 mi2vMap_.insert(std::make_pair(newMI, i));
76
77 // add new memory reference
78 mi2vMap_.insert(std::make_pair(newMI, virtReg));
79}
80
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000081std::ostream& llvm::operator<<(std::ostream& os, const VirtRegMap& vrm)
82{
83 const MRegisterInfo* mri = vrm.mf_->getTarget().getRegisterInfo();
84
85 std::cerr << "********** REGISTER MAP **********\n";
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000086 for (unsigned i = MRegisterInfo::FirstVirtualRegister,
87 e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000088 if (vrm.v2pMap_[i] != VirtRegMap::NO_PHYS_REG)
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000089 std::cerr << "[reg" << i << " -> "
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000090 << mri->getName(vrm.v2pMap_[i]) << "]\n";
91 }
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000092 for (unsigned i = MRegisterInfo::FirstVirtualRegister,
93 e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000094 if (vrm.v2ssMap_[i] != VirtRegMap::NO_STACK_SLOT)
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000095 std::cerr << "[reg" << i << " -> fi#"
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000096 << vrm.v2ssMap_[i] << "]\n";
97 }
98 return std::cerr << '\n';
99}
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000100
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000101Spiller::~Spiller()
102{
103
104}
105
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000106namespace {
107
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000108 class LocalSpiller : public Spiller {
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000109 typedef std::vector<unsigned> Phys2VirtMap;
110 typedef std::vector<bool> PhysFlag;
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000111 typedef DenseMap<MachineInstr*, VirtReg2IndexFunctor> Virt2MI;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000112
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000113 MachineFunction* mf_;
114 const TargetMachine* tm_;
115 const TargetInstrInfo* tii_;
116 const MRegisterInfo* mri_;
117 const VirtRegMap* vrm_;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000118 Phys2VirtMap p2vMap_;
119 PhysFlag dirty_;
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000120 Virt2MI lastDef_;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000121
122 public:
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000123 bool runOnMachineFunction(MachineFunction& mf, const VirtRegMap& vrm) {
124 mf_ = &mf;
125 tm_ = &mf_->getTarget();
126 tii_ = &tm_->getInstrInfo();
127 mri_ = tm_->getRegisterInfo();
128 vrm_ = &vrm;
129 p2vMap_.assign(mri_->getNumRegs(), 0);
130 dirty_.assign(mri_->getNumRegs(), false);
131
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000132 DEBUG(std::cerr << "********** REWRITE MACHINE CODE **********\n");
133 DEBUG(std::cerr << "********** Function: "
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000134 << mf_->getFunction()->getName() << '\n');
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000135
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000136 for (MachineFunction::iterator mbbi = mf_->begin(),
137 mbbe = mf_->end(); mbbi != mbbe; ++mbbi) {
138 lastDef_.grow(mf_->getSSARegMap()->getLastVirtReg());
Alkis Evlogimenos8fa16e42004-02-26 23:22:23 +0000139 DEBUG(std::cerr << mbbi->getBasicBlock()->getName() << ":\n");
140 eliminateVirtRegsInMbb(*mbbi);
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000141 // clear map, dirty flag and last ref
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000142 p2vMap_.assign(p2vMap_.size(), 0);
143 dirty_.assign(dirty_.size(), false);
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000144 lastDef_.clear();
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000145 }
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000146 return true;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000147 }
148
149 private:
150 void vacateJustPhysReg(MachineBasicBlock& mbb,
151 MachineBasicBlock::iterator mii,
152 unsigned physReg) {
153 unsigned virtReg = p2vMap_[physReg];
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000154 if (dirty_[physReg] && vrm_->hasStackSlot(virtReg)) {
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000155 assert(lastDef_[virtReg] && "virtual register is mapped "
156 "to a register and but was not defined!");
157 MachineBasicBlock::iterator lastDef = lastDef_[virtReg];
158 MachineBasicBlock::iterator nextLastRef = next(lastDef);
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000159 mri_->storeRegToStackSlot(*lastDef->getParent(),
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000160 nextLastRef,
161 physReg,
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000162 vrm_->getStackSlot(virtReg),
163 mri_->getRegClass(physReg));
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000164 ++numStores;
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000165 DEBUG(std::cerr << "added: ";
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000166 prior(nextLastRef)->print(std::cerr, *tm_);
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000167 std::cerr << "after: ";
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000168 lastDef->print(std::cerr, *tm_));
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000169 lastDef_[virtReg] = 0;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000170 }
171 p2vMap_[physReg] = 0;
172 dirty_[physReg] = false;
173 }
174
175 void vacatePhysReg(MachineBasicBlock& mbb,
176 MachineBasicBlock::iterator mii,
177 unsigned physReg) {
178 vacateJustPhysReg(mbb, mii, physReg);
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000179 for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as)
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000180 vacateJustPhysReg(mbb, mii, *as);
181 }
182
183 void handleUse(MachineBasicBlock& mbb,
184 MachineBasicBlock::iterator mii,
185 unsigned virtReg,
186 unsigned physReg) {
187 // check if we are replacing a previous mapping
188 if (p2vMap_[physReg] != virtReg) {
189 vacatePhysReg(mbb, mii, physReg);
190 p2vMap_[physReg] = virtReg;
191 // load if necessary
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000192 if (vrm_->hasStackSlot(virtReg)) {
193 mri_->loadRegFromStackSlot(mbb, mii, physReg,
194 vrm_->getStackSlot(virtReg),
195 mri_->getRegClass(physReg));
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000196 ++numLoads;
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000197 DEBUG(std::cerr << "added: ";
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000198 prior(mii)->print(std::cerr, *tm_));
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000199 lastDef_[virtReg] = mii;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000200 }
201 }
202 }
203
204 void handleDef(MachineBasicBlock& mbb,
205 MachineBasicBlock::iterator mii,
206 unsigned virtReg,
207 unsigned physReg) {
208 // check if we are replacing a previous mapping
209 if (p2vMap_[physReg] != virtReg)
210 vacatePhysReg(mbb, mii, physReg);
211
212 p2vMap_[physReg] = virtReg;
213 dirty_[physReg] = true;
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000214 lastDef_[virtReg] = mii;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000215 }
216
217 void eliminateVirtRegsInMbb(MachineBasicBlock& mbb) {
218 for (MachineBasicBlock::iterator mii = mbb.begin(),
219 mie = mbb.end(); mii != mie; ++mii) {
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000220
221 // if we have references to memory operands make sure
222 // we clear all physical registers that may contain
223 // the value of the spilled virtual register
224 VirtRegMap::MI2VirtMap::const_iterator i, e;
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000225 for (tie(i, e) = vrm_->getFoldedVirts(mii); i != e; ++i) {
226 unsigned physReg = vrm_->getPhys(i->second);
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000227 if (physReg) vacateJustPhysReg(mbb, mii, physReg);
228 }
229
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000230 // rewrite all used operands
231 for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
232 MachineOperand& op = mii->getOperand(i);
Alkis Evlogimenose3fcabe2004-02-25 23:21:52 +0000233 if (op.isRegister() && op.getReg() && op.isUse() &&
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000234 MRegisterInfo::isVirtualRegister(op.getReg())) {
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000235 unsigned virtReg = op.getReg();
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000236 unsigned physReg = vrm_->getPhys(virtReg);
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000237 handleUse(mbb, mii, virtReg, physReg);
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000238 mii->SetMachineOperandReg(i, physReg);
239 // mark as dirty if this is def&use
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000240 if (op.isDef()) {
241 dirty_[physReg] = true;
242 lastDef_[virtReg] = mii;
243 }
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000244 }
245 }
246
247 // spill implicit defs
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000248 const TargetInstrDescriptor& tid = tii_->get(mii->getOpcode());
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000249 for (const unsigned* id = tid.ImplicitDefs; *id; ++id)
250 vacatePhysReg(mbb, mii, *id);
251
252 // rewrite def operands (def&use was handled with the
253 // uses so don't check for those here)
254 for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
255 MachineOperand& op = mii->getOperand(i);
Alkis Evlogimenose3fcabe2004-02-25 23:21:52 +0000256 if (op.isRegister() && op.getReg() && !op.isUse())
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000257 if (MRegisterInfo::isPhysicalRegister(op.getReg()))
258 vacatePhysReg(mbb, mii, op.getReg());
259 else {
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000260 unsigned physReg = vrm_->getPhys(op.getReg());
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000261 handleDef(mbb, mii, op.getReg(), physReg);
262 mii->SetMachineOperandReg(i, physReg);
263 }
264 }
265
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000266 DEBUG(std::cerr << '\t'; mii->print(std::cerr, *tm_));
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000267 }
268
269 for (unsigned i = 1, e = p2vMap_.size(); i != e; ++i)
270 vacateJustPhysReg(mbb, mbb.getFirstTerminator(), i);
271
272 }
273 };
274}
275
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000276llvm::Spiller* llvm::createSpiller()
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000277{
Alkis Evlogimenosdd420e02004-03-01 23:18:15 +0000278 switch (SpillerOpt) {
279 default:
280 std::cerr << "no spiller selected";
281 abort();
282 case local:
283 return new LocalSpiller();
284 }
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000285}