VirtRegMap.h revision 5f37502bfbadfa65de087627bd67fd58bb03725c
134d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos//===-- llvm/CodeGen/VirtRegMap.h - Virtual Register Map -*- C++ -*--------===// 234d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos// 334d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos// The LLVM Compiler Infrastructure 434d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos// 534d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos// This file was developed by the LLVM research group and is distributed under 634d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos// the University of Illinois Open Source License. See LICENSE.TXT for details. 734d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos// 834d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos//===----------------------------------------------------------------------===// 934d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos// 1034d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos// This file implements a virtual register map. This maps virtual 1134d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos// registers to physical registers and virtual registers to stack 1234d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos// slots. It is created and updated by a register allocator and then 1334d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos// used by a machine code rewriter that adds spill code and rewrites 1434d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos// virtual into physical register references. 1534d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos// 1634d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos//===----------------------------------------------------------------------===// 1734d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 1834d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos#ifndef LLVM_CODEGEN_VIRTREGMAP_H 1934d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos#define LLVM_CODEGEN_VIRTREGMAP_H 2034d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 2134d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos#include "llvm/CodeGen/MachineFunction.h" 2234d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos#include "llvm/CodeGen/SSARegMap.h" 234d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos#include "Support/DenseMap.h" 2434d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos#include <climits> 255f37502bfbadfa65de087627bd67fd58bb03725cAlkis Evlogimenos#include <map> 2634d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 2734d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenosnamespace llvm { 2834d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 295f37502bfbadfa65de087627bd67fd58bb03725cAlkis Evlogimenos class MachineInstr; 305f37502bfbadfa65de087627bd67fd58bb03725cAlkis Evlogimenos 3134d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos class VirtRegMap { 3234d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos public: 334d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos typedef DenseMap<unsigned, VirtReg2IndexFunctor> Virt2PhysMap; 344d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos typedef DenseMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap; 355f37502bfbadfa65de087627bd67fd58bb03725cAlkis Evlogimenos typedef std::multimap<MachineInstr*, unsigned> MI2VirtMap; 36797428719f7001086b3c308b71c89cfca77d52b7Alkis Evlogimenos 3734d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos private: 3834d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos MachineFunction* mf_; 3934d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos Virt2PhysMap v2pMap_; 4034d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos Virt2StackSlotMap v2ssMap_; 415f37502bfbadfa65de087627bd67fd58bb03725cAlkis Evlogimenos MI2VirtMap mi2vMap_; 4234d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 4334d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos // do not implement 4434d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos VirtRegMap(const VirtRegMap& rhs); 4534d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos const VirtRegMap& operator=(const VirtRegMap& rhs); 4634d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 47e8124b9ddb332c8db5c9961323e6da3daf7251a3Alkis Evlogimenos enum { 48e8124b9ddb332c8db5c9961323e6da3daf7251a3Alkis Evlogimenos NO_PHYS_REG = 0, 49e8124b9ddb332c8db5c9961323e6da3daf7251a3Alkis Evlogimenos NO_STACK_SLOT = INT_MAX 50e8124b9ddb332c8db5c9961323e6da3daf7251a3Alkis Evlogimenos }; 51e8124b9ddb332c8db5c9961323e6da3daf7251a3Alkis Evlogimenos 5234d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos public: 5334d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos VirtRegMap(MachineFunction& mf) 5434d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos : mf_(&mf), 554d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos v2pMap_(NO_PHYS_REG), 564d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos v2ssMap_(NO_STACK_SLOT) { 574d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos v2pMap_.grow(mf.getSSARegMap()->getLastVirtReg()); 584d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos v2ssMap_.grow(mf.getSSARegMap()->getLastVirtReg()); 5934d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos } 6034d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 61ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos bool hasPhys(unsigned virtReg) const { 62ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos return getPhys(virtReg) != NO_PHYS_REG; 63ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos } 64ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos 65797428719f7001086b3c308b71c89cfca77d52b7Alkis Evlogimenos unsigned getPhys(unsigned virtReg) const { 6634d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos assert(MRegisterInfo::isVirtualRegister(virtReg)); 674d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos return v2pMap_[virtReg]; 6834d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos } 6934d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 7034d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos void assignVirt2Phys(unsigned virtReg, unsigned physReg) { 7134d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos assert(MRegisterInfo::isVirtualRegister(virtReg) && 7234d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos MRegisterInfo::isPhysicalRegister(physReg)); 734d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos assert(v2pMap_[virtReg] == NO_PHYS_REG && 7434d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos "attempt to assign physical register to already mapped " 7534d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos "virtual register"); 764d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos v2pMap_[virtReg] = physReg; 7734d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos } 7834d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 79fc54e83cea9c8bdc924981576caac92da690dbe6Alkis Evlogimenos void clearVirt(unsigned virtReg) { 8034d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos assert(MRegisterInfo::isVirtualRegister(virtReg)); 814d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos assert(v2pMap_[virtReg] != NO_PHYS_REG && 8234d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos "attempt to clear a not assigned virtual register"); 834d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos v2pMap_[virtReg] = NO_PHYS_REG; 8434d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos } 8534d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 86ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos bool hasStackSlot(unsigned virtReg) const { 87ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos return getStackSlot(virtReg) != NO_STACK_SLOT; 88ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos } 89ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos 90797428719f7001086b3c308b71c89cfca77d52b7Alkis Evlogimenos int getStackSlot(unsigned virtReg) const { 9134d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos assert(MRegisterInfo::isVirtualRegister(virtReg)); 924d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos return v2ssMap_[virtReg]; 9334d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos } 9434d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 9534d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos int assignVirt2StackSlot(unsigned virtReg); 9634d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 975f37502bfbadfa65de087627bd67fd58bb03725cAlkis Evlogimenos void virtFolded(unsigned virtReg, 985f37502bfbadfa65de087627bd67fd58bb03725cAlkis Evlogimenos MachineInstr* oldMI, 995f37502bfbadfa65de087627bd67fd58bb03725cAlkis Evlogimenos MachineInstr* newMI); 1005f37502bfbadfa65de087627bd67fd58bb03725cAlkis Evlogimenos 1015f37502bfbadfa65de087627bd67fd58bb03725cAlkis Evlogimenos std::pair<MI2VirtMap::const_iterator, MI2VirtMap::const_iterator> 1025f37502bfbadfa65de087627bd67fd58bb03725cAlkis Evlogimenos getFoldedVirts(MachineInstr* MI) const { 1035f37502bfbadfa65de087627bd67fd58bb03725cAlkis Evlogimenos return mi2vMap_.equal_range(MI); 1045f37502bfbadfa65de087627bd67fd58bb03725cAlkis Evlogimenos } 1055f37502bfbadfa65de087627bd67fd58bb03725cAlkis Evlogimenos 10634d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos friend std::ostream& operator<<(std::ostream& os, const VirtRegMap& li); 10734d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos }; 10834d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 10934d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos std::ostream& operator<<(std::ostream& os, const VirtRegMap& li); 11034d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 1110d6c5b6489b9abb634a1506d183ba47f1bf4d1f0Alkis Evlogimenos void eliminateVirtRegs(MachineFunction& mf, const VirtRegMap& vrm); 1120d6c5b6489b9abb634a1506d183ba47f1bf4d1f0Alkis Evlogimenos 11334d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos} // End llvm namespace 11434d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos 11534d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos#endif 116