X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FVirtRegMap.h;h=7974dda66a5f9a0ab4aa5081036080e3a95a0df9;hb=b21d9aebba7e45ddcbce61dd501000049cefb335;hp=342d800242cac59025b98e24b683a2d2974cb576;hpb=e81561909d128c6e2d8033cb5465a49b2596b26a;p=oota-llvm.git diff --git a/lib/CodeGen/VirtRegMap.h b/lib/CodeGen/VirtRegMap.h index 342d800242c..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,52 +17,73 @@ #ifndef LLVM_CODEGEN_VIRTREGMAP_H #define LLVM_CODEGEN_VIRTREGMAP_H -#include "llvm/Target/MRegisterInfo.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/Support/Streams.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: - enum ModRef { isRef = 1, isMod = 2, isModRef = 3 }; - typedef std::multimap > MI2VirtMapTy; + enum { + NO_PHYS_REG = 0, + NO_STACK_SLOT = (1L << 30)-1, + MAX_STACK_SLOT = (1L << 18)-1 + }; private: - const TargetInstrInfo &TII; + MachineRegisterInfo *MRI; + const TargetInstrInfo *TII; + const TargetRegisterInfo *TRI; + MachineFunction *MF; - 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). - DenseMap Virt2PhysMap; + 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. - DenseMap Virt2StackSlotMap; - /// MI2VirtMap - This is MachineInstr to virtual register - /// mapping. In the case of memory spill code being folded into - /// instructions, we need to know which virtual register was - /// read/written by this instruction. - MI2VirtMapTy MI2VirtMap; + IndexedMap Virt2StackSlotMap; - VirtRegMap(const VirtRegMap&); // DO NOT IMPLEMENT - void operator=(const VirtRegMap&); // DO NOT IMPLEMENT + /// Virt2SplitMap - This is virtual register to splitted virtual register + /// mapping. + IndexedMap Virt2SplitMap; - enum { - NO_PHYS_REG = 0, - NO_STACK_SLOT = ~0 >> 1 - }; + /// 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); + 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(); @@ -75,15 +96,15 @@ namespace llvm { /// @brief returns the physical register mapped to the specified /// virtual register unsigned getPhys(unsigned virtReg) const { - assert(MRegisterInfo::isVirtualRegister(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(TargetRegisterInfo::isVirtualRegister(virtReg) && + TargetRegisterInfo::isPhysicalRegister(physReg)); assert(Virt2PhysMap[virtReg] == NO_PHYS_REG && "attempt to assign physical register to already mapped " "virtual register"); @@ -93,7 +114,7 @@ namespace llvm { /// @brief clears the specified virtual register's, physical /// register mapping void clearVirt(unsigned virtReg) { - assert(MRegisterInfo::isVirtualRegister(virtReg)); + assert(TargetRegisterInfo::isVirtualRegister(virtReg)); assert(Virt2PhysMap[virtReg] != NO_PHYS_REG && "attempt to clear a not assigned virtual register"); Virt2PhysMap[virtReg] = NO_PHYS_REG; @@ -105,16 +126,47 @@ namespace llvm { grow(); } - /// @brief returns true is the specified virtual register is - /// mapped to a stack slot - 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); + } + + /// @brief records virtReg is a split live interval from SReg. + void setIsSplitFromReg(unsigned virtReg, unsigned SReg) { + Virt2SplitMap[virtReg] = SReg; + } + + /// @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; + } + + /// @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); } /// @brief returns the stack slot mapped to the specified virtual /// register int getStackSlot(unsigned virtReg) const { - assert(MRegisterInfo::isVirtualRegister(virtReg)); + assert(TargetRegisterInfo::isVirtualRegister(virtReg)); return Virt2StackSlotMap[virtReg]; } @@ -125,47 +177,14 @@ namespace llvm { /// the specified stack slot void assignVirt2StackSlot(unsigned virtReg, int frameIndex); - /// @brief Updates information about the specified virtual register's value - /// folded into newMI machine instruction. The OpNum argument indicates the - /// operand number of OldMI that is folded. - void virtFolded(unsigned VirtReg, MachineInstr *OldMI, unsigned OpNum, - MachineInstr *NewMI); - - /// @brief returns the virtual registers' values folded in memory - /// operands of this instruction - std::pair - getFoldedVirts(MachineInstr* MI) const { - return MI2VirtMap.equal_range(MI); - } - - /// RemoveFromFoldedVirtMap - If the specified machine instruction is in - /// the folded instruction map, remove its entry from the map. - void RemoveFromFoldedVirtMap(MachineInstr *MI) { - MI2VirtMap.erase(MI); - } - - void print(std::ostream &OS) const; - void print(OStream &OS) const; + 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, - VirtRegMap &VRM) = 0; - }; - - /// createSpiller - Create an return a spiller object, as specified on the - /// command line. - Spiller* createSpiller(); - } // End llvm namespace #endif