VirtRegMap.cpp revision 5f37502bfbadfa65de087627bd67fd58bb03725c
1//===-- 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//
10// 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.
15//
16//===----------------------------------------------------------------------===//
17
18#define DEBUG_TYPE "regalloc"
19#include "VirtRegMap.h"
20#include "llvm/Function.h"
21#include "llvm/CodeGen/MachineFrameInfo.h"
22#include "llvm/CodeGen/MachineInstr.h"
23#include "llvm/Target/TargetMachine.h"
24#include "llvm/Target/TargetInstrInfo.h"
25#include "Support/Statistic.h"
26#include "Support/Debug.h"
27#include "Support/DenseMap.h"
28#include "Support/STLExtras.h"
29#include <iostream>
30
31using namespace llvm;
32
33namespace {
34    Statistic<> numSpills("spiller", "Number of register spills");
35    Statistic<> numStores("spiller", "Number of stores added");
36    Statistic<> numLoads ("spiller", "Number of loads added");
37
38}
39
40int VirtRegMap::assignVirt2StackSlot(unsigned virtReg)
41{
42    assert(MRegisterInfo::isVirtualRegister(virtReg));
43    assert(v2ssMap_[virtReg] == NO_STACK_SLOT &&
44           "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);
48    v2ssMap_[virtReg] = frameIndex;
49    ++numSpills;
50    return frameIndex;
51}
52
53void 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
71std::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";
76    for (unsigned i = MRegisterInfo::FirstVirtualRegister,
77             e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
78        if (vrm.v2pMap_[i] != VirtRegMap::NO_PHYS_REG)
79            std::cerr << "[reg" << i << " -> "
80                      << mri->getName(vrm.v2pMap_[i]) << "]\n";
81    }
82    for (unsigned i = MRegisterInfo::FirstVirtualRegister,
83             e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
84        if (vrm.v2ssMap_[i] != VirtRegMap::NO_STACK_SLOT)
85            std::cerr << "[reg" << i << " -> fi#"
86                      << vrm.v2ssMap_[i] << "]\n";
87    }
88    return std::cerr << '\n';
89}
90
91namespace {
92
93    class Spiller {
94        typedef std::vector<unsigned> Phys2VirtMap;
95        typedef std::vector<bool> PhysFlag;
96        typedef DenseMap<MachineInstr*, VirtReg2IndexFunctor> Virt2MI;
97
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_;
105        Virt2MI lastDef_;
106
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),
114              p2vMap_(mri_.getNumRegs(), 0),
115              dirty_(mri_.getNumRegs(), false),
116              lastDef_() {
117            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) {
125                lastDef_.grow(mf_.getSSARegMap()->getLastVirtReg());
126                DEBUG(std::cerr << mbbi->getBasicBlock()->getName() << ":\n");
127                eliminateVirtRegsInMbb(*mbbi);
128                // clear map, dirty flag and last ref
129                p2vMap_.assign(p2vMap_.size(), 0);
130                dirty_.assign(dirty_.size(), false);
131                lastDef_.clear();
132            }
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)) {
141                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,
148                                         vrm_.getStackSlot(virtReg),
149                                         mri_.getRegClass(physReg));
150                ++numStores;
151                DEBUG(std::cerr << "added: ";
152                      prior(nextLastRef)->print(std::cerr, tm_);
153                      std::cerr << "after: ";
154                      lastDef->print(std::cerr, tm_));
155                lastDef_[virtReg] = 0;
156            }
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;
183                    DEBUG(std::cerr << "added: ";
184                          prior(mii)->print(std::cerr,tm_));
185                    lastDef_[virtReg] = mii;
186                }
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;
200            lastDef_[virtReg] = mii;
201        }
202
203        void eliminateVirtRegsInMbb(MachineBasicBlock& mbb) {
204            for (MachineBasicBlock::iterator mii = mbb.begin(),
205                     mie = mbb.end(); mii != mie; ++mii) {
206
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
216                // rewrite all used operands
217                for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
218                    MachineOperand& op = mii->getOperand(i);
219                    if (op.isRegister() && op.getReg() && op.isUse() &&
220                        MRegisterInfo::isVirtualRegister(op.getReg())) {
221                        unsigned virtReg = op.getReg();
222                        unsigned physReg = vrm_.getPhys(virtReg);
223                        handleUse(mbb, mii, virtReg, physReg);
224                        mii->SetMachineOperandReg(i, physReg);
225                        // mark as dirty if this is def&use
226                        if (op.isDef()) {
227                            dirty_[physReg] = true;
228                            lastDef_[virtReg] = mii;
229                        }
230                    }
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);
242                    if (op.isRegister() && op.getReg() && !op.isUse())
243                        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}
267