X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FMachineRegisterInfo.h;h=91d24dd0fc0c62a8414828a3fa78415a2ccad96d;hb=412cd2f81374865dfa708bef6d5b896ca10dece0;hp=51c71b724ccc67c3c8254c92d242f35564ee0074;hpb=90019479f9a3868d8be90564695097a61a725438;p=oota-llvm.git diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 51c71b724cc..91d24dd0fc0 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -15,6 +15,7 @@ #define LLVM_CODEGEN_MACHINEREGISTERINFO_H #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/CodeGen/MachineInstrBundle.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/IndexedMap.h" #include @@ -31,6 +32,11 @@ class MachineRegisterInfo { /// registers have a single def. bool IsSSA; + /// TracksLiveness - True while register liveness is being tracked accurately. + /// Basic block live-in lists, kill flags, and implicit defs may not be + /// accurate when after this flag is cleared. + bool TracksLiveness; + /// VRegInfo - Information we keep for each virtual register. /// /// Each element in this list contains the register class of the vreg and the @@ -51,6 +57,26 @@ class MachineRegisterInfo { /// physical registers. MachineOperand **PhysRegUseDefLists; + /// getRegUseDefListHead - Return the head pointer for the register use/def + /// list for the specified virtual or physical register. + MachineOperand *&getRegUseDefListHead(unsigned RegNo) { + if (TargetRegisterInfo::isVirtualRegister(RegNo)) + return VRegInfo[RegNo].second; + return PhysRegUseDefLists[RegNo]; + } + + MachineOperand *getRegUseDefListHead(unsigned RegNo) const { + if (TargetRegisterInfo::isVirtualRegister(RegNo)) + return VRegInfo[RegNo].second; + return PhysRegUseDefLists[RegNo]; + } + + /// Get the next element in the use-def chain. + static MachineOperand *getNextOperandForReg(const MachineOperand *MO) { + assert(MO && MO->isReg() && "This is not a register operand!"); + return MO->Contents.Reg.Next; + } + /// UsedPhysRegs - This is a bit vector that is computed and set by the /// register allocator, and must be kept up to date by passes that run after /// register allocation (though most don't modify this). This is used @@ -80,8 +106,8 @@ class MachineRegisterInfo { std::vector > LiveIns; std::vector LiveOuts; - MachineRegisterInfo(const MachineRegisterInfo&); // DO NOT IMPLEMENT - void operator=(const MachineRegisterInfo&); // DO NOT IMPLEMENT + MachineRegisterInfo(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION; + void operator=(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION; public: explicit MachineRegisterInfo(const TargetRegisterInfo &TRI); ~MachineRegisterInfo(); @@ -102,16 +128,42 @@ public: // leaveSSA - Indicates that the machine function is no longer in SSA form. void leaveSSA() { IsSSA = false; } + /// tracksLiveness - Returns true when tracking register liveness accurately. + /// + /// While this flag is true, register liveness information in basic block + /// live-in lists and machine instruction operands is accurate. This means it + /// can be used to change the code in ways that affect the values in + /// registers, for example by the register scavenger. + /// + /// When this flag is false, liveness is no longer reliable. + bool tracksLiveness() const { return TracksLiveness; } + + /// invalidateLiveness - Indicates that register liveness is no longer being + /// tracked accurately. + /// + /// This should be called by late passes that invalidate the liveness + /// information. + void invalidateLiveness() { TracksLiveness = false; } + //===--------------------------------------------------------------------===// // Register Info //===--------------------------------------------------------------------===// + // Strictly for use by MachineInstr.cpp. + void addRegOperandToUseList(MachineOperand *MO); + + // Strictly for use by MachineInstr.cpp. + void removeRegOperandFromUseList(MachineOperand *MO); + /// reg_begin/reg_end - Provide iteration support to walk over all definitions /// and uses of a register within the MachineFunction that corresponds to this /// MachineRegisterInfo object. template class defusechain_iterator; + // Make it a friend so it can access getNextOperandForReg(). + template friend class defusechain_iterator; + /// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified /// register. typedef defusechain_iterator reg_iterator; @@ -149,6 +201,15 @@ public: /// specified register (it may be live-in). bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); } + /// hasOneDef - Return true if there is exactly one instruction defining the + /// specified register. + bool hasOneDef(unsigned RegNo) const { + def_iterator DI = def_begin(RegNo); + if (DI == def_end()) + return false; + return ++DI == def_end(); + } + /// use_iterator/use_begin/use_end - Walk all uses of the specified register. typedef defusechain_iterator use_iterator; use_iterator use_begin(unsigned RegNo) const { @@ -162,7 +223,12 @@ public: /// hasOneUse - Return true if there is exactly one instruction using the /// specified register. - bool hasOneUse(unsigned RegNo) const; + bool hasOneUse(unsigned RegNo) const { + use_iterator UI = use_begin(RegNo); + if (UI == use_end()) + return false; + return ++UI == use_end(); + } /// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the /// specified register, skipping those marked as Debug. @@ -195,25 +261,16 @@ public: /// constraints. void replaceRegWith(unsigned FromReg, unsigned ToReg); - /// getRegUseDefListHead - Return the head pointer for the register use/def - /// list for the specified virtual or physical register. - MachineOperand *&getRegUseDefListHead(unsigned RegNo) { - if (TargetRegisterInfo::isVirtualRegister(RegNo)) - return VRegInfo[RegNo].second; - return PhysRegUseDefLists[RegNo]; - } - - MachineOperand *getRegUseDefListHead(unsigned RegNo) const { - if (TargetRegisterInfo::isVirtualRegister(RegNo)) - return VRegInfo[RegNo].second; - return PhysRegUseDefLists[RegNo]; - } - /// getVRegDef - Return the machine instr that defines the specified virtual /// register or null if none is found. This assumes that the code is in SSA /// form, so there should only be one definition. MachineInstr *getVRegDef(unsigned Reg) const; + /// getUniqueVRegDef - Return the unique machine instr that defines the + /// specified virtual register or null if none is found. If there are + /// multiple definitions or no definition, return null. + MachineInstr *getUniqueVRegDef(unsigned Reg) const; + /// clearKillFlags - Iterate over all the uses of the given register and /// clear the kill flag from the MachineOperand. This function is used by /// optimization passes which extend register lifetimes and need only @@ -273,6 +330,9 @@ public: /// unsigned getNumVirtRegs() const { return VRegInfo.size(); } + /// clearVirtRegs - Remove all virtual registers (after physreg assignment). + void clearVirtRegs(); + /// setRegAllocationHint - Specify a register allocation hint for the /// specified virtual register. void setRegAllocationHint(unsigned Reg, unsigned Type, unsigned PrefReg) { @@ -310,7 +370,7 @@ public: bool isPhysRegOrOverlapUsed(unsigned Reg) const { if (UsedPhysRegMask.test(Reg)) return true; - for (const unsigned *AI = TRI->getOverlaps(Reg); *AI; ++AI) + for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) if (UsedPhysRegs.test(*AI)) return true; return false; @@ -408,10 +468,6 @@ public: const TargetRegisterInfo &TRI, const TargetInstrInfo &TII); -private: - void HandleVRegListReallocation(); - -public: /// defusechain_iterator - This class provides iterator support for machine /// operands in the function that use or define a specific register. If /// ReturnUses is true it returns uses of registers, if ReturnDefs is true it @@ -455,13 +511,22 @@ public: // Iterator traversal: forward iteration only defusechain_iterator &operator++() { // Preincrement assert(Op && "Cannot increment end iterator!"); - Op = Op->getNextOperandForReg(); - - // If this is an operand we don't care about, skip it. - while (Op && ((!ReturnUses && Op->isUse()) || - (!ReturnDefs && Op->isDef()) || - (SkipDebug && Op->isDebug()))) - Op = Op->getNextOperandForReg(); + Op = getNextOperandForReg(Op); + + // All defs come before the uses, so stop def_iterator early. + if (!ReturnUses) { + if (Op) { + if (Op->isUse()) + Op = 0; + else + assert(!Op->isDebug() && "Can't have debug defs"); + } + } else { + // If this is an operand we don't care about, skip it. + while (Op && ((!ReturnDefs && Op->isDef()) || + (SkipDebug && Op->isDebug()))) + Op = getNextOperandForReg(Op); + } return *this; } @@ -480,6 +545,14 @@ public: return MI; } + MachineInstr *skipBundle() { + if (!Op) return 0; + MachineInstr *MI = getBundleStart(Op->getParent()); + do ++*this; + while (Op && getBundleStart(Op->getParent()) == MI); + return MI; + } + MachineOperand &getOperand() const { assert(Op && "Cannot dereference end iterator!"); return *Op;