[llvm] [MCP] Enhance MCP copy reovemal for special case (PR #70778)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 31 03:14:25 PDT 2023


https://github.com/LWenH created https://github.com/llvm/llvm-project/pull/70778

- Machine Copy Propagation Pass may lost some opportunities to further remove 
the redundant copy instruction during the **ForwardCopyPropagateBlock** procedure, 
consider the following MI sequence:
```asm  
L1: r0 = COPY r9     <- TrackMI
L2: r0 = COPY r8     <- TrackMI
L3: use r0           <- Remove L2 from MaybeDeadCopies
L4: early-clobber r9 <- Invalid L2 from Tracker
L5: r0 = COPY r8     <- Miss remove chance
L6: use r0           <- Miss remove L5 chance
```
- During the **ForwardCopyPropagateBlock** procedure, we need to invalidate all the  early-clobber register relative
instructions from CopyTracker, because of the **find** method from DenseMap, we might invalidate the "wrong" instruction
in the CopyTracker.  As a result, there is no way to eliminate subsequent redundant instructions (Like L5 in the instruction).

- Please see the C++ test case generated code for **vector.body** in MIR: https://gcc.godbolt.org/z/nK4oMaWv5

>From a42f48a44c614f2c996f3f4cb0561e2f7ab35d6f Mon Sep 17 00:00:00 2001
From: LWenH <924105575 at qq.com>
Date: Tue, 31 Oct 2023 16:33:41 +0800
Subject: [PATCH 1/2] add pre commit test for later mcp patch

---
 llvm/test/CodeGen/RISCV/machine-cp.mir | 34 ++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/machine-cp.mir b/llvm/test/CodeGen/RISCV/machine-cp.mir
index f3674f89cd918b4..9c04abf492a1475 100644
--- a/llvm/test/CodeGen/RISCV/machine-cp.mir
+++ b/llvm/test/CodeGen/RISCV/machine-cp.mir
@@ -9,6 +9,10 @@
   entry:
     ret void
   }
+  define void @bar() {
+  entry:
+    ret void
+  }
 ...
 ---
 name:            foo
@@ -21,6 +25,7 @@ body:             |
     ; RV32-NEXT: renamable $v4_v5_v6_v7_v8_v9_v10_v11 = COPY killed renamable $v0_v1_v2_v3_v4_v5_v6_v7
     ; RV32-NEXT: renamable $v28 = COPY renamable $v8, implicit killed $v28_v29_v30, implicit-def $v28_v29_v30
     ; RV32-NEXT: PseudoRET implicit $v28
+    ;
     ; RV64-LABEL: name: foo
     ; RV64: liveins: $v28_v29_v30, $v8_v9, $v1
     ; RV64-NEXT: {{  $}}
@@ -32,3 +37,32 @@ body:             |
     renamable $v28 = COPY renamable $v8, implicit killed $v28_v29_v30, implicit-def $v28_v29_v30
     PseudoRET implicit $v28
 ...
+---
+name:            bar
+body:             |
+  bb.0.entry:
+    liveins: $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $x28, $x29, $x30, $x31
+    ; RV32-LABEL: name: bar
+    ; RV32: liveins: $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $x28, $x29, $x30, $x31
+    ; RV32-NEXT: {{  $}}
+    ; RV32-NEXT: $v0 = COPY renamable $v8
+    ; RV32-NEXT: renamable $v14m2 = PseudoVLE32_V_M2_MASK undef renamable $v14m2, renamable $x15, $v0, -1, 5 /* e32 */, 1 /* ta, mu */, implicit $vl, implicit $vtype
+    ; RV32-NEXT: early-clobber renamable $v9 = PseudoVMSLE_VI_M2 killed renamable $v10m2, -1, -1, 5 /* e32 */, implicit $vl, implicit $vtype
+    ; RV32-NEXT: $v0 = COPY killed renamable $v8
+    ; RV32-NEXT: PseudoVSE32_V_M2_MASK killed renamable $v14m2, renamable $x9, $v0, -1, 5 /* e32 */, implicit $vl, implicit $vtype
+    ;
+    ; RV64-LABEL: name: bar
+    ; RV64: liveins: $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $x28, $x29, $x30, $x31
+    ; RV64-NEXT: {{  $}}
+    ; RV64-NEXT: $v0 = COPY renamable $v8
+    ; RV64-NEXT: renamable $v14m2 = PseudoVLE32_V_M2_MASK undef renamable $v14m2, renamable $x15, $v0, -1, 5 /* e32 */, 1 /* ta, mu */, implicit $vl, implicit $vtype
+    ; RV64-NEXT: early-clobber renamable $v9 = PseudoVMSLE_VI_M2 killed renamable $v10m2, -1, -1, 5 /* e32 */, implicit $vl, implicit $vtype
+    ; RV64-NEXT: $v0 = COPY killed renamable $v8
+    ; RV64-NEXT: PseudoVSE32_V_M2_MASK killed renamable $v14m2, renamable $x9, $v0, -1, 5 /* e32 */, implicit $vl, implicit $vtype
+    $v0 = COPY killed renamable $v9; example.cpp:14:22
+    $v0 = COPY renamable $v8; example.cpp:12:25
+    renamable $v14m2 = PseudoVLE32_V_M2_MASK undef renamable $v14m2, renamable $x15, $v0, -1, 5, 1, implicit $vl, implicit $vtype; example.cpp:12:25
+    early-clobber renamable $v9 = PseudoVMSLE_VI_M2 killed renamable $v10m2, -1, -1, 5, implicit $vl, implicit $vtype; example.cpp:9:22
+    $v0 = COPY killed renamable $v8; example.cpp:12:22
+    PseudoVSE32_V_M2_MASK killed renamable $v14m2, renamable $x9, $v0, -1, 5, implicit $vl, implicit $vtype; example.cpp:12:22
+...

