[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