From: Pete Cooper Date: Mon, 2 Apr 2012 22:44:18 +0000 (+0000) Subject: Moved LiveRangeEdit.h so that it can be called from other parts of the backend, not... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=789d5d85ba6e9259a8e0f0bcfbd06a59ad164512;p=oota-llvm.git Moved LiveRangeEdit.h so that it can be called from other parts of the backend, not just libCodeGen git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153906 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h new file mode 100644 index 00000000000..909130ff617 --- /dev/null +++ b/include/llvm/CodeGen/LiveRangeEdit.h @@ -0,0 +1,202 @@ +//===---- LiveRangeEdit.h - Basic tools for split and spill -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The LiveRangeEdit class represents changes done to a virtual register when it +// is spilled or split. +// +// The parent register is never changed. Instead, a number of new virtual +// registers are created and added to the newRegs vector. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_LIVERANGEEDIT_H +#define LLVM_CODEGEN_LIVERANGEEDIT_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/CodeGen/LiveInterval.h" +#include "llvm/Target/TargetMachine.h" + +namespace llvm { + +class AliasAnalysis; +class LiveIntervals; +class MachineLoopInfo; +class MachineRegisterInfo; +class VirtRegMap; + +class LiveRangeEdit { +public: + /// Callback methods for LiveRangeEdit owners. + class Delegate { + virtual void anchor(); + public: + /// Called immediately before erasing a dead machine instruction. + virtual void LRE_WillEraseInstruction(MachineInstr *MI) {} + + /// Called when a virtual register is no longer used. Return false to defer + /// its deletion from LiveIntervals. + virtual bool LRE_CanEraseVirtReg(unsigned) { return true; } + + /// Called before shrinking the live range of a virtual register. + virtual void LRE_WillShrinkVirtReg(unsigned) {} + + /// Called after cloning a virtual register. + /// This is used for new registers representing connected components of Old. + virtual void LRE_DidCloneVirtReg(unsigned New, unsigned Old) {} + + virtual ~Delegate() {} + }; + +private: + LiveInterval &parent_; + SmallVectorImpl &newRegs_; + MachineRegisterInfo &MRI; + LiveIntervals &LIS; + VirtRegMap *VRM; + const TargetInstrInfo &TII; + Delegate *const delegate_; + + /// firstNew_ - Index of the first register added to newRegs_. + const unsigned firstNew_; + + /// scannedRemattable_ - true when remattable values have been identified. + bool scannedRemattable_; + + /// remattable_ - Values defined by remattable instructions as identified by + /// tii.isTriviallyReMaterializable(). + SmallPtrSet remattable_; + + /// rematted_ - Values that were actually rematted, and so need to have their + /// live range trimmed or entirely removed. + SmallPtrSet rematted_; + + /// scanRemattable - Identify the parent_ values that may rematerialize. + void scanRemattable(AliasAnalysis *aa); + + /// allUsesAvailableAt - Return true if all registers used by OrigMI at + /// OrigIdx are also available with the same value at UseIdx. + bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx, + SlotIndex UseIdx); + + /// foldAsLoad - If LI has a single use and a single def that can be folded as + /// a load, eliminate the register by folding the def into the use. + bool foldAsLoad(LiveInterval *LI, SmallVectorImpl &Dead); + +public: + /// Create a LiveRangeEdit for breaking down parent into smaller pieces. + /// @param parent The register being spilled or split. + /// @param newRegs List to receive any new registers created. This needn't be + /// empty initially, any existing registers are ignored. + LiveRangeEdit(LiveInterval &parent, + SmallVectorImpl &newRegs, + MachineFunction &MF, + LiveIntervals &lis, + VirtRegMap *vrm, + Delegate *delegate = 0) + : parent_(parent), newRegs_(newRegs), + MRI(MF.getRegInfo()), LIS(lis), VRM(vrm), + TII(*MF.getTarget().getInstrInfo()), + delegate_(delegate), + firstNew_(newRegs.size()), + scannedRemattable_(false) {} + + LiveInterval &getParent() const { return parent_; } + unsigned getReg() const { return parent_.reg; } + + /// Iterator for accessing the new registers added by this edit. + typedef SmallVectorImpl::const_iterator iterator; + iterator begin() const { return newRegs_.begin()+firstNew_; } + iterator end() const { return newRegs_.end(); } + unsigned size() const { return newRegs_.size()-firstNew_; } + bool empty() const { return size() == 0; } + LiveInterval *get(unsigned idx) const { return newRegs_[idx+firstNew_]; } + + ArrayRef regs() const { + return makeArrayRef(newRegs_).slice(firstNew_); + } + + /// createFrom - Create a new virtual register based on OldReg. + LiveInterval &createFrom(unsigned OldReg); + + /// create - Create a new register with the same class and original slot as + /// parent. + LiveInterval &create() { + return createFrom(getReg()); + } + + /// anyRematerializable - Return true if any parent values may be + /// rematerializable. + /// This function must be called before any rematerialization is attempted. + bool anyRematerializable(AliasAnalysis*); + + /// checkRematerializable - Manually add VNI to the list of rematerializable + /// values if DefMI may be rematerializable. + bool checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI, + AliasAnalysis*); + + /// Remat - Information needed to rematerialize at a specific location. + struct Remat { + VNInfo *ParentVNI; // parent_'s value at the remat location. + MachineInstr *OrigMI; // Instruction defining ParentVNI. + explicit Remat(VNInfo *ParentVNI) : ParentVNI(ParentVNI), OrigMI(0) {} + }; + + /// canRematerializeAt - Determine if ParentVNI can be rematerialized at + /// UseIdx. It is assumed that parent_.getVNINfoAt(UseIdx) == ParentVNI. + /// When cheapAsAMove is set, only cheap remats are allowed. + bool canRematerializeAt(Remat &RM, + SlotIndex UseIdx, + bool cheapAsAMove); + + /// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an + /// instruction into MBB before MI. The new instruction is mapped, but + /// liveness is not updated. + /// Return the SlotIndex of the new instruction. + SlotIndex rematerializeAt(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, + const Remat &RM, + const TargetRegisterInfo&, + bool Late = false); + + /// markRematerialized - explicitly mark a value as rematerialized after doing + /// it manually. + void markRematerialized(const VNInfo *ParentVNI) { + rematted_.insert(ParentVNI); + } + + /// didRematerialize - Return true if ParentVNI was rematerialized anywhere. + bool didRematerialize(const VNInfo *ParentVNI) const { + return rematted_.count(ParentVNI); + } + + /// eraseVirtReg - Notify the delegate that Reg is no longer in use, and try + /// to erase it from LIS. + void eraseVirtReg(unsigned Reg); + + /// eliminateDeadDefs - Try to delete machine instructions that are now dead + /// (allDefsAreDead returns true). This may cause live intervals to be trimmed + /// and further dead efs to be eliminated. + /// RegsBeingSpilled lists registers currently being spilled by the register + /// allocator. These registers should not be split into new intervals + /// as currently those new intervals are not guaranteed to spill. + void eliminateDeadDefs(SmallVectorImpl &Dead, + ArrayRef RegsBeingSpilled + = ArrayRef()); + + /// calculateRegClassAndHint - Recompute register class and hint for each new + /// register. + void calculateRegClassAndHint(MachineFunction&, + const MachineLoopInfo&); +}; + +} + +#endif diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp index 9ebdebba911..d5ea666e4a1 100644 --- a/lib/CodeGen/InlineSpiller.cpp +++ b/lib/CodeGen/InlineSpiller.cpp @@ -14,12 +14,12 @@ #define DEBUG_TYPE "regalloc" #include "Spiller.h" -#include "LiveRangeEdit.h" #include "VirtRegMap.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/LiveRangeEdit.h" #include "llvm/CodeGen/LiveStackAnalysis.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineInstrBundle.h" diff --git a/lib/CodeGen/LiveRangeEdit.cpp b/lib/CodeGen/LiveRangeEdit.cpp index 3e21f52af12..52e366cb7d4 100644 --- a/lib/CodeGen/LiveRangeEdit.cpp +++ b/lib/CodeGen/LiveRangeEdit.cpp @@ -12,12 +12,12 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "regalloc" -#include "LiveRangeEdit.h" #include "VirtRegMap.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/CalcSpillWeights.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/LiveRangeEdit.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/Debug.h" diff --git a/lib/CodeGen/LiveRangeEdit.h b/lib/CodeGen/LiveRangeEdit.h deleted file mode 100644 index 909130ff617..00000000000 --- a/lib/CodeGen/LiveRangeEdit.h +++ /dev/null @@ -1,202 +0,0 @@ -//===---- LiveRangeEdit.h - Basic tools for split and spill -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// The LiveRangeEdit class represents changes done to a virtual register when it -// is spilled or split. -// -// The parent register is never changed. Instead, a number of new virtual -// registers are created and added to the newRegs vector. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_LIVERANGEEDIT_H -#define LLVM_CODEGEN_LIVERANGEEDIT_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/CodeGen/LiveInterval.h" -#include "llvm/Target/TargetMachine.h" - -namespace llvm { - -class AliasAnalysis; -class LiveIntervals; -class MachineLoopInfo; -class MachineRegisterInfo; -class VirtRegMap; - -class LiveRangeEdit { -public: - /// Callback methods for LiveRangeEdit owners. - class Delegate { - virtual void anchor(); - public: - /// Called immediately before erasing a dead machine instruction. - virtual void LRE_WillEraseInstruction(MachineInstr *MI) {} - - /// Called when a virtual register is no longer used. Return false to defer - /// its deletion from LiveIntervals. - virtual bool LRE_CanEraseVirtReg(unsigned) { return true; } - - /// Called before shrinking the live range of a virtual register. - virtual void LRE_WillShrinkVirtReg(unsigned) {} - - /// Called after cloning a virtual register. - /// This is used for new registers representing connected components of Old. - virtual void LRE_DidCloneVirtReg(unsigned New, unsigned Old) {} - - virtual ~Delegate() {} - }; - -private: - LiveInterval &parent_; - SmallVectorImpl &newRegs_; - MachineRegisterInfo &MRI; - LiveIntervals &LIS; - VirtRegMap *VRM; - const TargetInstrInfo &TII; - Delegate *const delegate_; - - /// firstNew_ - Index of the first register added to newRegs_. - const unsigned firstNew_; - - /// scannedRemattable_ - true when remattable values have been identified. - bool scannedRemattable_; - - /// remattable_ - Values defined by remattable instructions as identified by - /// tii.isTriviallyReMaterializable(). - SmallPtrSet remattable_; - - /// rematted_ - Values that were actually rematted, and so need to have their - /// live range trimmed or entirely removed. - SmallPtrSet rematted_; - - /// scanRemattable - Identify the parent_ values that may rematerialize. - void scanRemattable(AliasAnalysis *aa); - - /// allUsesAvailableAt - Return true if all registers used by OrigMI at - /// OrigIdx are also available with the same value at UseIdx. - bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx, - SlotIndex UseIdx); - - /// foldAsLoad - If LI has a single use and a single def that can be folded as - /// a load, eliminate the register by folding the def into the use. - bool foldAsLoad(LiveInterval *LI, SmallVectorImpl &Dead); - -public: - /// Create a LiveRangeEdit for breaking down parent into smaller pieces. - /// @param parent The register being spilled or split. - /// @param newRegs List to receive any new registers created. This needn't be - /// empty initially, any existing registers are ignored. - LiveRangeEdit(LiveInterval &parent, - SmallVectorImpl &newRegs, - MachineFunction &MF, - LiveIntervals &lis, - VirtRegMap *vrm, - Delegate *delegate = 0) - : parent_(parent), newRegs_(newRegs), - MRI(MF.getRegInfo()), LIS(lis), VRM(vrm), - TII(*MF.getTarget().getInstrInfo()), - delegate_(delegate), - firstNew_(newRegs.size()), - scannedRemattable_(false) {} - - LiveInterval &getParent() const { return parent_; } - unsigned getReg() const { return parent_.reg; } - - /// Iterator for accessing the new registers added by this edit. - typedef SmallVectorImpl::const_iterator iterator; - iterator begin() const { return newRegs_.begin()+firstNew_; } - iterator end() const { return newRegs_.end(); } - unsigned size() const { return newRegs_.size()-firstNew_; } - bool empty() const { return size() == 0; } - LiveInterval *get(unsigned idx) const { return newRegs_[idx+firstNew_]; } - - ArrayRef regs() const { - return makeArrayRef(newRegs_).slice(firstNew_); - } - - /// createFrom - Create a new virtual register based on OldReg. - LiveInterval &createFrom(unsigned OldReg); - - /// create - Create a new register with the same class and original slot as - /// parent. - LiveInterval &create() { - return createFrom(getReg()); - } - - /// anyRematerializable - Return true if any parent values may be - /// rematerializable. - /// This function must be called before any rematerialization is attempted. - bool anyRematerializable(AliasAnalysis*); - - /// checkRematerializable - Manually add VNI to the list of rematerializable - /// values if DefMI may be rematerializable. - bool checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI, - AliasAnalysis*); - - /// Remat - Information needed to rematerialize at a specific location. - struct Remat { - VNInfo *ParentVNI; // parent_'s value at the remat location. - MachineInstr *OrigMI; // Instruction defining ParentVNI. - explicit Remat(VNInfo *ParentVNI) : ParentVNI(ParentVNI), OrigMI(0) {} - }; - - /// canRematerializeAt - Determine if ParentVNI can be rematerialized at - /// UseIdx. It is assumed that parent_.getVNINfoAt(UseIdx) == ParentVNI. - /// When cheapAsAMove is set, only cheap remats are allowed. - bool canRematerializeAt(Remat &RM, - SlotIndex UseIdx, - bool cheapAsAMove); - - /// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an - /// instruction into MBB before MI. The new instruction is mapped, but - /// liveness is not updated. - /// Return the SlotIndex of the new instruction. - SlotIndex rematerializeAt(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, - const Remat &RM, - const TargetRegisterInfo&, - bool Late = false); - - /// markRematerialized - explicitly mark a value as rematerialized after doing - /// it manually. - void markRematerialized(const VNInfo *ParentVNI) { - rematted_.insert(ParentVNI); - } - - /// didRematerialize - Return true if ParentVNI was rematerialized anywhere. - bool didRematerialize(const VNInfo *ParentVNI) const { - return rematted_.count(ParentVNI); - } - - /// eraseVirtReg - Notify the delegate that Reg is no longer in use, and try - /// to erase it from LIS. - void eraseVirtReg(unsigned Reg); - - /// eliminateDeadDefs - Try to delete machine instructions that are now dead - /// (allDefsAreDead returns true). This may cause live intervals to be trimmed - /// and further dead efs to be eliminated. - /// RegsBeingSpilled lists registers currently being spilled by the register - /// allocator. These registers should not be split into new intervals - /// as currently those new intervals are not guaranteed to spill. - void eliminateDeadDefs(SmallVectorImpl &Dead, - ArrayRef RegsBeingSpilled - = ArrayRef()); - - /// calculateRegClassAndHint - Recompute register class and hint for each new - /// register. - void calculateRegClassAndHint(MachineFunction&, - const MachineLoopInfo&); -}; - -} - -#endif diff --git a/lib/CodeGen/RegAllocBase.cpp b/lib/CodeGen/RegAllocBase.cpp index 85119c998a2..b00eceb17f1 100644 --- a/lib/CodeGen/RegAllocBase.cpp +++ b/lib/CodeGen/RegAllocBase.cpp @@ -14,11 +14,11 @@ #define DEBUG_TYPE "regalloc" #include "RegAllocBase.h" -#include "LiveRangeEdit.h" #include "Spiller.h" #include "VirtRegMap.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/LiveRangeEdit.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetMachine.h" diff --git a/lib/CodeGen/RegAllocBasic.cpp b/lib/CodeGen/RegAllocBasic.cpp index 52f88e3b595..77ee3148f31 100644 --- a/lib/CodeGen/RegAllocBasic.cpp +++ b/lib/CodeGen/RegAllocBasic.cpp @@ -15,7 +15,6 @@ #define DEBUG_TYPE "regalloc" #include "RegAllocBase.h" #include "LiveDebugVariables.h" -#include "LiveRangeEdit.h" #include "RenderMachineFunction.h" #include "Spiller.h" #include "VirtRegMap.h" @@ -24,6 +23,7 @@ #include "llvm/PassAnalysisSupport.h" #include "llvm/CodeGen/CalcSpillWeights.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/LiveRangeEdit.h" #include "llvm/CodeGen/LiveStackAnalysis.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index d00259a6d91..3f2a617100c 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -16,7 +16,6 @@ #include "AllocationOrder.h" #include "InterferenceCache.h" #include "LiveDebugVariables.h" -#include "LiveRangeEdit.h" #include "RegAllocBase.h" #include "Spiller.h" #include "SpillPlacement.h" @@ -29,6 +28,7 @@ #include "llvm/CodeGen/CalcSpillWeights.h" #include "llvm/CodeGen/EdgeBundles.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/LiveRangeEdit.h" #include "llvm/CodeGen/LiveStackAnalysis.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunctionPass.h" diff --git a/lib/CodeGen/RegAllocPBQP.cpp b/lib/CodeGen/RegAllocPBQP.cpp index 239e9dbedb1..a2846145bc7 100644 --- a/lib/CodeGen/RegAllocPBQP.cpp +++ b/lib/CodeGen/RegAllocPBQP.cpp @@ -31,7 +31,6 @@ #define DEBUG_TYPE "regalloc" -#include "LiveRangeEdit.h" #include "RenderMachineFunction.h" #include "Spiller.h" #include "VirtRegMap.h" @@ -40,6 +39,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/CalcSpillWeights.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/LiveRangeEdit.h" #include "llvm/CodeGen/LiveStackAnalysis.h" #include "llvm/CodeGen/RegAllocPBQP.h" #include "llvm/CodeGen/MachineDominators.h" diff --git a/lib/CodeGen/Spiller.cpp b/lib/CodeGen/Spiller.cpp index a9209ccf37a..4cd22eb60f5 100644 --- a/lib/CodeGen/Spiller.cpp +++ b/lib/CodeGen/Spiller.cpp @@ -11,8 +11,8 @@ #include "Spiller.h" #include "VirtRegMap.h" -#include "LiveRangeEdit.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/LiveRangeEdit.h" #include "llvm/CodeGen/LiveStackAnalysis.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp index f65890ef2d9..9959f74d5f2 100644 --- a/lib/CodeGen/SplitKit.cpp +++ b/lib/CodeGen/SplitKit.cpp @@ -14,10 +14,10 @@ #define DEBUG_TYPE "regalloc" #include "SplitKit.h" -#include "LiveRangeEdit.h" #include "VirtRegMap.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/LiveRangeEdit.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineLoopInfo.h"