[llvm] [CodeGen] Port `two-address-instructions` to new pass manager (PR #98632)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 14 22:04:25 PDT 2024


https://github.com/paperchalice updated https://github.com/llvm/llvm-project/pull/98632

>From 4efa1a1935a1ebf3f31ab4627f37fe4461ea8b45 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Fri, 12 Jul 2024 21:34:06 +0800
Subject: [PATCH] [CodeGen] Port `two-address-instructions` to new pass manager

---
 .../llvm/CodeGen/TwoAddressInstructionPass.h  |  29 +++
 llvm/include/llvm/InitializePasses.h          |   2 +-
 llvm/include/llvm/Passes/CodeGenPassBuilder.h |   1 +
 .../llvm/Passes/MachinePassRegistry.def       |   2 +-
 llvm/lib/CodeGen/CodeGen.cpp                  |   2 +-
 .../lib/CodeGen/TwoAddressInstructionPass.cpp | 190 +++++++++++-------
 llvm/lib/Passes/PassBuilder.cpp               |   1 +
 .../CodeGen/AArch64/statepoint-twoaddr.mir    |   1 +
 .../GlobalISel/twoaddr-extract-dyn-v7f64.mir  |   1 +
 .../early-lis-two-address-partial-def.mir     |   1 +
 .../test/CodeGen/AMDGPU/gfx10-twoaddr-fma.mir |   2 +
 .../test/CodeGen/AMDGPU/gfx11-twoaddr-fma.mir |   1 +
 llvm/test/CodeGen/AMDGPU/twoaddr-fma-f64.mir  |   2 +
 llvm/test/CodeGen/AMDGPU/twoaddr-fma.mir      |   2 +
 llvm/test/CodeGen/AMDGPU/twoaddr-mad.mir      |   1 +
 llvm/test/CodeGen/AMDGPU/twoaddr-wmma.mir     |   1 +
 .../CodeGen/Hexagon/two-addr-tied-subregs.mir |   1 +
 llvm/test/CodeGen/X86/distancemap.mir         |   1 +
 .../CodeGen/X86/statepoint-vreg-twoaddr.mir   |   1 +
 llvm/test/CodeGen/X86/twoaddr-mul2.mir        |   1 +
 20 files changed, 170 insertions(+), 73 deletions(-)
 create mode 100644 llvm/include/llvm/CodeGen/TwoAddressInstructionPass.h

diff --git a/llvm/include/llvm/CodeGen/TwoAddressInstructionPass.h b/llvm/include/llvm/CodeGen/TwoAddressInstructionPass.h
new file mode 100644
index 0000000000000..7f2a070c58434
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/TwoAddressInstructionPass.h
@@ -0,0 +1,29 @@
+//===- llvm/CodeGen/TwoAddressInstructionPass.h -----------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_TWOADDRESSINSTRUCTIONPASS_H
+#define LLVM_CODEGEN_TWOADDRESSINSTRUCTIONPASS_H
+
+#include "llvm/CodeGen/MachinePassManager.h"
+
+namespace llvm {
+
+class TwoAddressInstructionPass
+    : public PassInfoMixin<TwoAddressInstructionPass> {
+public:
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+  MachineFunctionProperties getSetProperties() {
+    return MachineFunctionProperties().set(
+        MachineFunctionProperties::Property::TiedOpsRewritten);
+  }
+};
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_TWOADDRESSINSTRUCTIONPASS_H
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index c9dc8ac2e5d11..13be9c11f0107 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -298,7 +298,7 @@ void initializeTargetLibraryInfoWrapperPassPass(PassRegistry&);
 void initializeTargetPassConfigPass(PassRegistry&);
 void initializeTargetTransformInfoWrapperPassPass(PassRegistry&);
 void initializeTLSVariableHoistLegacyPassPass(PassRegistry &);
-void initializeTwoAddressInstructionPassPass(PassRegistry&);
+void initializeTwoAddressInstructionLegacyPassPass(PassRegistry &);
 void initializeTypeBasedAAWrapperPassPass(PassRegistry&);
 void initializeTypePromotionLegacyPass(PassRegistry&);
 void initializeInitUndefPass(PassRegistry &);
diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index 81900510c9ae7..5b8e69b602e2b 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -52,6 +52,7 @@
 #include "llvm/CodeGen/SjLjEHPrepare.h"
 #include "llvm/CodeGen/StackProtector.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/CodeGen/TwoAddressInstructionPass.h"
 #include "llvm/CodeGen/UnreachableBlockElim.h"
 #include "llvm/CodeGen/WasmEHPrepare.h"
 #include "llvm/CodeGen/WinEHPrepare.h"
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index 65e9e268b2a59..a47d7494f2eef 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -148,6 +148,7 @@ MACHINE_FUNCTION_PASS("print<slot-indexes>", SlotIndexesPrinterPass(dbgs()))
 MACHINE_FUNCTION_PASS("require-all-machine-function-properties",
                       RequireAllMachineFunctionPropertiesPass())
 MACHINE_FUNCTION_PASS("trigger-verifier-error", TriggerVerifierErrorPass())
+MACHINE_FUNCTION_PASS("two-address-instruction", TwoAddressInstructionPass())
 MACHINE_FUNCTION_PASS("verify", MachineVerifierPass())
 #undef MACHINE_FUNCTION_PASS
 
@@ -258,7 +259,6 @@ DUMMY_MACHINE_FUNCTION_PASS("stack-frame-layout", StackFrameLayoutAnalysisPass)
 DUMMY_MACHINE_FUNCTION_PASS("stack-slot-coloring", StackSlotColoringPass)
 DUMMY_MACHINE_FUNCTION_PASS("stackmap-liveness", StackMapLivenessPass)
 DUMMY_MACHINE_FUNCTION_PASS("tailduplication", TailDuplicatePass)
-DUMMY_MACHINE_FUNCTION_PASS("twoaddressinstruction", TwoAddressInstructionPass)
 DUMMY_MACHINE_FUNCTION_PASS("unpack-mi-bundles", UnpackMachineBundlesPass)
 DUMMY_MACHINE_FUNCTION_PASS("virtregrewriter", VirtRegRewriterPass)
 DUMMY_MACHINE_FUNCTION_PASS("xray-instrumentation", XRayInstrumentationPass)
diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp
index f67244d280c9e..31fa4c105cef8 100644
--- a/llvm/lib/CodeGen/CodeGen.cpp
+++ b/llvm/lib/CodeGen/CodeGen.cpp
@@ -132,7 +132,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
   initializeStripDebugMachineModulePass(Registry);
   initializeTailDuplicatePass(Registry);
   initializeTargetPassConfigPass(Registry);
-  initializeTwoAddressInstructionPassPass(Registry);
+  initializeTwoAddressInstructionLegacyPassPass(Registry);
   initializeTypePromotionLegacyPass(Registry);
   initializeUnpackMachineBundlesPass(Registry);
   initializeUnreachableBlockElimLegacyPassPass(Registry);
diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
index 73385fee019b0..665d57841a97b 100644
--- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -26,6 +26,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/CodeGen/TwoAddressInstructionPass.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
@@ -36,10 +37,12 @@
 #include "llvm/CodeGen/LiveIntervals.h"
 #include "llvm/CodeGen/LiveVariables.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineDominators.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineLoopInfo.h"
 #include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/Passes.h"
@@ -86,7 +89,7 @@ static cl::opt<unsigned> MaxDataFlowEdge(
 
 namespace {
 
-class TwoAddressInstructionPass : public MachineFunctionPass {
+class TwoAddressInstructionImpl {
   MachineFunction *MF = nullptr;
   const TargetInstrInfo *TII = nullptr;
   const TargetRegisterInfo *TRI = nullptr;
@@ -185,11 +188,31 @@ class TwoAddressInstructionPass : public MachineFunctionPass {
   void eliminateRegSequence(MachineBasicBlock::iterator&);
   bool processStatepoint(MachineInstr *MI, TiedOperandMap &TiedOperands);
 
+public:
+  TwoAddressInstructionImpl(MachineFunction &MF, MachineFunctionPass *P);
+  TwoAddressInstructionImpl(MachineFunction &MF,
+                            MachineFunctionAnalysisManager &MFAM);
+  void setOptLevel(CodeGenOptLevel Level) { OptLevel = Level; }
+  bool run();
+};
+
+class TwoAddressInstructionLegacyPass : public MachineFunctionPass {
 public:
   static char ID; // Pass identification, replacement for typeid
 
-  TwoAddressInstructionPass() : MachineFunctionPass(ID) {
-    initializeTwoAddressInstructionPassPass(*PassRegistry::getPassRegistry());
+  TwoAddressInstructionLegacyPass() : MachineFunctionPass(ID) {
+    initializeTwoAddressInstructionLegacyPassPass(
+        *PassRegistry::getPassRegistry());
+  }
+
+  /// Pass entry point.
+  bool runOnMachineFunction(MachineFunction &MF) override {
+    TwoAddressInstructionImpl Impl(MF, this);
+    // Disable optimizations if requested. We cannot skip the whole pass as some
+    // fixups are necessary for correctness.
+    if (skipFunction(MF.getFunction()))
+      Impl.setOptLevel(CodeGenOptLevel::None);
+    return Impl.run();
   }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -203,26 +226,76 @@ class TwoAddressInstructionPass : public MachineFunctionPass {
     AU.addPreservedID(MachineDominatorsID);
     MachineFunctionPass::getAnalysisUsage(AU);
   }
-
-  /// Pass entry point.
-  bool runOnMachineFunction(MachineFunction&) override;
 };
 
 } // end anonymous namespace
 
-char TwoAddressInstructionPass::ID = 0;
+PreservedAnalyses
+TwoAddressInstructionPass::run(MachineFunction &MF,
+                               MachineFunctionAnalysisManager &MFAM) {
+  // Disable optimizations if requested. We cannot skip the whole pass as some
+  // fixups are necessary for correctness.
+  TwoAddressInstructionImpl Impl(MF, MFAM);
+  if (MF.getFunction().hasOptNone())
+    Impl.setOptLevel(CodeGenOptLevel::None);
+
+  MFPropsModifier _(*this, MF);
+  bool Changed = Impl.run();
+  if (!Changed)
+    return PreservedAnalyses::all();
+  auto PA = getMachineFunctionPassPreservedAnalyses();
+  PA.preserve<LiveIntervalsAnalysis>();
+  PA.preserve<LiveVariablesAnalysis>();
+  PA.preserve<MachineDominatorTreeAnalysis>();
+  PA.preserve<MachineLoopAnalysis>();
+  PA.preserve<SlotIndexesAnalysis>();
+  PA.preserveSet<CFGAnalyses>();
+  return PA;
+}
+
+char TwoAddressInstructionLegacyPass::ID = 0;
 
-char &llvm::TwoAddressInstructionPassID = TwoAddressInstructionPass::ID;
+char &llvm::TwoAddressInstructionPassID = TwoAddressInstructionLegacyPass::ID;
 
-INITIALIZE_PASS_BEGIN(TwoAddressInstructionPass, DEBUG_TYPE,
-                "Two-Address instruction pass", false, false)
+INITIALIZE_PASS_BEGIN(TwoAddressInstructionLegacyPass, DEBUG_TYPE,
+                      "Two-Address instruction pass", false, false)
 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
-INITIALIZE_PASS_END(TwoAddressInstructionPass, DEBUG_TYPE,
-                "Two-Address instruction pass", false, false)
+INITIALIZE_PASS_END(TwoAddressInstructionLegacyPass, DEBUG_TYPE,
+                    "Two-Address instruction pass", false, false)
+
+TwoAddressInstructionImpl::TwoAddressInstructionImpl(
+    MachineFunction &Func, MachineFunctionAnalysisManager &MFAM)
+    : MF(&Func), TII(Func.getSubtarget().getInstrInfo()),
+      TRI(Func.getSubtarget().getRegisterInfo()),
+      InstrItins(Func.getSubtarget().getInstrItineraryData()),
+      MRI(&Func.getRegInfo()),
+      LV(MFAM.getCachedResult<LiveVariablesAnalysis>(Func)),
+      LIS(MFAM.getCachedResult<LiveIntervalsAnalysis>(Func)),
+      OptLevel(Func.getTarget().getOptLevel()) {
+  auto &FAM = MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(Func)
+                  .getManager();
+  AA = FAM.getCachedResult<AAManager>(Func.getFunction());
+}
+
+TwoAddressInstructionImpl::TwoAddressInstructionImpl(MachineFunction &Func,
+                                                     MachineFunctionPass *P)
+    : MF(&Func), TII(Func.getSubtarget().getInstrInfo()),
+      TRI(Func.getSubtarget().getRegisterInfo()),
+      InstrItins(Func.getSubtarget().getInstrItineraryData()),
+      MRI(&Func.getRegInfo()), OptLevel(Func.getTarget().getOptLevel()) {
+  auto *LVWrapper = P->getAnalysisIfAvailable<LiveVariablesWrapperPass>();
+  LV = LVWrapper ? &LVWrapper->getLV() : nullptr;
+  auto *LISWrapper = P->getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
+  LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
+  if (auto *AAPass = P->getAnalysisIfAvailable<AAResultsWrapperPass>())
+    AA = &AAPass->getAAResults();
+  else
+    AA = nullptr;
+}
 
 /// Return the MachineInstr* if it is the single def of the Reg in current BB.
 MachineInstr *
-TwoAddressInstructionPass::getSingleDef(Register Reg,
+TwoAddressInstructionImpl::getSingleDef(Register Reg,
                                         MachineBasicBlock *BB) const {
   MachineInstr *Ret = nullptr;
   for (MachineInstr &DefMI : MRI->def_instructions(Reg)) {
@@ -243,7 +316,7 @@ TwoAddressInstructionPass::getSingleDef(Register Reg,
 /// %Tmp2 = copy %ToReg;
 /// MaxLen specifies the maximum length of the copy chain the func
 /// can walk through.
-bool TwoAddressInstructionPass::isRevCopyChain(Register FromReg, Register ToReg,
+bool TwoAddressInstructionImpl::isRevCopyChain(Register FromReg, Register ToReg,
                                                int Maxlen) {
   Register TmpReg = FromReg;
   for (int i = 0; i < Maxlen; i++) {
@@ -263,7 +336,7 @@ bool TwoAddressInstructionPass::isRevCopyChain(Register FromReg, Register ToReg,
 /// in the MBB that defines the specified register and the two-address
 /// instruction which is being processed. It also returns the last def location
 /// by reference.
-bool TwoAddressInstructionPass::noUseAfterLastDef(Register Reg, unsigned Dist,
+bool TwoAddressInstructionImpl::noUseAfterLastDef(Register Reg, unsigned Dist,
                                                   unsigned &LastDef) {
   LastDef = 0;
   unsigned LastUse = Dist;
@@ -286,7 +359,7 @@ bool TwoAddressInstructionPass::noUseAfterLastDef(Register Reg, unsigned Dist,
 /// Return true if the specified MI is a copy instruction or an extract_subreg
 /// instruction. It also returns the source and destination registers and
 /// whether they are physical registers by reference.
-bool TwoAddressInstructionPass::isCopyToReg(MachineInstr &MI, Register &SrcReg,
+bool TwoAddressInstructionImpl::isCopyToReg(MachineInstr &MI, Register &SrcReg,
                                             Register &DstReg, bool &IsSrcPhys,
                                             bool &IsDstPhys) const {
   SrcReg = 0;
@@ -306,7 +379,7 @@ bool TwoAddressInstructionPass::isCopyToReg(MachineInstr &MI, Register &SrcReg,
   return true;
 }
 
-bool TwoAddressInstructionPass::isPlainlyKilled(const MachineInstr *MI,
+bool TwoAddressInstructionImpl::isPlainlyKilled(const MachineInstr *MI,
                                                 LiveRange &LR) const {
   // This is to match the kill flag version where undefs don't have kill flags.
   if (!LR.hasAtLeastOneValue())
@@ -320,7 +393,7 @@ bool TwoAddressInstructionPass::isPlainlyKilled(const MachineInstr *MI,
 
 /// Test if the given register value, which is used by the
 /// given instruction, is killed by the given instruction.
-bool TwoAddressInstructionPass::isPlainlyKilled(const MachineInstr *MI,
+bool TwoAddressInstructionImpl::isPlainlyKilled(const MachineInstr *MI,
                                                 Register Reg) const {
   // FIXME: Sometimes tryInstructionTransform() will add instructions and
   // test whether they can be folded before keeping them. In this case it
@@ -344,7 +417,7 @@ bool TwoAddressInstructionPass::isPlainlyKilled(const MachineInstr *MI,
 
 /// Test if the register used by the given operand is killed by the operand's
 /// instruction.
-bool TwoAddressInstructionPass::isPlainlyKilled(
+bool TwoAddressInstructionImpl::isPlainlyKilled(
     const MachineOperand &MO) const {
   return MO.isKill() || isPlainlyKilled(MO.getParent(), MO.getReg());
 }
@@ -366,7 +439,7 @@ bool TwoAddressInstructionPass::isPlainlyKilled(
 ///
 /// If allowFalsePositives is true then likely kills are treated as kills even
 /// if it can't be proven that they are kills.
-bool TwoAddressInstructionPass::isKilled(MachineInstr &MI, Register Reg,
+bool TwoAddressInstructionImpl::isKilled(MachineInstr &MI, Register Reg,
                                          bool allowFalsePositives) const {
   MachineInstr *DefMI = &MI;
   while (true) {
@@ -411,7 +484,7 @@ static bool isTwoAddrUse(MachineInstr &MI, Register Reg, Register &DstReg) {
 
 /// Given a register, if all its uses are in the same basic block, return the
 /// last use instruction if it's a copy or a two-address use.
-MachineInstr *TwoAddressInstructionPass::findOnlyInterestingUse(
+MachineInstr *TwoAddressInstructionImpl::findOnlyInterestingUse(
     Register Reg, MachineBasicBlock *MBB, bool &IsCopy, Register &DstReg,
     bool &IsDstPhys) const {
   MachineOperand *UseOp = nullptr;
@@ -468,7 +541,7 @@ static MCRegister getMappedReg(Register Reg,
 }
 
 /// Return true if the two registers are equal or aliased.
-bool TwoAddressInstructionPass::regsAreCompatible(Register RegA,
+bool TwoAddressInstructionImpl::regsAreCompatible(Register RegA,
                                                   Register RegB) const {
   if (RegA == RegB)
     return true;
@@ -478,7 +551,7 @@ bool TwoAddressInstructionPass::regsAreCompatible(Register RegA,
 }
 
 /// From RegMap remove entries mapped to a physical register which overlaps MO.
-void TwoAddressInstructionPass::removeMapRegEntry(
+void TwoAddressInstructionImpl::removeMapRegEntry(
     const MachineOperand &MO, DenseMap<Register, Register> &RegMap) const {
   assert(
       (MO.isReg() || MO.isRegMask()) &&
@@ -510,7 +583,7 @@ void TwoAddressInstructionPass::removeMapRegEntry(
 ///
 /// After the MUL instruction, $rdx contains different value than in the COPY
 /// instruction. So %2 should not map to $rdx after MUL.
-void TwoAddressInstructionPass::removeClobberedSrcRegMap(MachineInstr *MI) {
+void TwoAddressInstructionImpl::removeClobberedSrcRegMap(MachineInstr *MI) {
   if (MI->isCopy()) {
     // If a virtual register is copied to its mapped physical register, it
     // doesn't change the potential coalescing between them, so we don't remove
@@ -546,7 +619,7 @@ void TwoAddressInstructionPass::removeClobberedSrcRegMap(MachineInstr *MI) {
 }
 
 // Returns true if Reg is equal or aliased to at least one register in Set.
-bool TwoAddressInstructionPass::regOverlapsSet(
+bool TwoAddressInstructionImpl::regOverlapsSet(
     const SmallVectorImpl<Register> &Set, Register Reg) const {
   for (unsigned R : Set)
     if (TRI->regsOverlap(R, Reg))
@@ -557,7 +630,7 @@ bool TwoAddressInstructionPass::regOverlapsSet(
 
 /// Return true if it's potentially profitable to commute the two-address
 /// instruction that's being processed.
-bool TwoAddressInstructionPass::isProfitableToCommute(Register RegA,
+bool TwoAddressInstructionImpl::isProfitableToCommute(Register RegA,
                                                       Register RegB,
                                                       Register RegC,
                                                       MachineInstr *MI,
@@ -662,7 +735,7 @@ bool TwoAddressInstructionPass::isProfitableToCommute(Register RegA,
 
 /// Commute a two-address instruction and update the basic block, distance map,
 /// and live variables if needed. Return true if it is successful.
-bool TwoAddressInstructionPass::commuteInstruction(MachineInstr *MI,
+bool TwoAddressInstructionImpl::commuteInstruction(MachineInstr *MI,
                                                    unsigned DstIdx,
                                                    unsigned RegBIdx,
                                                    unsigned RegCIdx,
@@ -693,7 +766,7 @@ bool TwoAddressInstructionPass::commuteInstruction(MachineInstr *MI,
 
 /// Return true if it is profitable to convert the given 2-address instruction
 /// to a 3-address one.
-bool TwoAddressInstructionPass::isProfitableToConv3Addr(Register RegA,
+bool TwoAddressInstructionImpl::isProfitableToConv3Addr(Register RegA,
                                                         Register RegB) {
   // Look for situations like this:
   // %reg1024 = MOV r1
@@ -710,7 +783,7 @@ bool TwoAddressInstructionPass::isProfitableToConv3Addr(Register RegA,
 
 /// Convert the specified two-address instruction into a three address one.
 /// Return true if this transformation was successful.
-bool TwoAddressInstructionPass::convertInstTo3Addr(
+bool TwoAddressInstructionImpl::convertInstTo3Addr(
     MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi,
     Register RegA, Register RegB, unsigned &Dist) {
   MachineInstrSpan MIS(mi, MBB);
@@ -752,7 +825,7 @@ bool TwoAddressInstructionPass::convertInstTo3Addr(
 
 /// Scan forward recursively for only uses, update maps if the use is a copy or
 /// a two-address instruction.
-void TwoAddressInstructionPass::scanUses(Register DstReg) {
+void TwoAddressInstructionImpl::scanUses(Register DstReg) {
   SmallVector<Register, 4> VirtRegPairs;
   bool IsDstPhys;
   bool IsCopy = false;
@@ -805,7 +878,7 @@ void TwoAddressInstructionPass::scanUses(Register DstReg) {
 /// coalesced to r0 (from the input side). v1025 is mapped to r1. v1026 is
 /// potentially joined with r1 on the output side. It's worthwhile to commute
 /// 'add' to eliminate a copy.
-void TwoAddressInstructionPass::processCopy(MachineInstr *MI) {
+void TwoAddressInstructionImpl::processCopy(MachineInstr *MI) {
   if (Processed.count(MI))
     return;
 
@@ -831,7 +904,7 @@ void TwoAddressInstructionPass::processCopy(MachineInstr *MI) {
 /// If there is one more local instruction that reads 'Reg' and it kills 'Reg,
 /// consider moving the instruction below the kill instruction in order to
 /// eliminate the need for the copy.
-bool TwoAddressInstructionPass::rescheduleMIBelowKill(
+bool TwoAddressInstructionImpl::rescheduleMIBelowKill(
     MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi,
     Register Reg) {
   // Bail immediately if we don't have LV or LIS available. We use them to find
@@ -998,7 +1071,7 @@ bool TwoAddressInstructionPass::rescheduleMIBelowKill(
 
 /// Return true if the re-scheduling will put the given instruction too close
 /// to the defs of its register dependencies.
-bool TwoAddressInstructionPass::isDefTooClose(Register Reg, unsigned Dist,
+bool TwoAddressInstructionImpl::isDefTooClose(Register Reg, unsigned Dist,
                                               MachineInstr *MI) {
   for (MachineInstr &DefMI : MRI->def_instructions(Reg)) {
     if (DefMI.getParent() != MBB || DefMI.isCopy() || DefMI.isCopyLike())
@@ -1019,7 +1092,7 @@ bool TwoAddressInstructionPass::isDefTooClose(Register Reg, unsigned Dist,
 /// If there is one more local instruction that reads 'Reg' and it kills 'Reg,
 /// consider moving the kill instruction above the current two-address
 /// instruction in order to eliminate the need for the copy.
-bool TwoAddressInstructionPass::rescheduleKillAboveMI(
+bool TwoAddressInstructionImpl::rescheduleKillAboveMI(
     MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi,
     Register Reg) {
   // Bail immediately if we don't have LV or LIS available. We use them to find
@@ -1171,7 +1244,7 @@ bool TwoAddressInstructionPass::rescheduleKillAboveMI(
 /// to commute operands in the instruction.
 ///
 /// Returns true if the transformation happened. Otherwise, returns false.
-bool TwoAddressInstructionPass::tryInstructionCommute(MachineInstr *MI,
+bool TwoAddressInstructionImpl::tryInstructionCommute(MachineInstr *MI,
                                                       unsigned DstOpIdx,
                                                       unsigned BaseOpIdx,
                                                       bool BaseOpKilled,
@@ -1236,11 +1309,9 @@ bool TwoAddressInstructionPass::tryInstructionCommute(MachineInstr *MI,
 /// (either because they were untied, or because mi was rescheduled, and will
 /// be visited again later). If the shouldOnlyCommute flag is true, only
 /// instruction commutation is attempted.
-bool TwoAddressInstructionPass::
-tryInstructionTransform(MachineBasicBlock::iterator &mi,
-                        MachineBasicBlock::iterator &nmi,
-                        unsigned SrcIdx, unsigned DstIdx,
-                        unsigned &Dist, bool shouldOnlyCommute) {
+bool TwoAddressInstructionImpl::tryInstructionTransform(
+    MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi,
+    unsigned SrcIdx, unsigned DstIdx, unsigned &Dist, bool shouldOnlyCommute) {
   if (OptLevel == CodeGenOptLevel::None)
     return false;
 
@@ -1440,8 +1511,8 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi,
 // Collect tied operands of MI that need to be handled.
 // Rewrite trivial cases immediately.
 // Return true if any tied operands where found, including the trivial ones.
-bool TwoAddressInstructionPass::
-collectTiedOperands(MachineInstr *MI, TiedOperandMap &TiedOperands) {
+bool TwoAddressInstructionImpl::collectTiedOperands(
+    MachineInstr *MI, TiedOperandMap &TiedOperands) {
   bool AnyOps = false;
   unsigned NumOps = MI->getNumOperands();
 
@@ -1479,10 +1550,9 @@ collectTiedOperands(MachineInstr *MI, TiedOperandMap &TiedOperands) {
 
 // Process a list of tied MI operands that all use the same source register.
 // The tied pairs are of the form (SrcIdx, DstIdx).
-void
-TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
-                                            TiedPairList &TiedPairs,
-                                            unsigned &Dist) {
+void TwoAddressInstructionImpl::processTiedPairs(MachineInstr *MI,
+                                                 TiedPairList &TiedPairs,
+                                                 unsigned &Dist) {
   bool IsEarlyClobber = llvm::any_of(TiedPairs, [MI](auto const &TP) {
     return MI->getOperand(TP.second).isEarlyClobber();
   });
@@ -1668,7 +1738,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
 // and replaces all uses of RegA with RegB.
 // No extra COPY instruction is necessary because tied use is killed at
 // STATEPOINT.
-bool TwoAddressInstructionPass::processStatepoint(
+bool TwoAddressInstructionImpl::processStatepoint(
     MachineInstr *MI, TiedOperandMap &TiedOperands) {
 
   bool NeedCopy = false;
@@ -1755,27 +1825,7 @@ bool TwoAddressInstructionPass::processStatepoint(
 }
 
 /// Reduce two-address instructions to two operands.
-bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &Func) {
-  MF = &Func;
-  const TargetMachine &TM = MF->getTarget();
-  MRI = &MF->getRegInfo();
-  TII = MF->getSubtarget().getInstrInfo();
-  TRI = MF->getSubtarget().getRegisterInfo();
-  InstrItins = MF->getSubtarget().getInstrItineraryData();
-  auto *LVWrapper = getAnalysisIfAvailable<LiveVariablesWrapperPass>();
-  LV = LVWrapper ? &LVWrapper->getLV() : nullptr;
-  auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
-  LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
-  if (auto *AAPass = getAnalysisIfAvailable<AAResultsWrapperPass>())
-    AA = &AAPass->getAAResults();
-  else
-    AA = nullptr;
-  OptLevel = TM.getOptLevel();
-  // Disable optimizations if requested. We cannot skip the whole pass as some
-  // fixups are necessary for correctness.
-  if (skipFunction(Func.getFunction()))
-    OptLevel = CodeGenOptLevel::None;
-
+bool TwoAddressInstructionImpl::run() {
   bool MadeChange = false;
 
   LLVM_DEBUG(dbgs() << "********** REWRITING TWO-ADDR INSTRS **********\n");
@@ -1930,8 +1980,8 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &Func) {
 ///
 ///   undef %dst:ssub0 = COPY %v1
 ///   %dst:ssub1 = COPY %v2
-void TwoAddressInstructionPass::
-eliminateRegSequence(MachineBasicBlock::iterator &MBBI) {
+void TwoAddressInstructionImpl::eliminateRegSequence(
+    MachineBasicBlock::iterator &MBBI) {
   MachineInstr &MI = *MBBI;
   Register DstReg = MI.getOperand(0).getReg();
 
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 8d1be7d1acabf..929690c2c74d6 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -114,6 +114,7 @@
 #include "llvm/CodeGen/SlotIndexes.h"
 #include "llvm/CodeGen/StackProtector.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/CodeGen/TwoAddressInstructionPass.h"
 #include "llvm/CodeGen/TypePromotion.h"
 #include "llvm/CodeGen/WasmEHPrepare.h"
 #include "llvm/CodeGen/WinEHPrepare.h"
diff --git a/llvm/test/CodeGen/AArch64/statepoint-twoaddr.mir b/llvm/test/CodeGen/AArch64/statepoint-twoaddr.mir
index 55b3e84f290f8..c483d669a2758 100644
--- a/llvm/test/CodeGen/AArch64/statepoint-twoaddr.mir
+++ b/llvm/test/CodeGen/AArch64/statepoint-twoaddr.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple=aarch64-unknown-linux -run-pass=twoaddressinstruction -verify-machineinstrs %s -o - | FileCheck %s
+# RUN: llc -mtriple=aarch64-unknown-linux --passes=two-address-instruction %s -o - | FileCheck %s
 # REQUIRES: aarch64-registered-target
 
 # Verify that the register class is correctly constrained after the twoaddress replacement
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/twoaddr-extract-dyn-v7f64.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/twoaddr-extract-dyn-v7f64.mir
index 6c13756ab1c69..e84c51b73ad1e 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/twoaddr-extract-dyn-v7f64.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/twoaddr-extract-dyn-v7f64.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
 # RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx900 -early-live-intervals -run-pass=liveintervals -run-pass=twoaddressinstruction -verify-machineinstrs -o - %s | FileCheck %s
+# RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx900 -passes='require<live-intervals>,two-address-instruction' -o - %s | FileCheck %s
 
 ---
 name:            dyn_extract_v7f64_v_v
diff --git a/llvm/test/CodeGen/AMDGPU/early-lis-two-address-partial-def.mir b/llvm/test/CodeGen/AMDGPU/early-lis-two-address-partial-def.mir
index 7a151c4530a03..bf111d19f2147 100644
--- a/llvm/test/CodeGen/AMDGPU/early-lis-two-address-partial-def.mir
+++ b/llvm/test/CodeGen/AMDGPU/early-lis-two-address-partial-def.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
 # RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -run-pass=liveintervals -run-pass=twoaddressinstruction -verify-machineinstrs -o - %s | FileCheck --check-prefix=GFX90A %s
+# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a --passes='require<live-intervals>,two-address-instruction' -o - %s | FileCheck --check-prefix=GFX90A %s
 
 ---
 name:            aligned_partial_vgpr_64
diff --git a/llvm/test/CodeGen/AMDGPU/gfx10-twoaddr-fma.mir b/llvm/test/CodeGen/AMDGPU/gfx10-twoaddr-fma.mir
index 0ffecef1af26f..6f142d866149a 100644
--- a/llvm/test/CodeGen/AMDGPU/gfx10-twoaddr-fma.mir
+++ b/llvm/test/CodeGen/AMDGPU/gfx10-twoaddr-fma.mir
@@ -1,5 +1,7 @@
 # RUN: llc -mtriple=amdgcn -mcpu=gfx1010 %s -run-pass twoaddressinstruction -verify-machineinstrs -o - | FileCheck --check-prefixes=GFX10 %s
 # RUN: llc -mtriple=amdgcn -mcpu=gfx1010 %s -run-pass twoaddressinstruction -verify-machineinstrs -o - -early-live-intervals | FileCheck --check-prefixes=GFX10 %s
+# RUN: llc -mtriple=amdgcn -mcpu=gfx1010 %s --passes=two-address-instruction -o - | FileCheck --check-prefixes=GFX10 %s
+# RUN: llc -mtriple=amdgcn -mcpu=gfx1010 %s --passes=two-address-instruction -o - -early-live-intervals | FileCheck --check-prefixes=GFX10 %s
 
 # GFX10-LABEL: name: test_fmamk_reg_imm_f16
 # GFX10: %2:vgpr_32 = IMPLICIT_DEF
diff --git a/llvm/test/CodeGen/AMDGPU/gfx11-twoaddr-fma.mir b/llvm/test/CodeGen/AMDGPU/gfx11-twoaddr-fma.mir
index a197715d520b9..91ade8806e4d1 100644
--- a/llvm/test/CodeGen/AMDGPU/gfx11-twoaddr-fma.mir
+++ b/llvm/test/CodeGen/AMDGPU/gfx11-twoaddr-fma.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple=amdgcn -mcpu=gfx1100 %s -run-pass twoaddressinstruction -verify-machineinstrs -o - | FileCheck --check-prefixes=GFX11 %s
+# RUN: llc -mtriple=amdgcn -mcpu=gfx1100 %s --passes=two-address-instruction -verify-machineinstrs -o - | FileCheck --check-prefixes=GFX11 %s
 
 ---
 name:            test_fmamk_reg_imm_f16
diff --git a/llvm/test/CodeGen/AMDGPU/twoaddr-fma-f64.mir b/llvm/test/CodeGen/AMDGPU/twoaddr-fma-f64.mir
index cfd1bd4d13ce7..0831f532d68d8 100644
--- a/llvm/test/CodeGen/AMDGPU/twoaddr-fma-f64.mir
+++ b/llvm/test/CodeGen/AMDGPU/twoaddr-fma-f64.mir
@@ -1,5 +1,7 @@
 # RUN: llc -mtriple=amdgcn -mcpu=gfx90a %s -run-pass twoaddressinstruction -verify-machineinstrs -o - | FileCheck -check-prefix=GCN %s
 # RUN: llc -mtriple=amdgcn -mcpu=gfx90a %s -run-pass twoaddressinstruction -verify-machineinstrs -o - -early-live-intervals | FileCheck -check-prefix=GCN %s
+# RUN: llc -mtriple=amdgcn -mcpu=gfx90a %s --passes=two-address-instruction -o - | FileCheck -check-prefix=GCN %s
+# RUN: llc -mtriple=amdgcn -mcpu=gfx90a %s --passes=two-address-instruction -o - -early-live-intervals | FileCheck -check-prefix=GCN %s
 
 # GCN-LABEL: name: test_fmamk_reg_imm_f64
 # GCN: V_FMA_F64_e64 0, killed %0, 0, %2, 0, killed %1, 0, 0, implicit $mode, implicit $exec
diff --git a/llvm/test/CodeGen/AMDGPU/twoaddr-fma.mir b/llvm/test/CodeGen/AMDGPU/twoaddr-fma.mir
index 379133f9417c8..4802d05ce9d05 100644
--- a/llvm/test/CodeGen/AMDGPU/twoaddr-fma.mir
+++ b/llvm/test/CodeGen/AMDGPU/twoaddr-fma.mir
@@ -2,6 +2,8 @@
 # RUN: llc -mtriple=amdgcn -mcpu=gfx1010 %s -run-pass twoaddressinstruction -verify-machineinstrs -o - -early-live-intervals | FileCheck --check-prefixes=GCN %s
 # RUN: llc -mtriple=amdgcn -mcpu=gfx1100 %s -run-pass twoaddressinstruction -verify-machineinstrs -o - | FileCheck --check-prefixes=GCN %s
 # RUN: llc -mtriple=amdgcn -mcpu=gfx1100 %s -run-pass twoaddressinstruction -verify-machineinstrs -o - -early-live-intervals | FileCheck --check-prefixes=GCN %s
+# RUN: llc -mtriple=amdgcn -mcpu=gfx1010 %s --passes=two-address-instruction -o - | FileCheck --check-prefixes=GCN %s
+# RUN: llc -mtriple=amdgcn -mcpu=gfx1100 %s --passes=two-address-instruction -o - | FileCheck --check-prefixes=GCN %s
 
 # GCN-LABEL: name: test_fmamk_reg_imm_f32
 # GCN: %2:vgpr_32 = IMPLICIT_DEF
diff --git a/llvm/test/CodeGen/AMDGPU/twoaddr-mad.mir b/llvm/test/CodeGen/AMDGPU/twoaddr-mad.mir
index f5d147d83404b..6edce6ccaa9b0 100644
--- a/llvm/test/CodeGen/AMDGPU/twoaddr-mad.mir
+++ b/llvm/test/CodeGen/AMDGPU/twoaddr-mad.mir
@@ -1,5 +1,6 @@
 # RUN: llc -mtriple=amdgcn -mcpu=gfx900 %s -run-pass twoaddressinstruction -verify-machineinstrs -o - | FileCheck -check-prefix=GCN %s
 # RUN: llc -mtriple=amdgcn -mcpu=gfx900 %s -run-pass twoaddressinstruction -verify-machineinstrs -o - -early-live-intervals | FileCheck -check-prefix=GCN %s
+# RUN: llc -mtriple=amdgcn -mcpu=gfx900 %s --passes=two-address-instruction -o - | FileCheck -check-prefix=GCN %s
 
 # GCN-LABEL: name: test_madmk_reg_imm_f32
 # GCN: V_MADMK_F32 killed %0.sub0, 1078523331, killed %1, implicit $mode, implicit $exec
diff --git a/llvm/test/CodeGen/AMDGPU/twoaddr-wmma.mir b/llvm/test/CodeGen/AMDGPU/twoaddr-wmma.mir
index 8aaba0060723b..116673e885905 100644
--- a/llvm/test/CodeGen/AMDGPU/twoaddr-wmma.mir
+++ b/llvm/test/CodeGen/AMDGPU/twoaddr-wmma.mir
@@ -1,5 +1,6 @@
 # RUN: llc -mtriple=amdgcn -mcpu=gfx1100 %s -run-pass twoaddressinstruction -verify-machineinstrs -o - | FileCheck -check-prefix=GCN %s
 # RUN: llc -mtriple=amdgcn -mcpu=gfx1100 %s -run-pass twoaddressinstruction -verify-machineinstrs -o - -early-live-intervals | FileCheck -check-prefix=GCN %s
+# RUN: llc -mtriple=amdgcn -mcpu=gfx1100 %s --passes=two-address-instruction -o - | FileCheck -check-prefix=GCN %s
 
 # GCN-LABEL: name: test_v_wmma_f32_16x16x16_f16_twoaddr_w32
 # GCN: early-clobber %2:vreg_256 = V_WMMA_F32_16X16X16_F16_threeaddr_w32 8, killed %1, 8, killed %1, 8, %0, 0, 0, implicit $exec
diff --git a/llvm/test/CodeGen/Hexagon/two-addr-tied-subregs.mir b/llvm/test/CodeGen/Hexagon/two-addr-tied-subregs.mir
index 87e117c461b64..c533a5a167ab2 100644
--- a/llvm/test/CodeGen/Hexagon/two-addr-tied-subregs.mir
+++ b/llvm/test/CodeGen/Hexagon/two-addr-tied-subregs.mir
@@ -1,4 +1,5 @@
 # RUN: llc -march hexagon -run-pass livevars -run-pass twoaddressinstruction  -verify-machineinstrs -o - %s | FileCheck %s
+# RUN: llc -march hexagon --passes='require<live-vars>,two-address-instruction' -o - %s | FileCheck %s
 
 
 ###############################################################################
diff --git a/llvm/test/CodeGen/X86/distancemap.mir b/llvm/test/CodeGen/X86/distancemap.mir
index b389a0c6cae70..0a2f422302bd3 100644
--- a/llvm/test/CodeGen/X86/distancemap.mir
+++ b/llvm/test/CodeGen/X86/distancemap.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc %s -o - -mtriple=x86_64-unknown-linux -run-pass=twoaddressinstruction -verify-machineinstrs | FileCheck %s
+# RUN: llc %s -o - -mtriple=x86_64-unknown-linux --passes=two-address-instruction | FileCheck %s
 
 # In TwoAddressInstructionPass, new instructions should be added to DistanceMap.
 # In this case, function convertInstTo3Addr is called on the first ADD
diff --git a/llvm/test/CodeGen/X86/statepoint-vreg-twoaddr.mir b/llvm/test/CodeGen/X86/statepoint-vreg-twoaddr.mir
index 9e29739812d32..665ca956bc32e 100644
--- a/llvm/test/CodeGen/X86/statepoint-vreg-twoaddr.mir
+++ b/llvm/test/CodeGen/X86/statepoint-vreg-twoaddr.mir
@@ -1,4 +1,5 @@
 # RUN: llc -x mir -run-pass=twoaddressinstruction < %s | FileCheck %s
+# RUN: llc -x mir --passes=two-address-instruction < %s | FileCheck %s
 
 # This test checks that TwoAddressInstruction pass does not create redundate COPY
 # instruction for STATEPOINT tied operands.
diff --git a/llvm/test/CodeGen/X86/twoaddr-mul2.mir b/llvm/test/CodeGen/X86/twoaddr-mul2.mir
index 5aa9613e162eb..e21005fa92397 100644
--- a/llvm/test/CodeGen/X86/twoaddr-mul2.mir
+++ b/llvm/test/CodeGen/X86/twoaddr-mul2.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple=x86_64-unknown -mcpu=haswell -run-pass=twoaddressinstruction -verify-machineinstrs %s -o - | FileCheck %s
+# RUN: llc -mtriple=x86_64-unknown -mcpu=haswell --passes=two-address-instruction -verify-machineinstrs %s -o - | FileCheck %s
 
 # Check that we don't have any uses of [[COPY]] after it is killed.
 ---



More information about the llvm-commits mailing list