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