VirtRegMap.h revision 4d0d864be3d9a698c4edfe36961a22126f041298
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>
2534d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos
2634d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenosnamespace llvm {
2734d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos
2834d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos    class VirtRegMap {
2934d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos    public:
304d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos        typedef DenseMap<unsigned, VirtReg2IndexFunctor> Virt2PhysMap;
314d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos        typedef DenseMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap;
32797428719f7001086b3c308b71c89cfca77d52b7Alkis Evlogimenos
3334d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos    private:
3434d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        MachineFunction* mf_;
3534d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        Virt2PhysMap v2pMap_;
3634d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        Virt2StackSlotMap v2ssMap_;
3734d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos
3834d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        // do not implement
3934d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        VirtRegMap(const VirtRegMap& rhs);
4034d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        const VirtRegMap& operator=(const VirtRegMap& rhs);
4134d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos
42e8124b9ddb332c8db5c9961323e6da3daf7251a3Alkis Evlogimenos        enum {
43e8124b9ddb332c8db5c9961323e6da3daf7251a3Alkis Evlogimenos            NO_PHYS_REG   = 0,
44e8124b9ddb332c8db5c9961323e6da3daf7251a3Alkis Evlogimenos            NO_STACK_SLOT = INT_MAX
45e8124b9ddb332c8db5c9961323e6da3daf7251a3Alkis Evlogimenos        };
46e8124b9ddb332c8db5c9961323e6da3daf7251a3Alkis Evlogimenos
4734d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos    public:
4834d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        VirtRegMap(MachineFunction& mf)
4934d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos            : mf_(&mf),
504d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos              v2pMap_(NO_PHYS_REG),
514d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos              v2ssMap_(NO_STACK_SLOT) {
524d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos            v2pMap_.grow(mf.getSSARegMap()->getLastVirtReg());
534d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos            v2ssMap_.grow(mf.getSSARegMap()->getLastVirtReg());
5434d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        }
5534d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos
56ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos        bool hasPhys(unsigned virtReg) const {
57ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos            return getPhys(virtReg) != NO_PHYS_REG;
58ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos        }
59ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos
60797428719f7001086b3c308b71c89cfca77d52b7Alkis Evlogimenos        unsigned getPhys(unsigned virtReg) const {
6134d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos            assert(MRegisterInfo::isVirtualRegister(virtReg));
624d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos            return v2pMap_[virtReg];
6334d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        }
6434d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos
6534d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        void assignVirt2Phys(unsigned virtReg, unsigned physReg) {
6634d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos            assert(MRegisterInfo::isVirtualRegister(virtReg) &&
6734d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos                   MRegisterInfo::isPhysicalRegister(physReg));
684d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos            assert(v2pMap_[virtReg] == NO_PHYS_REG &&
6934d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos                   "attempt to assign physical register to already mapped "
7034d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos                   "virtual register");
714d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos            v2pMap_[virtReg] = physReg;
7234d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        }
7334d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos
7434d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        void clearVirtReg(unsigned virtReg) {
7534d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos            assert(MRegisterInfo::isVirtualRegister(virtReg));
764d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos            assert(v2pMap_[virtReg] != NO_PHYS_REG &&
7734d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos                   "attempt to clear a not assigned virtual register");
784d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos            v2pMap_[virtReg] = NO_PHYS_REG;
7934d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        }
8034d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos
81ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos        bool hasStackSlot(unsigned virtReg) const {
82ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos            return getStackSlot(virtReg) != NO_STACK_SLOT;
83ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos        }
84ec8b8bb9abffdcc22373a7f28803c18ed8efa102Alkis Evlogimenos
85797428719f7001086b3c308b71c89cfca77d52b7Alkis Evlogimenos        int getStackSlot(unsigned virtReg) const {
8634d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos            assert(MRegisterInfo::isVirtualRegister(virtReg));
874d0d864be3d9a698c4edfe36961a22126f041298Alkis Evlogimenos            return v2ssMap_[virtReg];
8834d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        }
8934d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos
9034d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        int assignVirt2StackSlot(unsigned virtReg);
9134d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos
9234d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos        friend std::ostream& operator<<(std::ostream& os, const VirtRegMap& li);
9334d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos    };
9434d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos
9534d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos    std::ostream& operator<<(std::ostream& os, const VirtRegMap& li);
9634d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos
970d6c5b6489b9abb634a1506d183ba47f1bf4d1f0Alkis Evlogimenos    void eliminateVirtRegs(MachineFunction& mf, const VirtRegMap& vrm);
980d6c5b6489b9abb634a1506d183ba47f1bf4d1f0Alkis Evlogimenos
9934d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos} // End llvm namespace
10034d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos
10134d9bc9f168d17c52eb57e024580bd9499695f91Alkis Evlogimenos#endif
102