X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSimpleRegisterCoalescing.h;h=c7a5df4cb8e7d0090b18eb55bfe78b63a6a2ec74;hb=af5663405834ca7cf4a847f2efa2d624ce99b1d8;hp=bb21515a3546e1406ed39964138e8ee689d682e7;hpb=f641395435ddfe2e3f0d9857fff4f6da77ee5427;p=oota-llvm.git diff --git a/lib/CodeGen/SimpleRegisterCoalescing.h b/lib/CodeGen/SimpleRegisterCoalescing.h index bb21515a354..c7a5df4cb8e 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.h +++ b/lib/CodeGen/SimpleRegisterCoalescing.h @@ -15,11 +15,9 @@ #define LLVM_CODEGEN_SIMPLE_REGISTER_COALESCING_H #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/LiveInterval.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/RegisterCoalescer.h" #include "llvm/ADT/BitVector.h" -#include "llvm/ADT/IndexedMap.h" #include namespace llvm { @@ -96,9 +94,17 @@ namespace llvm { /// SmallPtrSet JoinedCopies; + /// ReMatCopies - Keep track of copies eliminated due to remat. + /// + SmallPtrSet ReMatCopies; + + /// ReMatDefs - Keep track of definition instructions which have + /// been remat'ed. + SmallPtrSet ReMatDefs; + public: static char ID; // Pass identifcation, replacement for typeid - SimpleRegisterCoalescing() : MachineFunctionPass((intptr_t)&ID) {} + SimpleRegisterCoalescing() : MachineFunctionPass(&ID) {} struct InstrSlots { enum { @@ -127,7 +133,7 @@ namespace llvm { if (!li_->hasInterval(Reg)) return 0; return li_->getApproximateInstructionCount(li_->getInterval(Reg)) * - LiveIntervals::InstrSlots::NUM; + LiveInterval::InstrSlots::NUM; } /// print - Implement the dump method. @@ -167,12 +173,8 @@ namespace llvm { bool SimpleJoin(LiveInterval &LHS, LiveInterval &RHS); /// Return true if the two specified registers belong to different register - /// classes. The registers may be either phys or virt regs. In the - /// case where both registers are virtual registers, it would also returns - /// true by reference the RegB register class in SubRC if it is a subset of - /// RegA's register class. - bool differingRegisterClasses(unsigned RegA, unsigned RegB, - const TargetRegisterClass *&SubRC) const; + /// classes. The registers may be either phys or virt regs. + bool differingRegisterClasses(unsigned RegA, unsigned RegB) const; /// AdjustCopiesBackFrom - We found a non-trivially-coalescable copy. If @@ -194,27 +196,63 @@ namespace llvm { bool RemoveCopyByCommutingDef(LiveInterval &IntA, LiveInterval &IntB, MachineInstr *CopyMI); - /// TurnCopyIntoImpDef - If source of the specified copy is an implicit def, - /// turn the copy into an implicit def. - bool TurnCopyIntoImpDef(MachineBasicBlock::iterator &I, - MachineBasicBlock *MBB, - unsigned DstReg, unsigned SrcReg); + /// TrimLiveIntervalToLastUse - If there is a last use in the same basic + /// block as the copy instruction, trim the ive interval to the last use + /// and return true. + bool TrimLiveIntervalToLastUse(unsigned CopyIdx, + MachineBasicBlock *CopyMBB, + LiveInterval &li, const LiveRange *LR); + + /// ReMaterializeTrivialDef - If the source of a copy is defined by a trivial + /// computation, replace the copy by rematerialize the definition. + bool ReMaterializeTrivialDef(LiveInterval &SrcInt, unsigned DstReg, + unsigned DstSubIdx, MachineInstr *CopyMI); /// CanCoalesceWithImpDef - Returns true if the specified copy instruction /// from an implicit def to another register can be coalesced away. bool CanCoalesceWithImpDef(MachineInstr *CopyMI, LiveInterval &li, LiveInterval &ImpLi) const; - /// RemoveCopiesFromValNo - The specified value# is defined by an implicit - /// def and it is being removed. Turn all copies from this value# into - /// identity copies so they will be removed. - void RemoveCopiesFromValNo(LiveInterval &li, VNInfo *VNI); - - /// isProfitableToCoalesceToSubRC - Given that register class of DstReg is - /// a subset of the register class of SrcReg, return true if it's profitable - /// to coalesce the two registers. - bool isProfitableToCoalesceToSubRC(unsigned SrcReg, unsigned DstReg, - MachineBasicBlock *MBB); + /// TurnCopiesFromValNoToImpDefs - The specified value# is defined by an + /// implicit_def and it is being removed. Turn all copies from this value# + /// into implicit_defs. + void TurnCopiesFromValNoToImpDefs(LiveInterval &li, VNInfo *VNI); + + /// isWinToJoinVRWithSrcPhysReg - Return true if it's worth while to join a + /// a virtual destination register with physical source register. + bool isWinToJoinVRWithSrcPhysReg(MachineInstr *CopyMI, + MachineBasicBlock *CopyMBB, + LiveInterval &DstInt, LiveInterval &SrcInt); + + /// isWinToJoinVRWithDstPhysReg - Return true if it's worth while to join a + /// copy from a virtual source register to a physical destination register. + bool isWinToJoinVRWithDstPhysReg(MachineInstr *CopyMI, + MachineBasicBlock *CopyMBB, + LiveInterval &DstInt, LiveInterval &SrcInt); + + /// isWinToJoinCrossClass - Return true if it's profitable to coalesce + /// two virtual registers from different register classes. + bool isWinToJoinCrossClass(unsigned LargeReg, unsigned SmallReg, + unsigned Threshold); + + /// HasIncompatibleSubRegDefUse - If we are trying to coalesce a virtual + /// register with a physical register, check if any of the virtual register + /// operand is a sub-register use or def. If so, make sure it won't result + /// in an illegal extract_subreg or insert_subreg instruction. + bool HasIncompatibleSubRegDefUse(MachineInstr *CopyMI, + unsigned VirtReg, unsigned PhysReg); + + /// CanJoinExtractSubRegToPhysReg - Return true if it's possible to coalesce + /// an extract_subreg where dst is a physical register, e.g. + /// cl = EXTRACT_SUBREG reg1024, 1 + bool CanJoinExtractSubRegToPhysReg(unsigned DstReg, unsigned SrcReg, + unsigned SubIdx, unsigned &RealDstReg); + + /// CanJoinInsertSubRegToPhysReg - Return true if it's possible to coalesce + /// an insert_subreg where src is a physical register, e.g. + /// reg1024 = INSERT_SUBREG reg1024, c1, 0 + bool CanJoinInsertSubRegToPhysReg(unsigned DstReg, unsigned SrcReg, + unsigned SubIdx, unsigned &RealDstReg); /// RangeIsDefinedByCopyFromReg - Return true if the specified live range of /// the specified live interval is defined by a copy from the specified @@ -233,10 +271,6 @@ namespace llvm { /// subregister. void UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg, unsigned SubIdx); - /// RemoveDeadImpDef - Remove implicit_def instructions which are - /// "re-defining" registers due to insert_subreg coalescing. e.g. - void RemoveDeadImpDef(unsigned Reg, LiveInterval &LI); - /// RemoveUnnecessaryKills - Remove kill markers that are no longer accurate /// due to live range lengthening as the result of coalescing. void RemoveUnnecessaryKills(unsigned Reg, LiveInterval &LI); @@ -251,6 +285,11 @@ namespace llvm { /// live range is dead. Return true if live interval is removed. bool ShortenDeadCopySrcLiveRange(LiveInterval &li, MachineInstr *CopyMI); + /// RemoveDeadDef - If a def of a live interval is now determined dead, + /// remove the val# it defines. If the live interval becomes empty, remove + /// it as well. + bool RemoveDeadDef(LiveInterval &li, MachineInstr *DefMI); + /// lastRegisterUse - Returns the last use of the specific register between /// cycles Start and End or NULL if there are no uses. MachineOperand *lastRegisterUse(unsigned Start, unsigned End, unsigned Reg,