summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineCopyPropagation.cpp
AgeCommit message (Collapse)Author
2025-11-16[CodeGen] Turn MCRegUnit into an enum class (NFC) (#167943)Sergei Barannikov
This changes `MCRegUnit` type from `unsigned` to `enum class : unsigned` and inserts necessary casts. The added `MCRegUnitToIndex` functor is used with `SparseSet`, `SparseMultiSet` and `IndexedMap` in a few places. `MCRegUnit` is opaque to users, so it didn't seem worth making it a full-fledged class like `Register`. Static type checking has detected one issue in `PrologueEpilogueInserter.cpp`, where `BitVector` created for `MCRegister` is indexed by both `MCRegister` and `MCRegUnit`. The number of casts could be reduced by using `IndexedMap` in more places and/or adding a `BitVector` adaptor, but the number of casts *per file* is still small and `IndexedMap` has limitations, so it didn't seem worth the effort. Pull Request: https://github.com/llvm/llvm-project/pull/167943
2025-11-12[CodeGen] Use MCRegUnit in more places (NFC) (#167578)Sergei Barannikov
2025-11-11[MachineCopyPropagation] Remove logic to recognise and delete no-op moves ↵Alex Bradbury
produced after forwarded uses (#167336) As reported in <https://github.com/llvm/llvm-project/issues/166870>, some copies with src==reg are not no-ops, e.g. when self-assigning a w-reg on AArch64 which will zero-extend the corresponding x register. Revert in order to fix the issue. We may revisit whether the optimisation can be made safe at a later point. Reverts dffbc030e75b758e7512518abd499a0f680addbf. Fixes #166870.
2025-10-15[llvm] Replace LLVM_ATTRIBUTE_UNUSED with [[maybe_unused]] (NFC) (#163507)Kazu Hirata
This patch replaces LLVM_ATTRIBUTE_UNUSED with [[maybe_unused]]. Note that this patch adjusts the placement of [[maybe_unused]] to comply with the C++17 language.
2025-08-18[llvm] Replace SmallSet with SmallPtrSet (NFC) (#154068)Kazu Hirata
This patch replaces SmallSet<T *, N> with SmallPtrSet<T *, N>. Note that SmallSet.h "redirects" SmallSet to SmallPtrSet for pointer element types: template <typename PointeeType, unsigned N> class SmallSet<PointeeType*, N> : public SmallPtrSet<PointeeType*, N> {}; We only have 140 instances that rely on this "redirection", with the vast majority of them under llvm/. Since relying on the redirection doesn't improve readability, this patch replaces SmallSet with SmallPtrSet for pointer element types.
2025-06-02[MCP] Handle iterative simplification during forward copy prop (#140267)Philip Reames
This is the follow up I mentioned doing in the review of 52b345d. That change introduced an API for performing instruction simplifications following copy propagation (e.g. things like recognizing ORI a0, a1, zero is just a move). As noted in that review, we should be able to perform iterative simplification as we move forward through the block, but weren't because of the code structure. The majority of this code is just deleting the special casing for constant source and destination tracking, and merging the copy handling with the main path. By assumption, the properties of copies (in terms of register reads and writes), must be a subset of general instructions. Once we do that, the iterative bit basically falls out from having the tracking performed for copies which are recognized *after* we forward prior uses.
2025-05-22[LLVM][CodeGen] Add convenience accessors for MachineFunctionProperties ↵users/pcc/spr/main.elf-add-branch-to-branch-optimizationRahul Joshi
(#140002) Add per-property has<Prop>/set<Prop>/reset<Prop> functions to MachineFunctionProperties.
2025-05-16[MachineCopyPropagation] Make use of lane mask info in basic block liveins ↵Jay Foad
(#140248)
2025-05-08[MCP] Disable BackwardCopyPropagateBlock for copies with implicit registers. ↵Craig Topper
(#137687) If there's an implicit-def of a super register, the propagation must preserve this implicit-def. Knowing how and when to do this may require target specific knowledge so just disable it for now. Prior to 2def1c4, we checked that the copy had explicit 2 operands when that was removed we started allowing implicit operands through. This patch adds a check for implicit operands, but still allows extra explicit operands which was the goal of 2def1c4. Fixes #131478.
2025-05-08[RISCV][TII] Add and use new hook to simplify/canonicalize instructions ↵Alex Bradbury
after MachineCopyPropagation (#137973) PR #136875 was posted as a draft PR that handled a subset of these cases, using the CompressPat mechanism. The consensus from that discussion (and a conclusion I agree with) is that it would be beneficial doing this optimisation earlier on, and in a way that isn't limited just to cases that can be handled by instruction compression. The most common source for instructions that can be optimized/canonicalized in this way is through tail duplication in MachineBlockPlacement followed by machine copy propagation. For RISC-V, choosing a more canonical instruction allows it to be compressed when it couldn't be before. There is the potential that it would make other MI-level optimisations easier. This modifies ~910 instructions across an llvm-test-suite build including SPEC2017, targeting rva22u64. Looking at the diff, it seems there's room for eliminating instructions or further propagating after this. Coverage of instructions is based on observations from a script written to find redundant or improperly canonicalized instructions (though I aim to support all instructions in a 'group' at once, e.g. MUL* even if I only saw some variants of MUL in practice).
2025-03-20[llvm] Use *Set::insert_range (NFC) (#132325)Kazu Hirata
DenseSet, SmallPtrSet, SmallSet, SetVector, and StringSet recently gained C++23-style insert_range. This patch replaces: Dest.insert(Src.begin(), Src.end()); with: Dest.insert_range(Src); This patch does not touch custom begin like succ_begin for now.
2025-03-10[MachineCopyPropagation] Recognise and delete no-op moves produced after ↵Alex Bradbury
forwarded uses (#129889) This change removes 189 static instances of no-op reg-reg moves (i.e. where src == dest) across llvm-test-suite when compiled for RISC-V rv64gc and with SPEC included.
2025-02-10MachineCopyPropagation: Do not remove copies preserved by regmask (#125868)Jinsong Ji
llvm/llvm-project@9e436c2daa44 tries to handle register masks and sub-registers, it avoids clobbering RegUnit presreved by regmask. But it then introduces invalid pointer issues. We delete the copies without invalidate all the use in the CopyInfo, so we dereferenced invalid pointers in next interation, causing asserts. Fixes: #126107 --------- Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
2025-02-08[CodeGen] Avoid repeated hash lookups (NFC) (#126343)Kazu Hirata
2025-02-04[NewPM] MachineCopyPropagation: Remove dead ID (#125665)Akshat Oke
Fix for #125202 (4313345f2eeeb1e2ea7127a056ec4e1aaaa7fefb)
2025-02-04[CodeGen][NewPM] Port MachineCopyPropagation to NPM (#125202)Akshat Oke
2025-01-20[CodeGen] Avoid repeated hash lookups (NFC) (#123557)Kazu Hirata
2025-01-16[MachineCP] Correctly handle register masks and sub-registers (#122734)Oliver Stannard
When passing an instruction with a register mask, the machine copy propagation pass was dropping the information about some copy instructions which define a register which is preserved by the mask, because that register overlaps a register which is partially clobbered by it. This resulted in a miscompilation for AArch64, because this caused a live copy to be considered dead. The fix is to clobber register masks by finding the set of reg units which is preserved by the mask, and clobbering all units not in that set. This is based on #122472, and fixes the compile time performance regressions which were caused by that.
2025-01-13Revert "[MachineCP] Correctly handle register masks and sub-registers (#122472)"Nikita Popov
This reverts commit e2a071ece58790f8dd4886e998033cab82e906fb. This causes a large compile-time regression.
2025-01-13[MachineCP] Correctly handle register masks and sub-registers (#122472)Oliver Stannard
When passing an instruction with a register mask, the machine copy propagation pass was dropping the information about some copy instructions which define a register which is preserved by the mask, because that register overlaps a register which is partially clobbered by it. This resulted in a miscompilation for AArch64, because this caused a live copy to be considered dead. The fix is to clobber register masks by finding the set of reg units which is preserved by the mask, and clobbering all units not in that set.
2024-10-23[MCP] Optimize copies when src is used during backward propagation (#111130)Vladimir Radosavljevic
Before this patch, redundant COPY couldn't be removed for the following case: ``` $R0 = OP ... ... // Read of %R0 $R1 = COPY killed $R0 ``` This patch adds support for tracking the users of the source register during backward propagation, so that we can remove the redundant COPY in the above case and optimize it to: ``` $R1 = OP ... ... // Replace all uses of %R0 with $R1 ```
2024-10-10[MCP] Skip invalidating def constant regs during forward propagation (#111129)Vladimir Radosavljevic
Before this patch, redundant COPY couldn't be removed for the following case: ``` %reg1 = COPY %const-reg ... // There is a def of %const-reg %reg2 = COPY killed %reg1 ``` where this can be optimized to: ``` ... // There is a def of %const-reg %reg2 = COPY %const-reg ``` This patch allows for such optimization by not invalidating defined constant registers. This is safe, as architectures like AArch64 and RISCV replace a dead definition of a GPR with a zero constant register for certain instructions.
2024-09-13[CodeGen] Use DenseMap::operator[] (NFC) (#108489)Kazu Hirata
Once we modernize CopyInfo with default member initializations, Copies.insert({Unit, ...}) becomes equivalent to: Copies.try_emplace(Unit) which we can simplify further down to Copies[Unit].
2024-08-28[RISCV][MCP] Remove redundant move from tail duplication (#89865)Piyou Chen
Tail duplication will generate the redundant move before return. It is because the MachineCopyPropogation can't recognize COPY after post-RA pseudoExpand. This patch make MachineCopyPropogation recognize `%0 = ADDI %1, 0` as COPY
2024-07-11[MCP] Use MCRegUnit as the key type of CopyTracker::Copies map. NFC. (#98277)Kai Luo
`CopyTracker` is in fact tracking at RegUnit level, not MCRegister.
2024-05-30[MCP] Remove unused TII argument. NFCDavid Green
Last used in e35fbf5c04f4719db8ff7c7a993cbf96bb706903.
2024-04-24[CodeGen] Make the parameter TRI required in some functions. (#85968)Xu Zhang
Fixes #82659 There are some functions, such as `findRegisterDefOperandIdx` and `findRegisterDefOperand`, that have too many default parameters. As a result, we have encountered some issues due to the lack of TRI parameters, as shown in issue #82411. Following @RKSimon 's suggestion, this patch refactors 9 functions, including `{reads, kills, defines, modifies}Register`, `registerDefIsDead`, and `findRegister{UseOperandIdx, UseOperand, DefOperandIdx, DefOperand}`, adjusting the order of the TRI parameter and making it required. In addition, all the places that call these functions have also been updated correctly to ensure no additional impact. After this, the caller of these functions should explicitly know whether to pass the `TargetRegisterInfo` or just a `nullptr`.
2024-03-28[MCP] Remove dead copies from basic blocks with successors. (#86973)Craig Topper
Previously we wouldn't remove dead copies from basic blocks with successors. The comment said we didn't want to trust the live-in lists. The comment is very old so I'm not sure if that's still a concern today. This patch checks the live-in lists and removes copies from MaybeDeadCopies if they are referenced by any live-ins in any successors. We only do this if the tracksLiveness property is set. If that property is not set, we retain the old behavior.
2024-03-28[MCP] Use MachineInstr::all_defs instead of MachineInstr::defs in ↵Craig Topper
hasOverlappingMultipleDef. (#86889) defs does not return the defs for inline assembly. We need to use all_defs to find them. Fixes #86880.
2024-01-23[MachineCopyPropagation] Make a SmallVector larger (NFC) (#79106)Kazu Hirata
This patch makes a SmallVector slightly larger. We encounter quite a few instructions with 3 or 4 defs but very few beyond that on X86. This saves 0.39% of heap allocations during the compilation of a large preprocessed file, namely X86ISelLowering.cpp, for the X86 target.
2023-12-26[MCP] Enhance MCP copy Instruction removal for special case(reapply) (#74239)Vettel
Machine Copy Propagation Pass may lose some opportunities to further remove the redundant copy instructions during the ForwardCopyPropagateBlock procedure. When we Clobber a "Def" register, we also need to remove the record from the copy maps that indicates "Src" defined "Def" to ensure the correct semantics of the ClobberRegister function. This patch reapplies #70778 and addresses the corner case bug #73512 specific to the AMDGPU backend. Additionally, it refines the criteria for removing empty records from the copy maps, thereby enhancing overall safety. For more information, please see the C++ test case generated code in "vector.body" after the MCP Pass: https://gcc.godbolt.org/z/nK4oMaWv5.
2023-11-27Revert "[MCP] Enhance MCP copy Instruction removal for special case (#70778)"Bjorn Pettersson
This reverts commit cae46f6210293ba4d3568eb21b935d438934290d. Reverted due to miscompiles. See https://github.com/llvm/llvm-project/issues/73512
2023-11-22[MCP] Enhance MCP copy Instruction removal for special case (#70778)Vettel
Machine Copy Propagation Pass may lose some opportunities to further remove the redundant copy instructions during the ForwardCopyPropagateBlock procedure. When we Clobber a "Def" register, we also need to remove the record from the copy maps that indicates "Src" defined "Def" to ensure the correct semantics of the ClobberRegister function. For more information, please see the C++ test case generated code in "vector.body" after the MCP Pass: https://gcc.godbolt.org/z/nK4oMaWv5.
2023-09-22Use llvm::drop_begin and llvm::drop_end (NFC)Kazu Hirata
2023-08-11[MCP] Invalidate copy for super register in copy sourceJeffrey Byrnes
We must also track the super sources of a copy, otherwise we introduce a sort of subtle bug. Consider: 1. DEF r0:r1 2. USE r1 3. r6:r9 = COPY r10:r13 4. r14:15 = COPY r0:r1 5. USE r6 6.. r1:4 = COPY r6:9 BackwardCopyPropagateBlock processes the instructions from bottom up. After processing 6., we will have propagatable copy for r1-r4 and r6-r9. After 5., we invalidate and erase the propagatble copy for r1-r4 and r6 but not for r7-r9. The issue is that when processing 3., data structures still say we have valid copies for dest regs r7-r9 (from 6.). The corresponding defs for these registers in 6. are r1:r4, which we mark as registers to invalidate. When invalidating, we find the copy that corresponds to r1 is 4. (this was added when processing 4.), and we say that r1 now maps to unpropagatable copies. Thus, when we process 2., we do not have a valid copy, but when we process 1. we do -- because the mapped copy for subregister r0 was never invalidated. The net result is to propagate the copy from 4. to 1., and replace DEF r0:r1 with DEF r14:r15. Then, we have a use before def in 2. The main issue is that we have an inconsitent state between which def regs and which src regs are valid. When processing 5., we mark all the defs in 6. as invalid, but only the subreg use as invalid. Either we must only invalidate the individual subreg for both uses and defs, or the super register for both. Differential Revision: https://reviews.llvm.org//D157564 Change-Id: I99d5e0b1a0d735e8ea3bd7d137b6464690aa9486
2023-06-29[MCP] Optimize copies from undefpvanhout
Revert D152502 and instead optimize away copy from undefs, but clear the undef flag on the original copy. Apparently, not optimizing the COPY can cause performance issues in some cases. Fixes SWDEV-405813, SWDEV-405899 Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D153838
2023-06-16[MC] Use regunits instead of MCRegUnitIterator. NFC.Jay Foad
Differential Revision: https://reviews.llvm.org/D153122
2023-06-16[MC] Add MCRegisterInfo::regunits for iteration over register unitsSergei Barannikov
Reviewed By: foad Differential Revision: https://reviews.llvm.org/D152098
2023-06-09[MCP] Do not remove redundant copy for COPY from undefpvanhout
I don't think we can safely remove the second COPY as redundant in such cases. The first COPY (which has undef src) may be lowered to a KILL instruction instead, resulting in no COPY being emitted at all. Testcase is X86 so it's in the same place as other testcases for this function, but this was initially spotted on AMDGPU with the following: ``` renamable $vgpr24 = PRED_COPY undef renamable $vgpr25, implicit $exec renamable $vgpr24 = PRED_COPY killed renamable $vgpr25, implicit $exec ``` The second COPY waas removed as redundant, and the first one was lowered to a KILL (= removed too), causing $vgpr24 to not have $vgpr25's value. Fixes SWDEV-401507 Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D152502
2023-04-20Fix uninitialized class membersAkshay Khadse
Reviewed By: LuoYuanke Differential Revision: https://reviews.llvm.org/D148692
2023-04-17Fix uninitialized pointer members in CodeGenAkshay Khadse
This change initializes the members TSI, LI, DT, PSI, and ORE pointer feilds of the SelectOptimize class to nullptr. Reviewed By: LuoYuanke Differential Revision: https://reviews.llvm.org/D148303
2023-03-30[MCP] Do not try forward non-existent sub-register of a copySergei Barannikov
In this example: ``` $d14 = COPY killed $d18 $s0 = MI $s28 ``` $s28 is a sub-register of $d14. However, $d18 does not have sub-registers and thus cannot be forwarded. Previously, this resulted in $noreg being substituted in place of the use of $s28, which later led to an assertion failure. Fixes https://github.com/llvm/llvm-project/issues/60908, a regression that was introduced in D141747. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D146930
2023-03-25[MachineCopyPropagation] Pass DestSourcePair to isBackwardPropagatableCopy. NFCCraig Topper
Instead of calling isCopyInstr again, just pass the DestSourcePair from the isCopyInstr call from the caller.
2023-02-08[MachineCopyPropagation] Eliminate spillage copies that might be caused by ↵Kai Luo
eviction chain Remove spill-reload like copy chains. For example ``` r0 = COPY r1 r1 = COPY r2 r2 = COPY r3 r3 = COPY r4 <def-use r4> r4 = COPY r3 r3 = COPY r2 r2 = COPY r1 r1 = COPY r0 ``` will be folded into ``` r0 = COPY r1 r1 = COPY r4 <def-use r4> r4 = COPY r1 r1 = COPY r0 ``` Reviewed By: qcolombet Differential Revision: https://reviews.llvm.org/D122118
2023-01-25Resolve a FIXME in MachineCopyPropagation by allowig propagation to ↵Owen Anderson
subregister uses. Reviewed By: barannikov88 Differential Revision: https://reviews.llvm.org/D141747
2022-12-04[Target] llvm::Optional => std::optionalFangrui Song
The updated functions are mostly internal with a few exceptions (virtual functions in TargetInstrInfo.h, TargetRegisterInfo.h). To minimize changes to LLVMCodeGen, GlobalISel files are skipped. https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-02[CodeGen] Use std::nullopt instead of None (NFC)Kazu Hirata
This patch mechanically replaces None with std::nullopt where the compiler would warn if None were deprecated. The intent is to reduce the amount of manual work required in migrating from Optional to std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-06-17[MachineCopyPropagation][RISCV] Fix D125335 accidentally change control flow.Han-Kuan Chen
D125335 makes regsOverlap skip following control flow, which is not entended in the original code. Differential Revision: https://reviews.llvm.org/D128039
2022-05-26Give option to use isCopyInstr to determine which MI isAdrian Tong
treated as Copy instruction in MCP. This is then used in AArch64 to remove copy instructions after taildup ran in machine block placement Differential Revision: https://reviews.llvm.org/D125335
2022-03-21[MachineCopyPropagation] More robust isForwardableRegClassCopyJay Foad
Change the implementation of isForwardableRegClassCopy so that it does not rely on getMinimalPhysRegClass. Instead, iterate over all classes looking for any that satisfy a required property. NFCI on current upstream targets, but this copes better with downstream AMDGPU changes where some new smaller classes have been introduced, which was breaking regclass equality tests in the old code like: if (UseDstRC != CrossCopyRC && CopyDstRC == CrossCopyRC) Differential Revision: https://reviews.llvm.org/D121903