VirtRegMap.cpp revision 8fa16e47f88975b577fe1cafce1a366b78b2c340
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/Target/TargetMachine.h" 23#include "llvm/Target/TargetInstrInfo.h" 24#include "Support/Statistic.h" 25#include "Support/Debug.h" 26#include "Support/STLExtras.h" 27#include <iostream> 28 29using namespace llvm; 30 31namespace { 32 Statistic<> numSpills("spiller", "Number of register spills"); 33 Statistic<> numStores("spiller", "Number of stores added"); 34 Statistic<> numLoads ("spiller", "Number of loads added"); 35 36} 37 38int VirtRegMap::assignVirt2StackSlot(unsigned virtReg) 39{ 40 assert(MRegisterInfo::isVirtualRegister(virtReg)); 41 assert(v2ssMap_[virtReg] == NO_STACK_SLOT && 42 "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); 46 v2ssMap_[virtReg] = frameIndex; 47 ++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"; 56 for (unsigned i = MRegisterInfo::FirstVirtualRegister, 57 e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) { 58 if (vrm.v2pMap_[i] != VirtRegMap::NO_PHYS_REG) 59 std::cerr << "[reg" << i << " -> " 60 << mri->getName(vrm.v2pMap_[i]) << "]\n"; 61 } 62 for (unsigned i = MRegisterInfo::FirstVirtualRegister, 63 e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) { 64 if (vrm.v2ssMap_[i] != VirtRegMap::NO_STACK_SLOT) 65 std::cerr << "[reg" << i << " -> fi#" 66 << vrm.v2ssMap_[i] << "]\n"; 67 } 68 return std::cerr << '\n'; 69} 70 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), 92 p2vMap_(mri_.getNumRegs(), 0), 93 dirty_(mri_.getNumRegs(), false) { 94 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) { 102 DEBUG(std::cerr << mbbi->getBasicBlock()->getName() << ":\n"); 103 eliminateVirtRegsInMbb(*mbbi); 104 // clear map and dirty flag 105 p2vMap_.assign(p2vMap_.size(), 0); 106 dirty_.assign(dirty_.size(), false); 107 } 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); 171 if (op.isRegister() && op.getReg() && op.isUse() && 172 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); 190 if (op.isRegister() && op.getReg() && !op.isUse()) 191 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} 215