X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=include%2Fllvm%2FCodeGen%2FLiveVariables.h;h=fafbd4c0d178e0ddaa43557903e90b862e87161f;hb=7ed47a13356daed2a34cd2209a31f92552e3bdd8;hp=6e7e23d495b8d131b4bfce767765a2aa7e5b17ae;hpb=a284cbf667e11660840dc7bae3ee9eeaa3c7cbd2;p=oota-llvm.git diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h index 6e7e23d495b..fafbd4c0d17 100644 --- a/include/llvm/CodeGen/LiveVariables.h +++ b/include/llvm/CodeGen/LiveVariables.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. // //===----------------------------------------------------------------------===// // @@ -31,6 +31,8 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/ADT/BitVector.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallVector.h" #include namespace llvm { @@ -39,6 +41,9 @@ class MRegisterInfo; class LiveVariables : public MachineFunctionPass { public: + static char ID; // Pass identification, replacement for typeid + LiveVariables() : MachineFunctionPass((intptr_t)&ID) {} + /// VarInfo - This represents the regions where a virtual register is live in /// the program. We represent this with three different pieces of /// information: the instruction that uniquely defines the value, the set of @@ -78,12 +83,20 @@ public: /// BitVector AliveBlocks; + /// UsedBlocks - Set of blocks of which this value is actually used. This + /// is a bit set which uses the basic block number as an index. + BitVector UsedBlocks; + + /// NumUses - Number of uses of this register across the entire function. + /// + unsigned NumUses; + /// Kills - List of MachineInstruction's which are the last use of this /// virtual register (kill it) in their basic block. /// std::vector Kills; - VarInfo() : DefInst(0) {} + VarInfo() : DefInst(0), NumUses(0) {} /// removeKill - Delete a kill corresponding to the specified /// machine instruction. Returns true if there was a kill @@ -108,32 +121,48 @@ private: /// std::vector VirtRegInfo; - /// AllocatablePhysicalRegisters - This vector keeps track of which registers - /// are actually register allocatable by the target machine. We can not track - /// liveness for values that are not in this set. + /// ReservedRegisters - This vector keeps track of which registers + /// are reserved register which are not allocatable by the target machine. + /// We can not track liveness for values that are in this set. /// - BitVector AllocatablePhysicalRegisters; + BitVector ReservedRegisters; private: // Intermediate data structures + MachineFunction *MF; + const MRegisterInfo *RegInfo; + // PhysRegInfo - Keep track of which instruction was the last def/use of a + // physical register. This is a purely local property, because all physical + // register references as presumed dead across basic blocks. MachineInstr **PhysRegInfo; - bool *PhysRegUsed; - typedef std::map > PHIVarInfoMap; + // PhysRegUsed - Keep track whether the physical register has been used after + // its last definition. This is local property. + bool *PhysRegUsed; - PHIVarInfoMap PHIVarInfo; + // PhysRegPartUse - Keep track of which instruction was the last partial use + // of a physical register (e.g. on X86 a def of EAX followed by a use of AX). + // This is a purely local property. + MachineInstr **PhysRegPartUse; + // PhysRegPartDef - Keep track of a list of instructions which "partially" + // defined the physical register (e.g. on X86 AX partially defines EAX). + // These are turned into use/mod/write if there is a use of the register + // later in the same block. This is local property. + SmallVector *PhysRegPartDef; - /// addRegisterKilled - We have determined MI kills a register. Look for the - /// operand that uses it and mark it as IsKill. - void addRegisterKilled(unsigned IncomingReg, MachineInstr *MI); + SmallVector *PHIVarInfo; - /// addRegisterDead - We have determined MI defined a register without a use. - /// Look for the operand that defines it and mark it as IsDead. - void addRegisterDead(unsigned IncomingReg, MachineInstr *MI); + void addRegisterKills(unsigned Reg, MachineInstr *MI, + SmallSet &SubKills); + /// HandlePhysRegKill - Add kills of Reg and its sub-registers to the + /// uses. Pay special attention to the sub-register uses which may come below + /// the last use of the whole register. + bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI, + SmallSet &SubKills); + bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI); void HandlePhysRegUse(unsigned Reg, MachineInstr *MI); void HandlePhysRegDef(unsigned Reg, MachineInstr *MI); @@ -167,14 +196,28 @@ public: /// the records for NewMI. void instructionChanged(MachineInstr *OldMI, MachineInstr *NewMI); + /// transferKillDeadInfo - Similar to instructionChanged except it does not + /// update live variables internal data structures. + static void transferKillDeadInfo(MachineInstr *OldMI, MachineInstr *NewMI, + const MRegisterInfo *RegInfo); + + /// addRegisterKilled - We have determined MI kills a register. Look for the + /// operand that uses it and mark it as IsKill. If AddIfNotFound is true, + /// add a implicit operand if it's not found. Returns true if the operand + /// exists / is added. + static bool addRegisterKilled(unsigned IncomingReg, MachineInstr *MI, + const MRegisterInfo *RegInfo, + bool AddIfNotFound = false); + /// addVirtualRegisterKilled - Add information about the fact that the /// specified register is killed after being used by the specified - /// instruction. - /// - void addVirtualRegisterKilled(unsigned IncomingReg, MachineInstr *MI) { - addRegisterKilled(IncomingReg, MI); - getVarInfo(IncomingReg).Kills.push_back(MI); - } + /// instruction. If AddIfNotFound is true, add a implicit operand if it's + /// not found. + void addVirtualRegisterKilled(unsigned IncomingReg, MachineInstr *MI, + bool AddIfNotFound = false) { + if (addRegisterKilled(IncomingReg, MI, RegInfo, AddIfNotFound)) + getVarInfo(IncomingReg).Kills.push_back(MI); + } /// removeVirtualRegisterKilled - Remove the specified virtual /// register from the live variable information. Returns true if the @@ -189,7 +232,7 @@ public: bool Removed = false; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand &MO = MI->getOperand(i); - if (MO.isReg() && MO.isUse() && MO.getReg() == reg) { + if (MO.isRegister() && MO.isKill() && MO.getReg() == reg) { MO.unsetIsKill(); Removed = true; break; @@ -204,12 +247,21 @@ public: /// instruction. void removeVirtualRegistersKilled(MachineInstr *MI); + /// addRegisterDead - We have determined MI defined a register without a use. + /// Look for the operand that defines it and mark it as IsDead. If + /// AddIfNotFound is true, add a implicit operand if it's not found. Returns + /// true if the operand exists / is added. + static bool addRegisterDead(unsigned IncomingReg, MachineInstr *MI, + const MRegisterInfo *RegInfo, + bool AddIfNotFound = false); + /// addVirtualRegisterDead - Add information about the fact that the specified - /// register is dead after being used by the specified instruction. - /// - void addVirtualRegisterDead(unsigned IncomingReg, MachineInstr *MI) { - addRegisterDead(IncomingReg, MI); - getVarInfo(IncomingReg).Kills.push_back(MI); + /// register is dead after being used by the specified instruction. If + /// AddIfNotFound is true, add a implicit operand if it's not found. + void addVirtualRegisterDead(unsigned IncomingReg, MachineInstr *MI, + bool AddIfNotFound = false) { + if (addRegisterDead(IncomingReg, MI, RegInfo, AddIfNotFound)) + getVarInfo(IncomingReg).Kills.push_back(MI); } /// removeVirtualRegisterDead - Remove the specified virtual @@ -225,7 +277,7 @@ public: bool Removed = false; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand &MO = MI->getOperand(i); - if (MO.isReg() && MO.isDef() && MO.getReg() == reg) { + if (MO.isRegister() && MO.isDef() && MO.getReg() == reg) { MO.unsetIsDead(); Removed = true; break; @@ -252,6 +304,8 @@ public: VarInfo &getVarInfo(unsigned RegIdx); void MarkVirtRegAliveInBlock(VarInfo &VRInfo, MachineBasicBlock *BB); + void MarkVirtRegAliveInBlock(VarInfo &VRInfo, MachineBasicBlock *BB, + std::vector &WorkList); void HandleVirtRegUse(VarInfo &VRInfo, MachineBasicBlock *MBB, MachineInstr *MI); };