blob: 2e6b16b7709c18f73784cfb88c62848f21f83c44 [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"
26#include "Support/STLExtras.h"
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000027#include <iostream>
28
29using namespace llvm;
30
31namespace {
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000032 Statistic<> numSpills("spiller", "Number of register spills");
33 Statistic<> numStores("spiller", "Number of stores added");
34 Statistic<> numLoads ("spiller", "Number of loads added");
35
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000036}
37
38int VirtRegMap::assignVirt2StackSlot(unsigned virtReg)
39{
40 assert(MRegisterInfo::isVirtualRegister(virtReg));
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000041 assert(v2ssMap_[virtReg] == NO_STACK_SLOT &&
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000042 "attempt to assign stack slot to already spilled register");
43 const TargetRegisterClass* rc =
44 mf_->getSSARegMap()->getRegClass(virtReg);
45 int frameIndex = mf_->getFrameInfo()->CreateStackObject(rc);
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000046 v2ssMap_[virtReg] = frameIndex;
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000047 ++numSpills;
48 return frameIndex;
49}
50
51std::ostream& llvm::operator<<(std::ostream& os, const VirtRegMap& vrm)
52{
53 const MRegisterInfo* mri = vrm.mf_->getTarget().getRegisterInfo();
54
55 std::cerr << "********** REGISTER MAP **********\n";
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000056 for (unsigned i = MRegisterInfo::FirstVirtualRegister,
57 e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000058 if (vrm.v2pMap_[i] != VirtRegMap::NO_PHYS_REG)
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000059 std::cerr << "[reg" << i << " -> "
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000060 << mri->getName(vrm.v2pMap_[i]) << "]\n";
61 }
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000062 for (unsigned i = MRegisterInfo::FirstVirtualRegister,
63 e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000064 if (vrm.v2ssMap_[i] != VirtRegMap::NO_STACK_SLOT)
Alkis Evlogimenos4d0d8642004-02-25 21:55:45 +000065 std::cerr << "[reg" << i << " -> fi#"
Alkis Evlogimenos34d9bc92004-02-23 23:08:11 +000066 << vrm.v2ssMap_[i] << "]\n";
67 }
68 return std::cerr << '\n';
69}
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000070
71namespace {
72
73 class Spiller {
74 typedef std::vector<unsigned> Phys2VirtMap;
75 typedef std::vector<bool> PhysFlag;
76
77 MachineFunction& mf_;
78 const TargetMachine& tm_;
79 const TargetInstrInfo& tii_;
80 const MRegisterInfo& mri_;
81 const VirtRegMap& vrm_;
82 Phys2VirtMap p2vMap_;
83 PhysFlag dirty_;
84
85 public:
86 Spiller(MachineFunction& mf, const VirtRegMap& vrm)
87 : mf_(mf),
88 tm_(mf_.getTarget()),
89 tii_(tm_.getInstrInfo()),
90 mri_(*tm_.getRegisterInfo()),
91 vrm_(vrm),
Alkis Evlogimenos8fa16e42004-02-26 23:22:23 +000092 p2vMap_(mri_.getNumRegs(), 0),
93 dirty_(mri_.getNumRegs(), false) {
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +000094 DEBUG(std::cerr << "********** REWRITE MACHINE CODE **********\n");
95 DEBUG(std::cerr << "********** Function: "
96 << mf_.getFunction()->getName() << '\n');
97 }
98
99 void eliminateVirtRegs() {
100 for (MachineFunction::iterator mbbi = mf_.begin(),
101 mbbe = mf_.end(); mbbi != mbbe; ++mbbi) {
Alkis Evlogimenos8fa16e42004-02-26 23:22:23 +0000102 DEBUG(std::cerr << mbbi->getBasicBlock()->getName() << ":\n");
103 eliminateVirtRegsInMbb(*mbbi);
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000104 // clear map and dirty flag
105 p2vMap_.assign(p2vMap_.size(), 0);
106 dirty_.assign(dirty_.size(), false);
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000107 }
108 }
109
110 private:
111 void vacateJustPhysReg(MachineBasicBlock& mbb,
112 MachineBasicBlock::iterator mii,
113 unsigned physReg) {
114 unsigned virtReg = p2vMap_[physReg];
115 if (dirty_[physReg] && vrm_.hasStackSlot(virtReg)) {
116 mri_.storeRegToStackSlot(mbb, mii, physReg,
117 vrm_.getStackSlot(virtReg),
118 mri_.getRegClass(physReg));
119 ++numStores;
120 DEBUG(std::cerr << "*\t"; prior(mii)->print(std::cerr, tm_));
121 }
122 p2vMap_[physReg] = 0;
123 dirty_[physReg] = false;
124 }
125
126 void vacatePhysReg(MachineBasicBlock& mbb,
127 MachineBasicBlock::iterator mii,
128 unsigned physReg) {
129 vacateJustPhysReg(mbb, mii, physReg);
130 for (const unsigned* as = mri_.getAliasSet(physReg); *as; ++as)
131 vacateJustPhysReg(mbb, mii, *as);
132 }
133
134 void handleUse(MachineBasicBlock& mbb,
135 MachineBasicBlock::iterator mii,
136 unsigned virtReg,
137 unsigned physReg) {
138 // check if we are replacing a previous mapping
139 if (p2vMap_[physReg] != virtReg) {
140 vacatePhysReg(mbb, mii, physReg);
141 p2vMap_[physReg] = virtReg;
142 // load if necessary
143 if (vrm_.hasStackSlot(virtReg)) {
144 mri_.loadRegFromStackSlot(mbb, mii, physReg,
145 vrm_.getStackSlot(virtReg),
146 mri_.getRegClass(physReg));
147 ++numLoads;
148 DEBUG(std::cerr << "*\t"; prior(mii)->print(std::cerr,tm_));
149 }
150 }
151 }
152
153 void handleDef(MachineBasicBlock& mbb,
154 MachineBasicBlock::iterator mii,
155 unsigned virtReg,
156 unsigned physReg) {
157 // check if we are replacing a previous mapping
158 if (p2vMap_[physReg] != virtReg)
159 vacatePhysReg(mbb, mii, physReg);
160
161 p2vMap_[physReg] = virtReg;
162 dirty_[physReg] = true;
163 }
164
165 void eliminateVirtRegsInMbb(MachineBasicBlock& mbb) {
166 for (MachineBasicBlock::iterator mii = mbb.begin(),
167 mie = mbb.end(); mii != mie; ++mii) {
168 // rewrite all used operands
169 for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
170 MachineOperand& op = mii->getOperand(i);
Alkis Evlogimenose3fcabe2004-02-25 23:21:52 +0000171 if (op.isRegister() && op.getReg() && op.isUse() &&
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000172 MRegisterInfo::isVirtualRegister(op.getReg())) {
173 unsigned physReg = vrm_.getPhys(op.getReg());
174 handleUse(mbb, mii, op.getReg(), physReg);
175 mii->SetMachineOperandReg(i, physReg);
176 // mark as dirty if this is def&use
177 if (op.isDef()) dirty_[physReg] = true;
178 }
179 }
180
181 // spill implicit defs
182 const TargetInstrDescriptor& tid =tii_.get(mii->getOpcode());
183 for (const unsigned* id = tid.ImplicitDefs; *id; ++id)
184 vacatePhysReg(mbb, mii, *id);
185
186 // rewrite def operands (def&use was handled with the
187 // uses so don't check for those here)
188 for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
189 MachineOperand& op = mii->getOperand(i);
Alkis Evlogimenose3fcabe2004-02-25 23:21:52 +0000190 if (op.isRegister() && op.getReg() && !op.isUse())
Alkis Evlogimenos0d6c5b62004-02-24 08:58:30 +0000191 if (MRegisterInfo::isPhysicalRegister(op.getReg()))
192 vacatePhysReg(mbb, mii, op.getReg());
193 else {
194 unsigned physReg = vrm_.getPhys(op.getReg());
195 handleDef(mbb, mii, op.getReg(), physReg);
196 mii->SetMachineOperandReg(i, physReg);
197 }
198 }
199
200 DEBUG(std::cerr << '\t'; mii->print(std::cerr, tm_));
201 }
202
203 for (unsigned i = 1, e = p2vMap_.size(); i != e; ++i)
204 vacateJustPhysReg(mbb, mbb.getFirstTerminator(), i);
205
206 }
207 };
208}
209
210
211void llvm::eliminateVirtRegs(MachineFunction& mf, const VirtRegMap& vrm)
212{
213 Spiller(mf, vrm).eliminateVirtRegs();
214}