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 { +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", 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 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(); + PA.preserve(); + PA.preserve(); + PA.preserve(); + PA.preserve(); + PA.preserveSet(); + 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(Func)), + LIS(MFAM.getCachedResult(Func)), + OptLevel(Func.getTarget().getOptLevel()) { + auto &FAM = MFAM.getResult(Func) + .getManager(); + AA = FAM.getCachedResult(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(); + LV = LVWrapper ? &LVWrapper->getLV() : nullptr; + auto *LISWrapper = P->getAnalysisIfAvailable(); + LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr; + if (auto *AAPass = P->getAnalysisIfAvailable()) + 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 &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 &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 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(); - LV = LVWrapper ? &LVWrapper->getLV() : nullptr; - auto *LISWrapper = getAnalysisIfAvailable(); - LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr; - if (auto *AAPass = getAnalysisIfAvailable()) - 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,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,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,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. ---