X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FVirtRegMap.h;h=7974dda66a5f9a0ab4aa5081036080e3a95a0df9;hb=3e2d76c946ba753c2b11af192a52e25b6f9b46ff;hp=664ca628cf74a7d462d9aa16722f1948d371586b;hpb=8c4d88d3697835371ecf6823f4142af13603ad2d;p=oota-llvm.git diff --git a/lib/CodeGen/VirtRegMap.h b/lib/CodeGen/VirtRegMap.h index 664ca628cf7..7974dda66a5 100644 --- a/lib/CodeGen/VirtRegMap.h +++ b/lib/CodeGen/VirtRegMap.h @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -17,112 +17,174 @@ #ifndef LLVM_CODEGEN_VIRTREGMAP_H #define LLVM_CODEGEN_VIRTREGMAP_H -#include "llvm/Target/MRegisterInfo.h" -#include "llvm/ADT/DenseMap.h" -#include +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/ADT/IndexedMap.h" namespace llvm { class MachineInstr; + class MachineFunction; + class MachineRegisterInfo; + class TargetInstrInfo; + class raw_ostream; + class SlotIndexes; - class VirtRegMap { + class VirtRegMap : public MachineFunctionPass { public: - typedef DenseMap Virt2PhysMap; - typedef DenseMap Virt2StackSlotMap; - typedef std::multimap MI2VirtMap; - - private: - MachineFunction* mf_; - Virt2PhysMap v2pMap_; - Virt2StackSlotMap v2ssMap_; - MI2VirtMap mi2vMap_; - - VirtRegMap(const VirtRegMap&); // DO NOT IMPLEMENT - void operator=(const VirtRegMap&); // DO NOT IMPLEMENT - enum { NO_PHYS_REG = 0, - NO_STACK_SLOT = ~0 >> 1 + NO_STACK_SLOT = (1L << 30)-1, + MAX_STACK_SLOT = (1L << 18)-1 }; + private: + MachineRegisterInfo *MRI; + const TargetInstrInfo *TII; + const TargetRegisterInfo *TRI; + MachineFunction *MF; + + /// Virt2PhysMap - This is a virtual to physical register + /// mapping. Each virtual register is required to have an entry in + /// it; even spilled virtual registers (the register mapped to a + /// spilled register is the temporary used to load it from the + /// stack). + IndexedMap Virt2PhysMap; + + /// Virt2StackSlotMap - This is virtual register to stack slot + /// mapping. Each spilled virtual register has an entry in it + /// which corresponds to the stack slot this register is spilled + /// at. + IndexedMap Virt2StackSlotMap; + + /// Virt2SplitMap - This is virtual register to splitted virtual register + /// mapping. + IndexedMap Virt2SplitMap; + + /// createSpillSlot - Allocate a spill slot for RC from MFI. + unsigned createSpillSlot(const TargetRegisterClass *RC); + + VirtRegMap(const VirtRegMap&) LLVM_DELETED_FUNCTION; + void operator=(const VirtRegMap&) LLVM_DELETED_FUNCTION; + public: - VirtRegMap(MachineFunction& mf) - : mf_(&mf), v2pMap_(NO_PHYS_REG), v2ssMap_(NO_STACK_SLOT) { - grow(); + static char ID; + VirtRegMap() : MachineFunctionPass(ID), Virt2PhysMap(NO_PHYS_REG), + Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) { } + virtual bool runOnMachineFunction(MachineFunction &MF); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(AU); } + MachineFunction &getMachineFunction() const { + assert(MF && "getMachineFunction called before runOnMachineFunction"); + return *MF; + } + + MachineRegisterInfo &getRegInfo() const { return *MRI; } + const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; } + void grow(); + /// @brief returns true if the specified virtual register is + /// mapped to a physical register bool hasPhys(unsigned virtReg) const { return getPhys(virtReg) != NO_PHYS_REG; } + /// @brief returns the physical register mapped to the specified + /// virtual register unsigned getPhys(unsigned virtReg) const { - assert(MRegisterInfo::isVirtualRegister(virtReg)); - return v2pMap_[virtReg]; + assert(TargetRegisterInfo::isVirtualRegister(virtReg)); + return Virt2PhysMap[virtReg]; } + /// @brief creates a mapping for the specified virtual register to + /// the specified physical register void assignVirt2Phys(unsigned virtReg, unsigned physReg) { - assert(MRegisterInfo::isVirtualRegister(virtReg) && - MRegisterInfo::isPhysicalRegister(physReg)); - assert(v2pMap_[virtReg] == NO_PHYS_REG && + assert(TargetRegisterInfo::isVirtualRegister(virtReg) && + TargetRegisterInfo::isPhysicalRegister(physReg)); + assert(Virt2PhysMap[virtReg] == NO_PHYS_REG && "attempt to assign physical register to already mapped " "virtual register"); - v2pMap_[virtReg] = physReg; + Virt2PhysMap[virtReg] = physReg; } + /// @brief clears the specified virtual register's, physical + /// register mapping void clearVirt(unsigned virtReg) { - assert(MRegisterInfo::isVirtualRegister(virtReg)); - assert(v2pMap_[virtReg] != NO_PHYS_REG && + assert(TargetRegisterInfo::isVirtualRegister(virtReg)); + assert(Virt2PhysMap[virtReg] != NO_PHYS_REG && "attempt to clear a not assigned virtual register"); - v2pMap_[virtReg] = NO_PHYS_REG; + Virt2PhysMap[virtReg] = NO_PHYS_REG; } + /// @brief clears all virtual to physical register mappings void clearAllVirt() { - v2pMap_.clear(); + Virt2PhysMap.clear(); grow(); } - bool hasStackSlot(unsigned virtReg) const { - return getStackSlot(virtReg) != NO_STACK_SLOT; + /// @brief returns the register allocation preference. + unsigned getRegAllocPref(unsigned virtReg); + + /// @brief returns true if VirtReg is assigned to its preferred physreg. + bool hasPreferredPhys(unsigned VirtReg) { + return getPhys(VirtReg) == getRegAllocPref(VirtReg); } - int getStackSlot(unsigned virtReg) const { - assert(MRegisterInfo::isVirtualRegister(virtReg)); - return v2ssMap_[virtReg]; + /// @brief records virtReg is a split live interval from SReg. + void setIsSplitFromReg(unsigned virtReg, unsigned SReg) { + Virt2SplitMap[virtReg] = SReg; } - int assignVirt2StackSlot(unsigned virtReg); - void assignVirt2StackSlot(unsigned virtReg, int frameIndex); + /// @brief returns the live interval virtReg is split from. + unsigned getPreSplitReg(unsigned virtReg) const { + return Virt2SplitMap[virtReg]; + } + + /// getOriginal - Return the original virtual register that VirtReg descends + /// from through splitting. + /// A register that was not created by splitting is its own original. + /// This operation is idempotent. + unsigned getOriginal(unsigned VirtReg) const { + unsigned Orig = getPreSplitReg(VirtReg); + return Orig ? Orig : VirtReg; + } - void virtFolded(unsigned virtReg, MachineInstr* oldMI, - MachineInstr* newMI); + /// @brief returns true if the specified virtual register is not + /// mapped to a stack slot or rematerialized. + bool isAssignedReg(unsigned virtReg) const { + if (getStackSlot(virtReg) == NO_STACK_SLOT) + return true; + // Split register can be assigned a physical register as well as a + // stack slot or remat id. + return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg] != NO_PHYS_REG); + } - std::pair - getFoldedVirts(MachineInstr* MI) const { - return mi2vMap_.equal_range(MI); + /// @brief returns the stack slot mapped to the specified virtual + /// register + int getStackSlot(unsigned virtReg) const { + assert(TargetRegisterInfo::isVirtualRegister(virtReg)); + return Virt2StackSlotMap[virtReg]; } - void print(std::ostream &OS) const; + /// @brief create a mapping for the specifed virtual register to + /// the next available stack slot + int assignVirt2StackSlot(unsigned virtReg); + /// @brief create a mapping for the specified virtual register to + /// the specified stack slot + void assignVirt2StackSlot(unsigned virtReg, int frameIndex); + + void print(raw_ostream &OS, const Module* M = 0) const; void dump() const; }; - inline std::ostream &operator<<(std::ostream &OS, const VirtRegMap &VRM) { + inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) { VRM.print(OS); return OS; } - - /// Spiller interface: Implementations of this interface assign spilled - /// virtual registers to stack slots, rewriting the code. - struct Spiller { - virtual ~Spiller(); - virtual bool runOnMachineFunction(MachineFunction &MF, - const VirtRegMap &VRM) = 0; - }; - - /// createSpiller - Create an return a spiller object, as specified on the - /// command line. - Spiller* createSpiller(); - } // End llvm namespace #endif