blob: 1238a2cefbb43938beaf8dbfb3e8cb9c58df0b42 [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 Evlogimenos34d9bc92004-02-23 23:08:11 +000025#include "Support/Statistic.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 Evlogimenos0d6c5b62004-02-24 08:58:30 +000028#include "Support/STLExtras.h"
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000029#include <iostream>
30
31using namespace llvm;
32
33namespace {
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000034 Statistic<> numSpills("spiller", "Number of register spills");
35 Statistic<> numStores("spiller", "Number of stores added");
36 Statistic<> numLoads ("spiller", "Number of loads added");
37
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000038}
39
40int VirtRegMap::assignVirt2StackSlot(unsigned virtReg)
41{
42 assert(MRegisterInfo::isVirtualRegister(virtReg));
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000043 assert(v2ssMap_[virtReg] == NO_STACK_SLOT &&
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000044 "attempt to assign stack slot to already spilled register");
45 const TargetRegisterClass* rc =
46 mf_->getSSARegMap()->getRegClass(virtReg);
47 int frameIndex = mf_->getFrameInfo()->CreateStackObject(rc);
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000048 v2ssMap_[virtReg] = frameIndex;
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000049 ++numSpills;
50 return frameIndex;
51}
52
Alkis Evlogimenos5f375022004-03-01 20:05:10 +000053void VirtRegMap::virtFolded(unsigned virtReg,
54 MachineInstr* oldMI,
55 MachineInstr* newMI)
56{
57 // move previous memory references folded to new instruction
58 MI2VirtMap::iterator i, e;
59 std::vector<MI2VirtMap::mapped_type> regs;
60 for (tie(i, e) = mi2vMap_.equal_range(oldMI); i != e; ) {
61 regs.push_back(i->second);
62 mi2vMap_.erase(i++);
63 }
64 for (unsigned i = 0, e = regs.size(); i != e; ++i)
65 mi2vMap_.insert(std::make_pair(newMI, i));
66
67 // add new memory reference
68 mi2vMap_.insert(std::make_pair(newMI, virtReg));
69}
70
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000071std::ostream& llvm::operator<<(std::ostream& os, const VirtRegMap& vrm)
72{
73 const MRegisterInfo* mri = vrm.mf_->getTarget().getRegisterInfo();
74
75 std::cerr << "********** REGISTER MAP **********\n";
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000076 for (unsigned i = MRegisterInfo::FirstVirtualRegister,
77 e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000078 if (vrm.v2pMap_[i] != VirtRegMap::NO_PHYS_REG)
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000079 std::cerr << "[reg" << i << " -> "
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000080 << mri->getName(vrm.v2pMap_[i]) << "]\n";
81 }
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000082 for (unsigned i = MRegisterInfo::FirstVirtualRegister,
83 e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000084 if (vrm.v2ssMap_[i] != VirtRegMap::NO_STACK_SLOT)
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000085 std::cerr << "[reg" << i << " -> fi#"
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000086 << vrm.v2ssMap_[i] << "]\n";
87 }
88 return std::cerr << '\n';
89}
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000090
91namespace {
92
93 class Spiller {
94 typedef std::vector<unsigned> Phys2VirtMap;
95 typedef std::vector<bool> PhysFlag;
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +000096 typedef DenseMap<MachineInstr*, VirtReg2IndexFunctor> Virt2MI;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000097
98 MachineFunction& mf_;
99 const TargetMachine& tm_;
100 const TargetInstrInfo& tii_;
101 const MRegisterInfo& mri_;
102 const VirtRegMap& vrm_;
103 Phys2VirtMap p2vMap_;
104 PhysFlag dirty_;
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000105 Virt2MI lastDef_;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000106
107 public:
108 Spiller(MachineFunction& mf, const VirtRegMap& vrm)
109 : mf_(mf),
110 tm_(mf_.getTarget()),
111 tii_(tm_.getInstrInfo()),
112 mri_(*tm_.getRegisterInfo()),
113 vrm_(vrm),
Alkis Evlogimenos8fa16e42004-02-26 23:22:23 +0000114 p2vMap_(mri_.getNumRegs(), 0),
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000115 dirty_(mri_.getNumRegs(), false),
116 lastDef_() {
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000117 DEBUG(std::cerr << "********** REWRITE MACHINE CODE **********\n");
118 DEBUG(std::cerr << "********** Function: "
119 << mf_.getFunction()->getName() << '\n');
120 }
121
122 void eliminateVirtRegs() {
123 for (MachineFunction::iterator mbbi = mf_.begin(),
124 mbbe = mf_.end(); mbbi != mbbe; ++mbbi) {
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000125 lastDef_.grow(mf_.getSSARegMap()->getLastVirtReg());
Alkis Evlogimenos8fa16e42004-02-26 23:22:23 +0000126 DEBUG(std::cerr << mbbi->getBasicBlock()->getName() << ":\n");
127 eliminateVirtRegsInMbb(*mbbi);
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000128 // clear map, dirty flag and last ref
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000129 p2vMap_.assign(p2vMap_.size(), 0);
130 dirty_.assign(dirty_.size(), false);
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000131 lastDef_.clear();
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000132 }
133 }
134
135 private:
136 void vacateJustPhysReg(MachineBasicBlock& mbb,
137 MachineBasicBlock::iterator mii,
138 unsigned physReg) {
139 unsigned virtReg = p2vMap_[physReg];
140 if (dirty_[physReg] && vrm_.hasStackSlot(virtReg)) {
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000141 assert(lastDef_[virtReg] && "virtual register is mapped "
142 "to a register and but was not defined!");
143 MachineBasicBlock::iterator lastDef = lastDef_[virtReg];
144 MachineBasicBlock::iterator nextLastRef = next(lastDef);
145 mri_.storeRegToStackSlot(*lastDef->getParent(),
146 nextLastRef,
147 physReg,
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000148 vrm_.getStackSlot(virtReg),
149 mri_.getRegClass(physReg));
150 ++numStores;
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000151 DEBUG(std::cerr << "added: ";
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000152 prior(nextLastRef)->print(std::cerr, tm_);
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000153 std::cerr << "after: ";
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000154 lastDef->print(std::cerr, tm_));
155 lastDef_[virtReg] = 0;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000156 }
157 p2vMap_[physReg] = 0;
158 dirty_[physReg] = false;
159 }
160
161 void vacatePhysReg(MachineBasicBlock& mbb,
162 MachineBasicBlock::iterator mii,
163 unsigned physReg) {
164 vacateJustPhysReg(mbb, mii, physReg);
165 for (const unsigned* as = mri_.getAliasSet(physReg); *as; ++as)
166 vacateJustPhysReg(mbb, mii, *as);
167 }
168
169 void handleUse(MachineBasicBlock& mbb,
170 MachineBasicBlock::iterator mii,
171 unsigned virtReg,
172 unsigned physReg) {
173 // check if we are replacing a previous mapping
174 if (p2vMap_[physReg] != virtReg) {
175 vacatePhysReg(mbb, mii, physReg);
176 p2vMap_[physReg] = virtReg;
177 // load if necessary
178 if (vrm_.hasStackSlot(virtReg)) {
179 mri_.loadRegFromStackSlot(mbb, mii, physReg,
180 vrm_.getStackSlot(virtReg),
181 mri_.getRegClass(physReg));
182 ++numLoads;
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000183 DEBUG(std::cerr << "added: ";
184 prior(mii)->print(std::cerr,tm_));
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000185 lastDef_[virtReg] = mii;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000186 }
187 }
188 }
189
190 void handleDef(MachineBasicBlock& mbb,
191 MachineBasicBlock::iterator mii,
192 unsigned virtReg,
193 unsigned physReg) {
194 // check if we are replacing a previous mapping
195 if (p2vMap_[physReg] != virtReg)
196 vacatePhysReg(mbb, mii, physReg);
197
198 p2vMap_[physReg] = virtReg;
199 dirty_[physReg] = true;
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000200 lastDef_[virtReg] = mii;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000201 }
202
203 void eliminateVirtRegsInMbb(MachineBasicBlock& mbb) {
204 for (MachineBasicBlock::iterator mii = mbb.begin(),
205 mie = mbb.end(); mii != mie; ++mii) {
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000206
207 // if we have references to memory operands make sure
208 // we clear all physical registers that may contain
209 // the value of the spilled virtual register
210 VirtRegMap::MI2VirtMap::const_iterator i, e;
211 for (tie(i, e) = vrm_.getFoldedVirts(mii); i != e; ++i) {
212 unsigned physReg = vrm_.getPhys(i->second);
213 if (physReg) vacateJustPhysReg(mbb, mii, physReg);
214 }
215
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000216 // rewrite all used operands
217 for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
218 MachineOperand& op = mii->getOperand(i);
Alkis Evlogimenose3fcabe2004-02-25 23:21:52 +0000219 if (op.isRegister() && op.getReg() && op.isUse() &&
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000220 MRegisterInfo::isVirtualRegister(op.getReg())) {
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000221 unsigned virtReg = op.getReg();
222 unsigned physReg = vrm_.getPhys(virtReg);
223 handleUse(mbb, mii, virtReg, physReg);
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000224 mii->SetMachineOperandReg(i, physReg);
225 // mark as dirty if this is def&use
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000226 if (op.isDef()) {
227 dirty_[physReg] = true;
228 lastDef_[virtReg] = mii;
229 }
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000230 }
231 }
232
233 // spill implicit defs
234 const TargetInstrDescriptor& tid =tii_.get(mii->getOpcode());
235 for (const unsigned* id = tid.ImplicitDefs; *id; ++id)
236 vacatePhysReg(mbb, mii, *id);
237
238 // rewrite def operands (def&use was handled with the
239 // uses so don't check for those here)
240 for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
241 MachineOperand& op = mii->getOperand(i);
Alkis Evlogimenose3fcabe2004-02-25 23:21:52 +0000242 if (op.isRegister() && op.getReg() && !op.isUse())
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000243 if (MRegisterInfo::isPhysicalRegister(op.getReg()))
244 vacatePhysReg(mbb, mii, op.getReg());
245 else {
246 unsigned physReg = vrm_.getPhys(op.getReg());
247 handleDef(mbb, mii, op.getReg(), physReg);
248 mii->SetMachineOperandReg(i, physReg);
249 }
250 }
251
252 DEBUG(std::cerr << '\t'; mii->print(std::cerr, tm_));
253 }
254
255 for (unsigned i = 1, e = p2vMap_.size(); i != e; ++i)
256 vacateJustPhysReg(mbb, mbb.getFirstTerminator(), i);
257
258 }
259 };
260}
261
262
263void llvm::eliminateVirtRegs(MachineFunction& mf, const VirtRegMap& vrm)
264{
265 Spiller(mf, vrm).eliminateVirtRegs();
266}