blob: e517cb371e65b5c3ee874c1befaa2d742061f84d [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"
22#include "llvm/Target/TargetMachine.h"
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000023#include "llvm/Target/TargetInstrInfo.h"
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000024#include "Support/Statistic.h"
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000025#include "Support/Debug.h"
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +000026#include "Support/DenseMap.h"
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000027#include "Support/STLExtras.h"
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000028#include <iostream>
29
30using namespace llvm;
31
32namespace {
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000033 Statistic<> numSpills("spiller", "Number of register spills");
34 Statistic<> numStores("spiller", "Number of stores added");
35 Statistic<> numLoads ("spiller", "Number of loads added");
36
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000037}
38
39int VirtRegMap::assignVirt2StackSlot(unsigned virtReg)
40{
41 assert(MRegisterInfo::isVirtualRegister(virtReg));
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000042 assert(v2ssMap_[virtReg] == NO_STACK_SLOT &&
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000043 "attempt to assign stack slot to already spilled register");
44 const TargetRegisterClass* rc =
45 mf_->getSSARegMap()->getRegClass(virtReg);
46 int frameIndex = mf_->getFrameInfo()->CreateStackObject(rc);
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000047 v2ssMap_[virtReg] = frameIndex;
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000048 ++numSpills;
49 return frameIndex;
50}
51
52std::ostream& llvm::operator<<(std::ostream& os, const VirtRegMap& vrm)
53{
54 const MRegisterInfo* mri = vrm.mf_->getTarget().getRegisterInfo();
55
56 std::cerr << "********** REGISTER MAP **********\n";
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000057 for (unsigned i = MRegisterInfo::FirstVirtualRegister,
58 e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000059 if (vrm.v2pMap_[i] != VirtRegMap::NO_PHYS_REG)
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000060 std::cerr << "[reg" << i << " -> "
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000061 << mri->getName(vrm.v2pMap_[i]) << "]\n";
62 }
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000063 for (unsigned i = MRegisterInfo::FirstVirtualRegister,
64 e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000065 if (vrm.v2ssMap_[i] != VirtRegMap::NO_STACK_SLOT)
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000066 std::cerr << "[reg" << i << " -> fi#"
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000067 << vrm.v2ssMap_[i] << "]\n";
68 }
69 return std::cerr << '\n';
70}
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000071
72namespace {
73
74 class Spiller {
75 typedef std::vector<unsigned> Phys2VirtMap;
76 typedef std::vector<bool> PhysFlag;
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +000077 typedef DenseMap<MachineInstr*, VirtReg2IndexFunctor> Virt2MI;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000078
79 MachineFunction& mf_;
80 const TargetMachine& tm_;
81 const TargetInstrInfo& tii_;
82 const MRegisterInfo& mri_;
83 const VirtRegMap& vrm_;
84 Phys2VirtMap p2vMap_;
85 PhysFlag dirty_;
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +000086 Virt2MI lastDef_;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000087
88 public:
89 Spiller(MachineFunction& mf, const VirtRegMap& vrm)
90 : mf_(mf),
91 tm_(mf_.getTarget()),
92 tii_(tm_.getInstrInfo()),
93 mri_(*tm_.getRegisterInfo()),
94 vrm_(vrm),
Alkis Evlogimenos8fa16e42004-02-26 23:22:23 +000095 p2vMap_(mri_.getNumRegs(), 0),
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +000096 dirty_(mri_.getNumRegs(), false),
97 lastDef_() {
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000098 DEBUG(std::cerr << "********** REWRITE MACHINE CODE **********\n");
99 DEBUG(std::cerr << "********** Function: "
100 << mf_.getFunction()->getName() << '\n');
101 }
102
103 void eliminateVirtRegs() {
104 for (MachineFunction::iterator mbbi = mf_.begin(),
105 mbbe = mf_.end(); mbbi != mbbe; ++mbbi) {
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000106 lastDef_.grow(mf_.getSSARegMap()->getLastVirtReg());
Alkis Evlogimenos8fa16e42004-02-26 23:22:23 +0000107 DEBUG(std::cerr << mbbi->getBasicBlock()->getName() << ":\n");
108 eliminateVirtRegsInMbb(*mbbi);
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000109 // clear map, dirty flag and last ref
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000110 p2vMap_.assign(p2vMap_.size(), 0);
111 dirty_.assign(dirty_.size(), false);
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000112 lastDef_.clear();
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000113 }
114 }
115
116 private:
117 void vacateJustPhysReg(MachineBasicBlock& mbb,
118 MachineBasicBlock::iterator mii,
119 unsigned physReg) {
120 unsigned virtReg = p2vMap_[physReg];
121 if (dirty_[physReg] && vrm_.hasStackSlot(virtReg)) {
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000122 assert(lastDef_[virtReg] && "virtual register is mapped "
123 "to a register and but was not defined!");
124 MachineBasicBlock::iterator lastDef = lastDef_[virtReg];
125 MachineBasicBlock::iterator nextLastRef = next(lastDef);
126 mri_.storeRegToStackSlot(*lastDef->getParent(),
127 nextLastRef,
128 physReg,
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000129 vrm_.getStackSlot(virtReg),
130 mri_.getRegClass(physReg));
131 ++numStores;
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000132 DEBUG(std::cerr << "\t\tadded: ";
133 prior(nextLastRef)->print(std::cerr, tm_);
134 std::cerr << "\t\tafter: ";
135 lastDef->print(std::cerr, tm_));
136 lastDef_[virtReg] = 0;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000137 }
138 p2vMap_[physReg] = 0;
139 dirty_[physReg] = false;
140 }
141
142 void vacatePhysReg(MachineBasicBlock& mbb,
143 MachineBasicBlock::iterator mii,
144 unsigned physReg) {
145 vacateJustPhysReg(mbb, mii, physReg);
146 for (const unsigned* as = mri_.getAliasSet(physReg); *as; ++as)
147 vacateJustPhysReg(mbb, mii, *as);
148 }
149
150 void handleUse(MachineBasicBlock& mbb,
151 MachineBasicBlock::iterator mii,
152 unsigned virtReg,
153 unsigned physReg) {
154 // check if we are replacing a previous mapping
155 if (p2vMap_[physReg] != virtReg) {
156 vacatePhysReg(mbb, mii, physReg);
157 p2vMap_[physReg] = virtReg;
158 // load if necessary
159 if (vrm_.hasStackSlot(virtReg)) {
160 mri_.loadRegFromStackSlot(mbb, mii, physReg,
161 vrm_.getStackSlot(virtReg),
162 mri_.getRegClass(physReg));
163 ++numLoads;
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000164 DEBUG(std::cerr << "\t\tadded: ";
165 prior(mii)->print(std::cerr,tm_);
166 std::cerr << "\t\tbefore: ";
167 mii->print(std::cerr, tm_));
168 lastDef_[virtReg] = mii;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000169 }
170 }
171 }
172
173 void handleDef(MachineBasicBlock& mbb,
174 MachineBasicBlock::iterator mii,
175 unsigned virtReg,
176 unsigned physReg) {
177 // check if we are replacing a previous mapping
178 if (p2vMap_[physReg] != virtReg)
179 vacatePhysReg(mbb, mii, physReg);
180
181 p2vMap_[physReg] = virtReg;
182 dirty_[physReg] = true;
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000183 lastDef_[virtReg] = mii;
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000184 }
185
186 void eliminateVirtRegsInMbb(MachineBasicBlock& mbb) {
187 for (MachineBasicBlock::iterator mii = mbb.begin(),
188 mie = mbb.end(); mii != mie; ++mii) {
189 // rewrite all used operands
190 for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
191 MachineOperand& op = mii->getOperand(i);
Alkis Evlogimenose3fcabe2004-02-25 23:21:52 +0000192 if (op.isRegister() && op.getReg() && op.isUse() &&
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000193 MRegisterInfo::isVirtualRegister(op.getReg())) {
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000194 unsigned virtReg = op.getReg();
195 unsigned physReg = vrm_.getPhys(virtReg);
196 handleUse(mbb, mii, virtReg, physReg);
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000197 mii->SetMachineOperandReg(i, physReg);
198 // mark as dirty if this is def&use
Alkis Evlogimenos57af2cf2004-02-27 04:51:35 +0000199 if (op.isDef()) {
200 dirty_[physReg] = true;
201 lastDef_[virtReg] = mii;
202 }
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000203 }
204 }
205
206 // spill implicit defs
207 const TargetInstrDescriptor& tid =tii_.get(mii->getOpcode());
208 for (const unsigned* id = tid.ImplicitDefs; *id; ++id)
209 vacatePhysReg(mbb, mii, *id);
210
211 // rewrite def operands (def&use was handled with the
212 // uses so don't check for those here)
213 for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
214 MachineOperand& op = mii->getOperand(i);
Alkis Evlogimenose3fcabe2004-02-25 23:21:52 +0000215 if (op.isRegister() && op.getReg() && !op.isUse())
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000216 if (MRegisterInfo::isPhysicalRegister(op.getReg()))
217 vacatePhysReg(mbb, mii, op.getReg());
218 else {
219 unsigned physReg = vrm_.getPhys(op.getReg());
220 handleDef(mbb, mii, op.getReg(), physReg);
221 mii->SetMachineOperandReg(i, physReg);
222 }
223 }
224
225 DEBUG(std::cerr << '\t'; mii->print(std::cerr, tm_));
226 }
227
228 for (unsigned i = 1, e = p2vMap_.size(); i != e; ++i)
229 vacateJustPhysReg(mbb, mbb.getFirstTerminator(), i);
230
231 }
232 };
233}
234
235
236void llvm::eliminateVirtRegs(MachineFunction& mf, const VirtRegMap& vrm)
237{
238 Spiller(mf, vrm).eliminateVirtRegs();
239}