1f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===-- llvm/CodeGen/VirtRegMap.h - Virtual Register Map -*- C++ -*--------===// 2f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 3f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// The LLVM Compiler Infrastructure 4f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 5f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file is distributed under the University of Illinois Open Source 6f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// License. See LICENSE.TXT for details. 7f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 8f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===// 9f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 10f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file implements a virtual register map. This maps virtual registers to 11f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// physical registers and virtual registers to stack slots. It is created and 12f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// updated by a register allocator and then used by a machine code rewriter that 13f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// adds spill code and rewrites virtual into physical register references. 14f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 15f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===// 16f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 17f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef LLVM_CODEGEN_VIRTREGMAP_H 18f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define LLVM_CODEGEN_VIRTREGMAP_H 19f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 20f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/IndexedMap.h" 21f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/CodeGen/MachineFunctionPass.h" 22f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Target/TargetRegisterInfo.h" 23f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 24f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace llvm { 25f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot class MachineInstr; 26f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot class MachineFunction; 27f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot class MachineRegisterInfo; 28f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot class TargetInstrInfo; 29f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot class raw_ostream; 30f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot class SlotIndexes; 31f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 32f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot class VirtRegMap : public MachineFunctionPass { 33f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot public: 34f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot enum { 35f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot NO_PHYS_REG = 0, 36f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot NO_STACK_SLOT = (1L << 30)-1, 37f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot MAX_STACK_SLOT = (1L << 18)-1 38f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 39f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 40f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot private: 41f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot MachineRegisterInfo *MRI; 42f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const TargetInstrInfo *TII; 43f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const TargetRegisterInfo *TRI; 44f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot MachineFunction *MF; 45f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 46f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Virt2PhysMap - This is a virtual to physical register 47f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// mapping. Each virtual register is required to have an entry in 48f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// it; even spilled virtual registers (the register mapped to a 49f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// spilled register is the temporary used to load it from the 50f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// stack). 51f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2PhysMap; 52f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 53f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Virt2StackSlotMap - This is virtual register to stack slot 54f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// mapping. Each spilled virtual register has an entry in it 55f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// which corresponds to the stack slot this register is spilled 56f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// at. 57f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap; 58f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 59f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Virt2SplitMap - This is virtual register to splitted virtual register 60f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// mapping. 61f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2SplitMap; 62f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 63f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// createSpillSlot - Allocate a spill slot for RC from MFI. 64f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned createSpillSlot(const TargetRegisterClass *RC); 65f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 66f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot VirtRegMap(const VirtRegMap&) = delete; 67f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void operator=(const VirtRegMap&) = delete; 68f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 69f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot public: 70f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static char ID; 71f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot VirtRegMap() : MachineFunctionPass(ID), Virt2PhysMap(NO_PHYS_REG), 72f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) { } 73f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool runOnMachineFunction(MachineFunction &MF) override; 74f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 75f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void getAnalysisUsage(AnalysisUsage &AU) const override { 76f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot AU.setPreservesAll(); 77f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot MachineFunctionPass::getAnalysisUsage(AU); 78f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 79f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 80f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot MachineFunction &getMachineFunction() const { 81f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(MF && "getMachineFunction called before runOnMachineFunction"); 82f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return *MF; 83f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 84f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 85f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot MachineRegisterInfo &getRegInfo() const { return *MRI; } 86f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; } 87f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 88f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void grow(); 89f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 90f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// @brief returns true if the specified virtual register is 91f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// mapped to a physical register 92f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool hasPhys(unsigned virtReg) const { 93f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return getPhys(virtReg) != NO_PHYS_REG; 94f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 95f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 96f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// @brief returns the physical register mapped to the specified 97f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// virtual register 98f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned getPhys(unsigned virtReg) const { 99f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(TargetRegisterInfo::isVirtualRegister(virtReg)); 100f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Virt2PhysMap[virtReg]; 101f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 102f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 103f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// @brief creates a mapping for the specified virtual register to 104f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// the specified physical register 105f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void assignVirt2Phys(unsigned virtReg, MCPhysReg physReg); 106f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 107f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// @brief clears the specified virtual register's, physical 108f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// register mapping 109f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void clearVirt(unsigned virtReg) { 110f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(TargetRegisterInfo::isVirtualRegister(virtReg)); 111f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(Virt2PhysMap[virtReg] != NO_PHYS_REG && 112f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot "attempt to clear a not assigned virtual register"); 113f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Virt2PhysMap[virtReg] = NO_PHYS_REG; 114f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 115f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 116f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// @brief clears all virtual to physical register mappings 117f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void clearAllVirt() { 118f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Virt2PhysMap.clear(); 119f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot grow(); 120f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 121f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 122f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// @brief returns true if VirtReg is assigned to its preferred physreg. 123f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool hasPreferredPhys(unsigned VirtReg); 124f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 125f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// @brief returns true if VirtReg has a known preferred register. 126f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// This returns false if VirtReg has a preference that is a virtual 127f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// register that hasn't been assigned yet. 128f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool hasKnownPreference(unsigned VirtReg); 129f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 130f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// @brief records virtReg is a split live interval from SReg. 131f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setIsSplitFromReg(unsigned virtReg, unsigned SReg) { 132f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Virt2SplitMap[virtReg] = SReg; 133f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 134f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 135f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// @brief returns the live interval virtReg is split from. 136f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned getPreSplitReg(unsigned virtReg) const { 137f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Virt2SplitMap[virtReg]; 138f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 139f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 140f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// getOriginal - Return the original virtual register that VirtReg descends 141f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// from through splitting. 142f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// A register that was not created by splitting is its own original. 143f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// This operation is idempotent. 144f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned getOriginal(unsigned VirtReg) const { 145f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned Orig = getPreSplitReg(VirtReg); 146f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Orig ? Orig : VirtReg; 147f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 148f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 149f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// @brief returns true if the specified virtual register is not 150f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// mapped to a stack slot or rematerialized. 151f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isAssignedReg(unsigned virtReg) const { 152f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (getStackSlot(virtReg) == NO_STACK_SLOT) 153f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return true; 154f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // Split register can be assigned a physical register as well as a 155f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // stack slot or remat id. 156f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg] != NO_PHYS_REG); 157f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 158f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 159f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// @brief returns the stack slot mapped to the specified virtual 160f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// register 161f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot int getStackSlot(unsigned virtReg) const { 162f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(TargetRegisterInfo::isVirtualRegister(virtReg)); 163f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Virt2StackSlotMap[virtReg]; 164f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 165f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 166f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// @brief create a mapping for the specifed virtual register to 167f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// the next available stack slot 168f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot int assignVirt2StackSlot(unsigned virtReg); 169f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// @brief create a mapping for the specified virtual register to 170f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// the specified stack slot 171f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void assignVirt2StackSlot(unsigned virtReg, int frameIndex); 172f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 173f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void print(raw_ostream &OS, const Module* M = nullptr) const override; 174f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void dump() const; 175f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 176f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 177f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) { 178f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot VRM.print(OS); 179f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return OS; 180f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 181f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // End llvm namespace 182f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 183f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif 184