diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2024-01-03 18:04:11 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-06 20:13:16 +0000 |
commit | 647cbc5de815c5651677bf8582797f716ec7b48d (patch) | |
tree | 0a57db146d82068137e0fe0109ca612aaef5afb6 /contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp | |
parent | edc2dc17b1f2dfe45dc85e6cc0ff54bca1ac8214 (diff) | |
parent | 77dbea07356e1ab2f37a777d4d1ddc5dd3e301c2 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp index a032b31a1fc7..51e944d0279f 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp @@ -175,8 +175,46 @@ public: if (MachineInstr *MI = I->second.MI) { std::optional<DestSourcePair> CopyOperands = isCopyInstr(*MI, TII, UseCopyInstr); - markRegsUnavailable({CopyOperands->Destination->getReg().asMCReg()}, - TRI); + + MCRegister Def = CopyOperands->Destination->getReg().asMCReg(); + MCRegister Src = CopyOperands->Source->getReg().asMCReg(); + + markRegsUnavailable(Def, TRI); + + // Since we clobber the destination of a copy, the semantic of Src's + // "DefRegs" to contain Def is no longer effectual. We will also need + // to remove the record from the copy maps that indicates Src defined + // Def. Failing to do so might cause the target to miss some + // opportunities to further eliminate redundant copy instructions. + // Consider the following sequence during the + // ForwardCopyPropagateBlock procedure: + // L1: r0 = COPY r9 <- TrackMI + // L2: r0 = COPY r8 <- TrackMI (Remove r9 defined r0 from tracker) + // L3: use r0 <- Remove L2 from MaybeDeadCopies + // L4: early-clobber r9 <- Clobber r9 (L2 is still valid in tracker) + // L5: r0 = COPY r8 <- Remove NopCopy + for (MCRegUnit SrcUnit : TRI.regunits(Src)) { + auto SrcCopy = Copies.find(SrcUnit); + if (SrcCopy != Copies.end() && SrcCopy->second.LastSeenUseInCopy) { + // If SrcCopy defines multiple values, we only need + // to erase the record for Def in DefRegs. + for (auto itr = SrcCopy->second.DefRegs.begin(); + itr != SrcCopy->second.DefRegs.end(); itr++) { + if (*itr == Def) { + SrcCopy->second.DefRegs.erase(itr); + // If DefReg becomes empty after removal, we can remove the + // SrcCopy from the tracker's copy maps. We only remove those + // entries solely record the Def is defined by Src. If an + // entry also contains the definition record of other Def' + // registers, it cannot be cleared. + if (SrcCopy->second.DefRegs.empty() && !SrcCopy->second.MI) { + Copies.erase(SrcCopy); + } + break; + } + } + } + } } // Now we can erase the copy. Copies.erase(I); |