-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[CodeGen][NFC] Format RegisterCoalescer sources #124697
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
optimisan
merged 1 commit into
main
from
users/Akshat-Oke/01-27-_codegen_nfc_format_registercoalescer_sources
Jan 28, 2025
Merged
[CodeGen][NFC] Format RegisterCoalescer sources #124697
optimisan
merged 1 commit into
main
from
users/Akshat-Oke/01-27-_codegen_nfc_format_registercoalescer_sources
Jan 28, 2025
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This stack of pull requests is managed by Graphite. Learn more about stacking. |
@llvm/pr-subscribers-llvm-regalloc Author: Akshat Oke (optimisan) ChangesPatch is 69.89 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/124697.diff 2 Files Affected:
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 9d49b24ab15789..1970d550113b6a 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -62,15 +62,15 @@ using namespace llvm;
#define DEBUG_TYPE "regalloc"
-STATISTIC(numJoins , "Number of interval joins performed");
-STATISTIC(numCrossRCs , "Number of cross class joins performed");
-STATISTIC(numCommutes , "Number of instruction commuting performed");
-STATISTIC(numExtends , "Number of copies extended");
-STATISTIC(NumReMats , "Number of instructions re-materialized");
-STATISTIC(NumInflated , "Number of register classes inflated");
+STATISTIC(numJoins, "Number of interval joins performed");
+STATISTIC(numCrossRCs, "Number of cross class joins performed");
+STATISTIC(numCommutes, "Number of instruction commuting performed");
+STATISTIC(numExtends, "Number of copies extended");
+STATISTIC(NumReMats, "Number of instructions re-materialized");
+STATISTIC(NumInflated, "Number of register classes inflated");
STATISTIC(NumLaneConflicts, "Number of dead lane conflicts tested");
-STATISTIC(NumLaneResolves, "Number of dead lane conflicts resolved");
-STATISTIC(NumShrinkToUses, "Number of shrinkToUses called");
+STATISTIC(NumLaneResolves, "Number of dead lane conflicts resolved");
+STATISTIC(NumShrinkToUses, "Number of shrinkToUses called");
static cl::opt<bool> EnableJoining("join-liveintervals",
cl::desc("Coalesce copies (default=true)"),
@@ -81,20 +81,20 @@ static cl::opt<bool> UseTerminalRule("terminal-rule",
cl::init(false), cl::Hidden);
/// Temporary flag to test critical edge unsplitting.
-static cl::opt<bool>
-EnableJoinSplits("join-splitedges",
- cl::desc("Coalesce copies on split edges (default=subtarget)"), cl::Hidden);
+static cl::opt<bool> EnableJoinSplits(
+ "join-splitedges",
+ cl::desc("Coalesce copies on split edges (default=subtarget)"), cl::Hidden);
/// Temporary flag to test global copy optimization.
-static cl::opt<cl::boolOrDefault>
-EnableGlobalCopies("join-globalcopies",
- cl::desc("Coalesce copies that span blocks (default=subtarget)"),
- cl::init(cl::BOU_UNSET), cl::Hidden);
+static cl::opt<cl::boolOrDefault> EnableGlobalCopies(
+ "join-globalcopies",
+ cl::desc("Coalesce copies that span blocks (default=subtarget)"),
+ cl::init(cl::BOU_UNSET), cl::Hidden);
-static cl::opt<bool>
-VerifyCoalescing("verify-coalescing",
- cl::desc("Verify machine instrs before and after register coalescing"),
- cl::Hidden);
+static cl::opt<bool> VerifyCoalescing(
+ "verify-coalescing",
+ cl::desc("Verify machine instrs before and after register coalescing"),
+ cl::Hidden);
static cl::opt<unsigned> LateRematUpdateThreshold(
"late-remat-update-threshold", cl::Hidden,
@@ -120,287 +120,286 @@ 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.
- ///
- /// If \p IsSubregToReg, we are coalescing a DstReg = SUBREG_TO_REG
- /// SrcReg. This introduces an implicit-def of DstReg on coalesced users.
- void updateRegDefsUses(Register SrcReg, Register DstReg, unsigned SubIdx,
- bool IsSubregToReg);
-
- /// 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 : 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.
+ };
- /// 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 isHighCostLiv...
[truncated]
|
arsenm
approved these changes
Jan 28, 2025
c5b9326
to
0063b31
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
No description provided.