diff options
author | Vettel <924105575@qq.com> | 2023-11-22 23:57:42 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-22 23:57:42 +0800 |
commit | cae46f6210293ba4d3568eb21b935d438934290d (patch) | |
tree | 6c052cfff69407ef1a899ad72d20806b33e1473e /llvm/lib/CodeGen/MachineCopyPropagation.cpp | |
parent | c2b3f16fb595fa88bfd21b455785c59ac6a21ed4 (diff) | |
download | llvm-cae46f6210293ba4d3568eb21b935d438934290d.zip llvm-cae46f6210293ba4d3568eb21b935d438934290d.tar.gz llvm-cae46f6210293ba4d3568eb21b935d438934290d.tar.bz2 |
[MCP] Enhance MCP copy Instruction removal for special case (#70778)
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.
Diffstat (limited to 'llvm/lib/CodeGen/MachineCopyPropagation.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineCopyPropagation.cpp | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp index a032b31..abd6e64 100644 --- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp +++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp @@ -175,8 +175,43 @@ 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 directly + // remove SrcCopy from the tracker's copy maps. + if (SrcCopy->second.DefRegs.empty()) { + Copies.erase(SrcCopy); + } + break; + } + } + } + } } // Now we can erase the copy. Copies.erase(I); @@ -785,6 +820,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { // ... // %xmm2 = copy %xmm9 Tracker.clobberRegister(Def, *TRI, *TII, UseCopyInstr); + for (const MachineOperand &MO : MI.implicit_operands()) { if (!MO.isReg() || !MO.isDef()) continue; @@ -795,7 +831,6 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { } Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr); - continue; } } |