[llvm] [RISCV] Add a pass to eliminate special copies in order to facilitate shrink-wrap optimization (PR #140716)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue May 20 10:55:48 PDT 2025


================
@@ -0,0 +1,150 @@
+//===- RISCVCopyCombine.cpp - Remove special copy for RISC-V --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===---------------------------------------------------------------------===//
+//
+// This pass attempts a shrink-wrap optimization for special cases, which is
+// effective when data types require extension.
+//
+// After finalize-isel:
+//   bb0:
+//   liveins: $x10, $x11
+//     %1:gpr = COPY $x11   ---- will be delete in this pass
+//     %0:gpr = COPY $x10
+//     %2:gpr = COPY %1:gpr ---- without this pass, sink to bb1 in machine-sink,
+//                               then delete at regalloc
+//     BEQ %0:gpr, killed %3:gpr, %bb.3 PseudoBR %bb1
+//
+//   bb1:
+//   bb2:
+//     BNE %2:gpr, killed %5:gpr, %bb.2
+// ...
+// After regalloc
+//  bb0:
+//    liveins: $x10, $x11
+//    renamable $x8 = COPY $x11
+//    renamable $x11 = ADDI $x0, 57 --- def x11, so COPY can not be sink
+//    BEQ killed renamable $x10, killed renamable $x11, %bb.4
+//    PseudoBR %bb.1
+//
+//  bb1:
+//  bb2:
+//    BEQ killed renamable $x8, killed renamable $x10, %bb.4
+//
+// ----->
+//
+// After this pass:
+//   bb0:
+//   liveins: $x10, $x11
+//     %0:gpr = COPY $x10
+//     %2:gpr = COPY $x11
+//     BEQ %0:gpr, killed %3:gpr, %bb.3
+//     PseudoBR %bb1
+//
+//   bb1:
+//   bb2:
+//     BNE %2:gpr, killed %5:gpr, %bb.2
+// ...
+// After regalloc
+//  bb0:
+//    liveins: $x10, $x11
+//    renamable $x12 = ADDI $x0, 57
+//    renamable $x8 = COPY $x11
+//    BEQ killed renamable $x10, killed renamable $x11, %bb.4
+//    PseudoBR %bb.1
+//
+//  bb1:
+//  bb2:
+//    BEQ killed renamable $x8, killed renamable $x10, %bb.4
+//===---------------------------------------------------------------------===//
+
+#include "RISCV.h"
+#include "RISCVSubtarget.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+using namespace llvm;
+#define DEBUG_TYPE "riscv-copy-combine"
+#define RISCV_COPY_COMBINE "RISC-V Copy Combine"
+
+STATISTIC(NumCopyDeleted, "Number of copy deleted");
+
+namespace {
+class RISCVCopyCombine : public MachineFunctionPass {
+public:
+  static char ID;
+  const TargetInstrInfo *TII;
+  MachineRegisterInfo *MRI;
+  const TargetRegisterInfo *TRI;
+  const RISCVSubtarget *ST;
+
+  RISCVCopyCombine() : MachineFunctionPass(ID) {}
+  bool runOnMachineFunction(MachineFunction &MF) override;
+  MachineFunctionProperties getRequiredProperties() const override {
+    return MachineFunctionProperties().set(
+        MachineFunctionProperties::Property::IsSSA);
+  }
+
+  StringRef getPassName() const override { return RISCV_COPY_COMBINE; }
+
+private:
+  bool optimizeBlock(MachineBasicBlock &MBB);
+};
+} // end anonymous namespace
+
+char RISCVCopyCombine::ID = 0;
+INITIALIZE_PASS(RISCVCopyCombine, DEBUG_TYPE, RISCV_COPY_COMBINE, false, false)
+
+bool RISCVCopyCombine::optimizeBlock(MachineBasicBlock &MBB) {
+  MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
+  SmallVector<MachineOperand, 3> Cond;
+  if (TII->analyzeBranch(MBB, TBB, FBB, Cond, /*AllowModify*/ false) ||
+      Cond.empty())
+    return false;
+
+  if (!TBB || Cond.size() != 3)
+    return false;
+
+  MachineInstr *MI = MRI->getVRegDef(Cond[1].getReg());
+  if (MI->getOpcode() == RISCV::COPY) {
+    if (MRI->hasOneUse(MI->getOperand(1).getReg()) &&
+        MI->getOperand(1).getReg().isVirtual() &&
+        MI->getOperand(0).getReg().isVirtual()) {
+      MachineInstr *Src = MRI->getVRegDef(MI->getOperand(1).getReg());
+      if (Src && Src->getOpcode() == RISCV::COPY &&
+          Src->getParent() == MI->getParent()) {
+        MRI->replaceRegWith(MI->getOperand(1).getReg(),
+                            Src->getOperand(1).getReg());
+        LLVM_DEBUG(dbgs() << "Deleting this copy instruction ";
+                   Src->print(dbgs()));
+        ++NumCopyDeleted;
+        Src->eraseFromParent();
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+bool RISCVCopyCombine::runOnMachineFunction(MachineFunction &MF) {
+  if (skipFunction(MF.getFunction()))
+    return false;
+
+  TII = MF.getSubtarget().getInstrInfo();
+  ;
----------------
topperc wrote:

Stray semicolon

https://github.com/llvm/llvm-project/pull/140716


More information about the llvm-commits mailing list