[llvm] [CodeGen][NewPM] Port RegisterCoalescer to NPM (PR #124698)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 28 05:47:17 PST 2025
================
@@ -120,317 +123,334 @@ static cl::opt<unsigned> LargeIntervalFreqThreshold(
namespace {
- class JoinVals;
-
- class RegisterCoalescer : public MachineFunctionPass,
- private LiveRangeEdit::Delegate {
- MachineFunction* MF = nullptr;
- MachineRegisterInfo* MRI = nullptr;
- const TargetRegisterInfo* TRI = nullptr;
- const TargetInstrInfo* TII = nullptr;
- LiveIntervals *LIS = nullptr;
- const MachineLoopInfo* Loops = nullptr;
- AliasAnalysis *AA = nullptr;
- RegisterClassInfo RegClassInfo;
-
- /// Position and VReg of a PHI instruction during coalescing.
- struct PHIValPos {
- SlotIndex SI; ///< Slot where this PHI occurs.
- Register Reg; ///< VReg the PHI occurs in.
- unsigned SubReg; ///< Qualifying subregister for Reg.
- };
-
- /// Map from debug instruction number to PHI position during coalescing.
- DenseMap<unsigned, PHIValPos> PHIValToPos;
- /// Index of, for each VReg, which debug instruction numbers and
- /// corresponding PHIs are sensitive to coalescing. Each VReg may have
- /// multiple PHI defs, at different positions.
- DenseMap<Register, SmallVector<unsigned, 2>> RegToPHIIdx;
-
- /// Debug variable location tracking -- for each VReg, maintain an
- /// ordered-by-slot-index set of DBG_VALUEs, to help quick
- /// identification of whether coalescing may change location validity.
- using DbgValueLoc = std::pair<SlotIndex, MachineInstr*>;
- DenseMap<Register, std::vector<DbgValueLoc>> DbgVRegToValues;
-
- /// A LaneMask to remember on which subregister live ranges we need to call
- /// shrinkToUses() later.
- LaneBitmask ShrinkMask;
-
- /// True if the main range of the currently coalesced intervals should be
- /// checked for smaller live intervals.
- bool ShrinkMainRange = false;
-
- /// True if the coalescer should aggressively coalesce global copies
- /// in favor of keeping local copies.
- bool JoinGlobalCopies = false;
-
- /// True if the coalescer should aggressively coalesce fall-thru
- /// blocks exclusively containing copies.
- bool JoinSplitEdges = false;
-
- /// Copy instructions yet to be coalesced.
- SmallVector<MachineInstr*, 8> WorkList;
- SmallVector<MachineInstr*, 8> LocalWorkList;
-
- /// Set of instruction pointers that have been erased, and
- /// that may be present in WorkList.
- SmallPtrSet<MachineInstr*, 8> ErasedInstrs;
-
- /// Dead instructions that are about to be deleted.
- SmallVector<MachineInstr*, 8> DeadDefs;
-
- /// Virtual registers to be considered for register class inflation.
- SmallVector<Register, 8> InflateRegs;
-
- /// The collection of live intervals which should have been updated
- /// immediately after rematerialiation but delayed until
- /// lateLiveIntervalUpdate is called.
- DenseSet<Register> ToBeUpdated;
-
- /// Record how many times the large live interval with many valnos
- /// has been tried to join with other live interval.
- DenseMap<Register, unsigned long> LargeLIVisitCounter;
-
- /// Recursively eliminate dead defs in DeadDefs.
- void eliminateDeadDefs(LiveRangeEdit *Edit = nullptr);
-
- /// LiveRangeEdit callback for eliminateDeadDefs().
- void LRE_WillEraseInstruction(MachineInstr *MI) override;
-
- /// Coalesce the LocalWorkList.
- void coalesceLocals();
-
- /// Join compatible live intervals
- void joinAllIntervals();
-
- /// Coalesce copies in the specified MBB, putting
- /// copies that cannot yet be coalesced into WorkList.
- void copyCoalesceInMBB(MachineBasicBlock *MBB);
-
- /// Tries to coalesce all copies in CurrList. Returns true if any progress
- /// was made.
- bool copyCoalesceWorkList(MutableArrayRef<MachineInstr*> CurrList);
-
- /// If one def has many copy like uses, and those copy uses are all
- /// rematerialized, the live interval update needed for those
- /// rematerializations will be delayed and done all at once instead
- /// of being done multiple times. This is to save compile cost because
- /// live interval update is costly.
- void lateLiveIntervalUpdate();
-
- /// Check if the incoming value defined by a COPY at \p SLRQ in the subrange
- /// has no value defined in the predecessors. If the incoming value is the
- /// same as defined by the copy itself, the value is considered undefined.
- bool copyValueUndefInPredecessors(LiveRange &S,
- const MachineBasicBlock *MBB,
- LiveQueryResult SLRQ);
-
- /// Set necessary undef flags on subregister uses after pruning out undef
- /// lane segments from the subrange.
- void setUndefOnPrunedSubRegUses(LiveInterval &LI, Register Reg,
- LaneBitmask PrunedLanes);
-
- /// Attempt to join intervals corresponding to SrcReg/DstReg, which are the
- /// src/dst of the copy instruction CopyMI. This returns true if the copy
- /// was successfully coalesced away. If it is not currently possible to
- /// coalesce this interval, but it may be possible if other things get
- /// coalesced, then it returns true by reference in 'Again'.
- bool joinCopy(MachineInstr *CopyMI, bool &Again,
- SmallPtrSetImpl<MachineInstr *> &CurrentErasedInstrs);
-
- /// Attempt to join these two intervals. On failure, this
- /// returns false. The output "SrcInt" will not have been modified, so we
- /// can use this information below to update aliases.
- bool joinIntervals(CoalescerPair &CP);
-
- /// Attempt joining two virtual registers. Return true on success.
- bool joinVirtRegs(CoalescerPair &CP);
-
- /// If a live interval has many valnos and is coalesced with other
- /// live intervals many times, we regard such live interval as having
- /// high compile time cost.
- bool isHighCostLiveInterval(LiveInterval &LI);
-
- /// Attempt joining with a reserved physreg.
- bool joinReservedPhysReg(CoalescerPair &CP);
-
- /// Add the LiveRange @p ToMerge as a subregister liverange of @p LI.
- /// Subranges in @p LI which only partially interfere with the desired
- /// LaneMask are split as necessary. @p LaneMask are the lanes that
- /// @p ToMerge will occupy in the coalescer register. @p LI has its subrange
- /// lanemasks already adjusted to the coalesced register.
- void mergeSubRangeInto(LiveInterval &LI, const LiveRange &ToMerge,
- LaneBitmask LaneMask, CoalescerPair &CP,
- unsigned DstIdx);
-
- /// Join the liveranges of two subregisters. Joins @p RRange into
- /// @p LRange, @p RRange may be invalid afterwards.
- void joinSubRegRanges(LiveRange &LRange, LiveRange &RRange,
- LaneBitmask LaneMask, const CoalescerPair &CP);
-
- /// We found a non-trivially-coalescable copy. If the source value number is
- /// defined by a copy from the destination reg see if we can merge these two
- /// destination reg valno# into a single value number, eliminating a copy.
- /// This returns true if an interval was modified.
- bool adjustCopiesBackFrom(const CoalescerPair &CP, MachineInstr *CopyMI);
-
- /// Return true if there are definitions of IntB
- /// other than BValNo val# that can reach uses of AValno val# of IntA.
- bool hasOtherReachingDefs(LiveInterval &IntA, LiveInterval &IntB,
- VNInfo *AValNo, VNInfo *BValNo);
-
- /// We found a non-trivially-coalescable copy.
- /// If the source value number is defined by a commutable instruction and
- /// its other operand is coalesced to the copy dest register, see if we
- /// can transform the copy into a noop by commuting the definition.
- /// This returns a pair of two flags:
- /// - the first element is true if an interval was modified,
- /// - the second element is true if the destination interval needs
- /// to be shrunk after deleting the copy.
- std::pair<bool,bool> removeCopyByCommutingDef(const CoalescerPair &CP,
- MachineInstr *CopyMI);
-
- /// We found a copy which can be moved to its less frequent predecessor.
- bool removePartialRedundancy(const CoalescerPair &CP, MachineInstr &CopyMI);
-
- /// If the source of a copy is defined by a
- /// trivial computation, replace the copy by rematerialize the definition.
- bool reMaterializeTrivialDef(const CoalescerPair &CP, MachineInstr *CopyMI,
- bool &IsDefCopy);
-
- /// Return true if a copy involving a physreg should be joined.
- bool canJoinPhys(const CoalescerPair &CP);
-
- /// Replace all defs and uses of SrcReg to DstReg and update the subregister
- /// number if it is not zero. If DstReg is a physical register and the
- /// existing subregister number of the def / use being updated is not zero,
- /// make sure to set it to the correct physical subregister.
- void updateRegDefsUses(Register SrcReg, Register DstReg, unsigned SubIdx);
-
- /// If the given machine operand reads only undefined lanes add an undef
- /// flag.
- /// This can happen when undef uses were previously concealed by a copy
- /// which we coalesced. Example:
- /// %0:sub0<def,read-undef> = ...
- /// %1 = COPY %0 <-- Coalescing COPY reveals undef
- /// = use %1:sub1 <-- hidden undef use
- void addUndefFlag(const LiveInterval &Int, SlotIndex UseIdx,
- MachineOperand &MO, unsigned SubRegIdx);
-
- /// Handle copies of undef values. If the undef value is an incoming
- /// PHI value, it will convert @p CopyMI to an IMPLICIT_DEF.
- /// Returns nullptr if @p CopyMI was not in any way eliminable. Otherwise,
- /// it returns @p CopyMI (which could be an IMPLICIT_DEF at this point).
- MachineInstr *eliminateUndefCopy(MachineInstr *CopyMI);
-
- /// Check whether or not we should apply the terminal rule on the
- /// destination (Dst) of \p Copy.
- /// When the terminal rule applies, Copy is not profitable to
- /// coalesce.
- /// Dst is terminal if it has exactly one affinity (Dst, Src) and
- /// at least one interference (Dst, Dst2). If Dst is terminal, the
- /// terminal rule consists in checking that at least one of
- /// interfering node, say Dst2, has an affinity of equal or greater
- /// weight with Src.
- /// In that case, Dst2 and Dst will not be able to be both coalesced
- /// with Src. Since Dst2 exposes more coalescing opportunities than
- /// Dst, we can drop \p Copy.
- bool applyTerminalRule(const MachineInstr &Copy) const;
-
- /// Wrapper method for \see LiveIntervals::shrinkToUses.
- /// This method does the proper fixing of the live-ranges when the afore
- /// mentioned method returns true.
- void shrinkToUses(LiveInterval *LI,
- SmallVectorImpl<MachineInstr * > *Dead = nullptr) {
- NumShrinkToUses++;
- if (LIS->shrinkToUses(LI, Dead)) {
- /// Check whether or not \p LI is composed by multiple connected
- /// components and if that is the case, fix that.
- SmallVector<LiveInterval*, 8> SplitLIs;
- LIS->splitSeparateComponents(*LI, SplitLIs);
- }
- }
+class JoinVals;
+
+class RegisterCoalescer : private LiveRangeEdit::Delegate {
+ MachineFunction *MF = nullptr;
+ MachineRegisterInfo *MRI = nullptr;
+ const TargetRegisterInfo *TRI = nullptr;
+ const TargetInstrInfo *TII = nullptr;
+ LiveIntervals *LIS = nullptr;
+ SlotIndexes *SI = nullptr;
+ const MachineLoopInfo *Loops = nullptr;
+ RegisterClassInfo RegClassInfo;
+
+ /// Position and VReg of a PHI instruction during coalescing.
+ struct PHIValPos {
+ SlotIndex SI; ///< Slot where this PHI occurs.
+ Register Reg; ///< VReg the PHI occurs in.
+ unsigned SubReg; ///< Qualifying subregister for Reg.
+ };
- /// Wrapper Method to do all the necessary work when an Instruction is
- /// deleted.
- /// Optimizations should use this to make sure that deleted instructions
- /// are always accounted for.
- void deleteInstr(MachineInstr* MI) {
- ErasedInstrs.insert(MI);
- LIS->RemoveMachineInstrFromMaps(*MI);
- MI->eraseFromParent();
+ /// Map from debug instruction number to PHI position during coalescing.
+ DenseMap<unsigned, PHIValPos> PHIValToPos;
+ /// Index of, for each VReg, which debug instruction numbers and
+ /// corresponding PHIs are sensitive to coalescing. Each VReg may have
+ /// multiple PHI defs, at different positions.
+ DenseMap<Register, SmallVector<unsigned, 2>> RegToPHIIdx;
+
+ /// Debug variable location tracking -- for each VReg, maintain an
+ /// ordered-by-slot-index set of DBG_VALUEs, to help quick
+ /// identification of whether coalescing may change location validity.
+ using DbgValueLoc = std::pair<SlotIndex, MachineInstr *>;
+ DenseMap<Register, std::vector<DbgValueLoc>> DbgVRegToValues;
+
+ /// A LaneMask to remember on which subregister live ranges we need to call
+ /// shrinkToUses() later.
+ LaneBitmask ShrinkMask;
+
+ /// True if the main range of the currently coalesced intervals should be
+ /// checked for smaller live intervals.
+ bool ShrinkMainRange = false;
+
+ /// True if the coalescer should aggressively coalesce global copies
+ /// in favor of keeping local copies.
+ bool JoinGlobalCopies = false;
+
+ /// True if the coalescer should aggressively coalesce fall-thru
+ /// blocks exclusively containing copies.
+ bool JoinSplitEdges = false;
+
+ /// Copy instructions yet to be coalesced.
+ SmallVector<MachineInstr *, 8> WorkList;
+ SmallVector<MachineInstr *, 8> LocalWorkList;
+
+ /// Set of instruction pointers that have been erased, and
+ /// that may be present in WorkList.
+ SmallPtrSet<MachineInstr *, 8> ErasedInstrs;
+
+ /// Dead instructions that are about to be deleted.
+ SmallVector<MachineInstr *, 8> DeadDefs;
+
+ /// Virtual registers to be considered for register class inflation.
+ SmallVector<Register, 8> InflateRegs;
+
+ /// The collection of live intervals which should have been updated
+ /// immediately after rematerialiation but delayed until
+ /// lateLiveIntervalUpdate is called.
+ DenseSet<Register> ToBeUpdated;
+
+ /// Record how many times the large live interval with many valnos
+ /// has been tried to join with other live interval.
+ DenseMap<Register, unsigned long> LargeLIVisitCounter;
+
+ /// Recursively eliminate dead defs in DeadDefs.
+ void eliminateDeadDefs(LiveRangeEdit *Edit = nullptr);
+
+ /// LiveRangeEdit callback for eliminateDeadDefs().
+ void LRE_WillEraseInstruction(MachineInstr *MI) override;
+
+ /// Coalesce the LocalWorkList.
+ void coalesceLocals();
+
+ /// Join compatible live intervals
+ void joinAllIntervals();
+
+ /// Coalesce copies in the specified MBB, putting
+ /// copies that cannot yet be coalesced into WorkList.
+ void copyCoalesceInMBB(MachineBasicBlock *MBB);
+
+ /// Tries to coalesce all copies in CurrList. Returns true if any progress
+ /// was made.
+ bool copyCoalesceWorkList(MutableArrayRef<MachineInstr *> CurrList);
+
+ /// If one def has many copy like uses, and those copy uses are all
+ /// rematerialized, the live interval update needed for those
+ /// rematerializations will be delayed and done all at once instead
+ /// of being done multiple times. This is to save compile cost because
+ /// live interval update is costly.
+ void lateLiveIntervalUpdate();
+
+ /// Check if the incoming value defined by a COPY at \p SLRQ in the subrange
+ /// has no value defined in the predecessors. If the incoming value is the
+ /// same as defined by the copy itself, the value is considered undefined.
+ bool copyValueUndefInPredecessors(LiveRange &S, const MachineBasicBlock *MBB,
+ LiveQueryResult SLRQ);
+
+ /// Set necessary undef flags on subregister uses after pruning out undef
+ /// lane segments from the subrange.
+ void setUndefOnPrunedSubRegUses(LiveInterval &LI, Register Reg,
+ LaneBitmask PrunedLanes);
+
+ /// Attempt to join intervals corresponding to SrcReg/DstReg, which are the
+ /// src/dst of the copy instruction CopyMI. This returns true if the copy
+ /// was successfully coalesced away. If it is not currently possible to
+ /// coalesce this interval, but it may be possible if other things get
+ /// coalesced, then it returns true by reference in 'Again'.
+ bool joinCopy(MachineInstr *CopyMI, bool &Again,
+ SmallPtrSetImpl<MachineInstr *> &CurrentErasedInstrs);
+
+ /// Attempt to join these two intervals. On failure, this
+ /// returns false. The output "SrcInt" will not have been modified, so we
+ /// can use this information below to update aliases.
+ bool joinIntervals(CoalescerPair &CP);
+
+ /// Attempt joining two virtual registers. Return true on success.
+ bool joinVirtRegs(CoalescerPair &CP);
+
+ /// If a live interval has many valnos and is coalesced with other
+ /// live intervals many times, we regard such live interval as having
+ /// high compile time cost.
+ bool isHighCostLiveInterval(LiveInterval &LI);
+
+ /// Attempt joining with a reserved physreg.
+ bool joinReservedPhysReg(CoalescerPair &CP);
+
+ /// Add the LiveRange @p ToMerge as a subregister liverange of @p LI.
+ /// Subranges in @p LI which only partially interfere with the desired
+ /// LaneMask are split as necessary. @p LaneMask are the lanes that
+ /// @p ToMerge will occupy in the coalescer register. @p LI has its subrange
+ /// lanemasks already adjusted to the coalesced register.
+ void mergeSubRangeInto(LiveInterval &LI, const LiveRange &ToMerge,
+ LaneBitmask LaneMask, CoalescerPair &CP,
+ unsigned DstIdx);
+
+ /// Join the liveranges of two subregisters. Joins @p RRange into
+ /// @p LRange, @p RRange may be invalid afterwards.
+ void joinSubRegRanges(LiveRange &LRange, LiveRange &RRange,
+ LaneBitmask LaneMask, const CoalescerPair &CP);
+
+ /// We found a non-trivially-coalescable copy. If the source value number is
+ /// defined by a copy from the destination reg see if we can merge these two
+ /// destination reg valno# into a single value number, eliminating a copy.
+ /// This returns true if an interval was modified.
+ bool adjustCopiesBackFrom(const CoalescerPair &CP, MachineInstr *CopyMI);
+
+ /// Return true if there are definitions of IntB
+ /// other than BValNo val# that can reach uses of AValno val# of IntA.
+ bool hasOtherReachingDefs(LiveInterval &IntA, LiveInterval &IntB,
+ VNInfo *AValNo, VNInfo *BValNo);
+
+ /// We found a non-trivially-coalescable copy.
+ /// If the source value number is defined by a commutable instruction and
+ /// its other operand is coalesced to the copy dest register, see if we
+ /// can transform the copy into a noop by commuting the definition.
+ /// This returns a pair of two flags:
+ /// - the first element is true if an interval was modified,
+ /// - the second element is true if the destination interval needs
+ /// to be shrunk after deleting the copy.
+ std::pair<bool, bool> removeCopyByCommutingDef(const CoalescerPair &CP,
+ MachineInstr *CopyMI);
+
+ /// We found a copy which can be moved to its less frequent predecessor.
+ bool removePartialRedundancy(const CoalescerPair &CP, MachineInstr &CopyMI);
+
+ /// If the source of a copy is defined by a
+ /// trivial computation, replace the copy by rematerialize the definition.
+ bool reMaterializeTrivialDef(const CoalescerPair &CP, MachineInstr *CopyMI,
+ bool &IsDefCopy);
+
+ /// Return true if a copy involving a physreg should be joined.
+ bool canJoinPhys(const CoalescerPair &CP);
+
+ /// Replace all defs and uses of SrcReg to DstReg and update the subregister
+ /// number if it is not zero. If DstReg is a physical register and the
+ /// existing subregister number of the def / use being updated is not zero,
+ /// make sure to set it to the correct physical subregister.
+ void updateRegDefsUses(Register SrcReg, Register DstReg, unsigned SubIdx);
+
+ /// If the given machine operand reads only undefined lanes add an undef
+ /// flag.
+ /// This can happen when undef uses were previously concealed by a copy
+ /// which we coalesced. Example:
+ /// %0:sub0<def,read-undef> = ...
+ /// %1 = COPY %0 <-- Coalescing COPY reveals undef
+ /// = use %1:sub1 <-- hidden undef use
+ void addUndefFlag(const LiveInterval &Int, SlotIndex UseIdx,
+ MachineOperand &MO, unsigned SubRegIdx);
+
+ /// Handle copies of undef values. If the undef value is an incoming
+ /// PHI value, it will convert @p CopyMI to an IMPLICIT_DEF.
+ /// Returns nullptr if @p CopyMI was not in any way eliminable. Otherwise,
+ /// it returns @p CopyMI (which could be an IMPLICIT_DEF at this point).
+ MachineInstr *eliminateUndefCopy(MachineInstr *CopyMI);
+
+ /// Check whether or not we should apply the terminal rule on the
+ /// destination (Dst) of \p Copy.
+ /// When the terminal rule applies, Copy is not profitable to
+ /// coalesce.
+ /// Dst is terminal if it has exactly one affinity (Dst, Src) and
+ /// at least one interference (Dst, Dst2). If Dst is terminal, the
+ /// terminal rule consists in checking that at least one of
+ /// interfering node, say Dst2, has an affinity of equal or greater
+ /// weight with Src.
+ /// In that case, Dst2 and Dst will not be able to be both coalesced
+ /// with Src. Since Dst2 exposes more coalescing opportunities than
+ /// Dst, we can drop \p Copy.
+ bool applyTerminalRule(const MachineInstr &Copy) const;
+
+ /// Wrapper method for \see LiveIntervals::shrinkToUses.
+ /// This method does the proper fixing of the live-ranges when the afore
+ /// mentioned method returns true.
+ void shrinkToUses(LiveInterval *LI,
+ SmallVectorImpl<MachineInstr *> *Dead = nullptr) {
+ NumShrinkToUses++;
+ if (LIS->shrinkToUses(LI, Dead)) {
+ /// Check whether or not \p LI is composed by multiple connected
+ /// components and if that is the case, fix that.
+ SmallVector<LiveInterval *, 8> SplitLIs;
+ LIS->splitSeparateComponents(*LI, SplitLIs);
}
+ }
- /// Walk over function and initialize the DbgVRegToValues map.
- void buildVRegToDbgValueMap(MachineFunction &MF);
+ /// Wrapper Method to do all the necessary work when an Instruction is
+ /// deleted.
+ /// Optimizations should use this to make sure that deleted instructions
+ /// are always accounted for.
+ void deleteInstr(MachineInstr *MI) {
+ ErasedInstrs.insert(MI);
+ LIS->RemoveMachineInstrFromMaps(*MI);
+ MI->eraseFromParent();
+ }
- /// Test whether, after merging, any DBG_VALUEs would refer to a
- /// different value number than before merging, and whether this can
- /// be resolved. If not, mark the DBG_VALUE as being undef.
- void checkMergingChangesDbgValues(CoalescerPair &CP, LiveRange &LHS,
- JoinVals &LHSVals, LiveRange &RHS,
- JoinVals &RHSVals);
+ /// Walk over function and initialize the DbgVRegToValues map.
+ void buildVRegToDbgValueMap(MachineFunction &MF);
- void checkMergingChangesDbgValuesImpl(Register Reg, LiveRange &OtherRange,
- LiveRange &RegRange, JoinVals &Vals2);
+ /// Test whether, after merging, any DBG_VALUEs would refer to a
+ /// different value number than before merging, and whether this can
+ /// be resolved. If not, mark the DBG_VALUE as being undef.
+ void checkMergingChangesDbgValues(CoalescerPair &CP, LiveRange &LHS,
+ JoinVals &LHSVals, LiveRange &RHS,
+ JoinVals &RHSVals);
- public:
- static char ID; ///< Class identification, replacement for typeinfo
+ void checkMergingChangesDbgValuesImpl(Register Reg, LiveRange &OtherRange,
+ LiveRange &RegRange, JoinVals &Vals2);
- RegisterCoalescer() : MachineFunctionPass(ID) {
- initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry());
- }
+public:
+ // For legacy pass only.
+ RegisterCoalescer() {}
+ RegisterCoalescer &operator=(RegisterCoalescer &&Other) = default;
- void getAnalysisUsage(AnalysisUsage &AU) const override;
+ RegisterCoalescer(LiveIntervals *LIS, SlotIndexes *SI,
+ const MachineLoopInfo *Loops)
+ : LIS(LIS), SI(SI), Loops(Loops) {}
- MachineFunctionProperties getClearedProperties() const override {
- return MachineFunctionProperties().set(
- MachineFunctionProperties::Property::IsSSA);
- }
+ void releaseMemory();
+ void print(raw_ostream &O, const Module * = nullptr) const;
+ bool run(MachineFunction &MF);
+};
- void releaseMemory() override;
+class RegisterCoalescerLegacy : public MachineFunctionPass {
+ RegisterCoalescer Impl;
- /// This is the pass entry point.
- bool runOnMachineFunction(MachineFunction&) override;
+public:
+ static char ID; ///< Class identification, replacement for typeinfo
- /// Implement the dump method.
- void print(raw_ostream &O, const Module* = nullptr) const override;
- };
+ RegisterCoalescerLegacy() : MachineFunctionPass(ID) {
+ initializeRegisterCoalescerLegacyPass(*PassRegistry::getPassRegistry());
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ MachineFunctionProperties getClearedProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::IsSSA);
+ }
+
+ void releaseMemory() override { Impl.releaseMemory(); }
+
+ /// This is the pass entry point.
+ bool runOnMachineFunction(MachineFunction &) override;
+
+ /// Implement the dump method.
+ void print(raw_ostream &O, const Module * = nullptr) const override {
+ Impl.print(O, nullptr);
+ }
----------------
arsenm wrote:
I'm not sure how this or releaseMemory is useful. Every other pass just has the Impl locally live to the run method
https://github.com/llvm/llvm-project/pull/124698
More information about the llvm-commits
mailing list