>From 516d95d53b00d1478aca2ad3f180eb6a3dc3d24b Mon Sep 17 00:00:00 2001
From: LWenH <924105575 at qq.com>
Date: Tue, 31 Oct 2023 17:39:04 +0800
Subject: [PATCH 2/2] mcp: further enhance chance for reduncdant copy removal

---
 llvm/lib/CodeGen/MachineCopyPropagation.cpp | 25 +++++++++++++++++++++
 llvm/test/CodeGen/RISCV/machine-cp.mir      |  2 --
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
index a032b31a1fc7c62..b0640b48121febd 100644
--- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
@@ -719,6 +719,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
   LLVM_DEBUG(dbgs() << "MCP: ForwardCopyPropagateBlock " << MBB.getName()
                     << "\n");
 
+  const MachineInstr *LastMI = nullptr;
   for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
     // Analyze copies (which don't overlap themselves).
     std::optional<DestSourcePair> CopyOperands =
@@ -735,6 +736,27 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
         MCRegister Def = RegDef.asMCReg();
         MCRegister Src = RegSrc.asMCReg();
 
+        // Target may lost some opportunity to further remove the redundant
+        // copy instruction, consider the following sequence:
+        // L1: r0 = COPY r9     <- TrackMI
+        // L2: r0 = COPY r8     <- TrackMI
+        // L3: use r0           <- Remove L2 from MaybeDeadCopies
+        // L4: early-clobber r9 <- Invalid L2 from Tracker
+        // L5: r0 = COPY r8     <- Miss remove chance
+        // L6: use r0           <- Miss remove L5 chance
+        if (LastMI) {
+          std::optional<DestSourcePair> PrevCopyOperands =
+              isCopyInstr(*LastMI, *TII, UseCopyInstr);
+          if (PrevCopyOperands) {
+            Register PrevRegDef = PrevCopyOperands->Destination->getReg();
+            // We could remove the previous copy from tracker directly.
+            if (TRI->isSubRegisterEq(RegDef, PrevRegDef)) {
+              Tracker.invalidateRegister(PrevRegDef.asMCReg(), *TRI, *TII,
+                                         UseCopyInstr);
+            }
+          }
+        }
+
         // The two copies cancel out and the source of the first copy
         // hasn't been overridden, eliminate the second one. e.g.
         //  %ecx = COPY %eax
@@ -795,6 +817,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
         }
 
         Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr);
+        LastMI = &MI;
 
         continue;
       }
@@ -874,6 +897,8 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
     // Any previous copy definition or reading the Defs is no longer available.
     for (MCRegister Reg : Defs)
       Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr);
+
+    LastMI = &MI;
   }
 
   // If MBB doesn't have successors, delete the copies whose defs are not used.
diff --git a/llvm/test/CodeGen/RISCV/machine-cp.mir b/llvm/test/CodeGen/RISCV/machine-cp.mir
index 9c04abf492a1475..7523332a23c6839 100644
--- a/llvm/test/CodeGen/RISCV/machine-cp.mir
+++ b/llvm/test/CodeGen/RISCV/machine-cp.mir
@@ -48,7 +48,6 @@ body:             |
     ; RV32-NEXT: $v0 = COPY renamable $v8
     ; RV32-NEXT: renamable $v14m2 = PseudoVLE32_V_M2_MASK undef renamable $v14m2, renamable $x15, $v0, -1, 5 /* e32 */, 1 /* ta, mu */, implicit $vl, implicit $vtype
     ; RV32-NEXT: early-clobber renamable $v9 = PseudoVMSLE_VI_M2 killed renamable $v10m2, -1, -1, 5 /* e32 */, implicit $vl, implicit $vtype
-    ; RV32-NEXT: $v0 = COPY killed renamable $v8
     ; RV32-NEXT: PseudoVSE32_V_M2_MASK killed renamable $v14m2, renamable $x9, $v0, -1, 5 /* e32 */, implicit $vl, implicit $vtype
     ;
     ; RV64-LABEL: name: bar
@@ -57,7 +56,6 @@ body:             |
     ; RV64-NEXT: $v0 = COPY renamable $v8
     ; RV64-NEXT: renamable $v14m2 = PseudoVLE32_V_M2_MASK undef renamable $v14m2, renamable $x15, $v0, -1, 5 /* e32 */, 1 /* ta, mu */, implicit $vl, implicit $vtype
     ; RV64-NEXT: early-clobber renamable $v9 = PseudoVMSLE_VI_M2 killed renamable $v10m2, -1, -1, 5 /* e32 */, implicit $vl, implicit $vtype
-    ; RV64-NEXT: $v0 = COPY killed renamable $v8
     ; RV64-NEXT: PseudoVSE32_V_M2_MASK killed renamable $v14m2, renamable $x9, $v0, -1, 5 /* e32 */, implicit $vl, implicit $vtype
     $v0 = COPY killed renamable $v9; example.cpp:14:22
     $v0 = COPY renamable $v8; example.cpp:12:25



More information about the llvm-commits mailing list