diff --git a/llvm/include/llvm/CodeGen/RegisterCoalescerPass.h b/llvm/include/llvm/CodeGen/RegisterCoalescerPass.h new file mode 100644 index 0000000000000..91f66dbf33b5f --- /dev/null +++ b/llvm/include/llvm/CodeGen/RegisterCoalescerPass.h @@ -0,0 +1,28 @@ +//===- llvm/CodeGen/RegisterCoalescerPass.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_REGISTER_COALESCERPASS_H +#define LLVM_CODEGEN_REGISTER_COALESCERPASS_H + +#include "llvm/CodeGen/MachinePassManager.h" + +namespace llvm { +class RegisterCoalescerPass : public PassInfoMixin { +public: + PreservedAnalyses run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM); + + MachineFunctionProperties getClearedProperties() const { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::IsSSA); + } +}; + +} // namespace llvm + +#endif // LLVM_CODEGEN_REGISTER_COALESCERPASS_H diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 8111afcc1fb20..46fcd17347f4e 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -266,7 +266,7 @@ void initializeRegionOnlyPrinterPass(PassRegistry &); void initializeRegionOnlyViewerPass(PassRegistry &); void initializeRegionPrinterPass(PassRegistry &); void initializeRegionViewerPass(PassRegistry &); -void initializeRegisterCoalescerPass(PassRegistry &); +void initializeRegisterCoalescerLegacyPass(PassRegistry &); void initializeRemoveLoadsIntoFakeUsesPass(PassRegistry &); void initializeRemoveRedundantDebugValuesPass(PassRegistry &); void initializeRenameIndependentSubregsPass(PassRegistry &); diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h index a84164bed46ce..9681368249a0f 100644 --- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h +++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h @@ -57,6 +57,7 @@ #include "llvm/CodeGen/RegAllocFast.h" #include "llvm/CodeGen/RegUsageInfoCollector.h" #include "llvm/CodeGen/RegUsageInfoPropagate.h" +#include "llvm/CodeGen/RegisterCoalescerPass.h" #include "llvm/CodeGen/RegisterUsageInfo.h" #include "llvm/CodeGen/ReplaceWithVeclib.h" #include "llvm/CodeGen/SafeStack.h" diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def index dfe3514360c3c..1d978f2ea3122 100644 --- a/llvm/include/llvm/Passes/MachinePassRegistry.def +++ b/llvm/include/llvm/Passes/MachinePassRegistry.def @@ -164,6 +164,7 @@ MACHINE_FUNCTION_PASS("print", SlotIndexesPrinterPass(errs())) MACHINE_FUNCTION_PASS("print", VirtRegMapPrinterPass(errs())) MACHINE_FUNCTION_PASS("reg-usage-collector", RegUsageInfoCollectorPass()) MACHINE_FUNCTION_PASS("reg-usage-propagation", RegUsageInfoPropagationPass()) +MACHINE_FUNCTION_PASS("register-coalescer", RegisterCoalescerPass()) MACHINE_FUNCTION_PASS("require-all-machine-function-properties", RequireAllMachineFunctionPropertiesPass()) MACHINE_FUNCTION_PASS("stack-coloring", StackColoringPass()) @@ -265,7 +266,6 @@ DUMMY_MACHINE_FUNCTION_PASS("removeredundantdebugvalues", RemoveRedundantDebugVa DUMMY_MACHINE_FUNCTION_PASS("rename-independent-subregs", RenameIndependentSubregsPass) DUMMY_MACHINE_FUNCTION_PASS("reset-machine-function", ResetMachineFunctionPass) DUMMY_MACHINE_FUNCTION_PASS("shrink-wrap", ShrinkWrapPass) -DUMMY_MACHINE_FUNCTION_PASS("simple-register-coalescing", RegisterCoalescerPass) DUMMY_MACHINE_FUNCTION_PASS("stack-frame-layout", StackFrameLayoutAnalysisPass) DUMMY_MACHINE_FUNCTION_PASS("stack-slot-coloring", StackSlotColoringPass) DUMMY_MACHINE_FUNCTION_PASS("stackmap-liveness", StackMapLivenessPass) diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp index ed871519e33bc..5f0c7ec9c8d01 100644 --- a/llvm/lib/CodeGen/CodeGen.cpp +++ b/llvm/lib/CodeGen/CodeGen.cpp @@ -116,7 +116,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) { initializeRegAllocFastPass(Registry); initializeRegUsageInfoCollectorLegacyPass(Registry); initializeRegUsageInfoPropagationLegacyPass(Registry); - initializeRegisterCoalescerPass(Registry); + initializeRegisterCoalescerLegacyPass(Registry); initializeRemoveLoadsIntoFakeUsesPass(Registry); initializeRemoveRedundantDebugValuesPass(Registry); initializeRenameIndependentSubregsPass(Registry); diff --git a/llvm/lib/CodeGen/RegAllocBasic.cpp b/llvm/lib/CodeGen/RegAllocBasic.cpp index f3f34f890be11..e1f05406297d2 100644 --- a/llvm/lib/CodeGen/RegAllocBasic.cpp +++ b/llvm/lib/CodeGen/RegAllocBasic.cpp @@ -134,7 +134,7 @@ INITIALIZE_PASS_BEGIN(RABasic, "regallocbasic", "Basic Register Allocator", INITIALIZE_PASS_DEPENDENCY(LiveDebugVariablesWrapperLegacy) INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass) INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass) -INITIALIZE_PASS_DEPENDENCY(RegisterCoalescer) +INITIALIZE_PASS_DEPENDENCY(RegisterCoalescerLegacy) INITIALIZE_PASS_DEPENDENCY(MachineScheduler) INITIALIZE_PASS_DEPENDENCY(LiveStacksWrapperLegacy) INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp index 6077cfd514de2..465c4e8feffbb 100644 --- a/llvm/lib/CodeGen/RegAllocGreedy.cpp +++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -154,7 +154,7 @@ INITIALIZE_PASS_BEGIN(RAGreedy, "greedy", INITIALIZE_PASS_DEPENDENCY(LiveDebugVariablesWrapperLegacy) INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass) INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass) -INITIALIZE_PASS_DEPENDENCY(RegisterCoalescer) +INITIALIZE_PASS_DEPENDENCY(RegisterCoalescerLegacy) INITIALIZE_PASS_DEPENDENCY(MachineScheduler) INITIALIZE_PASS_DEPENDENCY(LiveStacksWrapperLegacy) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass) diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp index d2f7684ec83a4..f0b597e21f6fd 100644 --- a/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -24,15 +24,18 @@ #include "llvm/CodeGen/LiveIntervals.h" #include "llvm/CodeGen/LiveRangeEdit.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/MachinePassManager.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/RegisterClassInfo.h" +#include "llvm/CodeGen/RegisterCoalescerPass.h" #include "llvm/CodeGen/SlotIndexes.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetOpcodes.h" @@ -121,13 +124,13 @@ namespace { class JoinVals; -class RegisterCoalescer : public MachineFunctionPass, - private LiveRangeEdit::Delegate { +class RegisterCoalescer : private LiveRangeEdit::Delegate { MachineFunction *MF = nullptr; MachineRegisterInfo *MRI = nullptr; const TargetRegisterInfo *TRI = nullptr; const TargetInstrInfo *TII = nullptr; LiveIntervals *LIS = nullptr; + SlotIndexes *SI = nullptr; const MachineLoopInfo *Loops = nullptr; RegisterClassInfo RegClassInfo; @@ -372,11 +375,24 @@ class RegisterCoalescer : public MachineFunctionPass, void checkMergingChangesDbgValuesImpl(Register Reg, LiveRange &OtherRange, LiveRange &RegRange, JoinVals &Vals2); +public: + // For legacy pass only. + RegisterCoalescer() {} + RegisterCoalescer &operator=(RegisterCoalescer &&Other) = default; + + RegisterCoalescer(LiveIntervals *LIS, SlotIndexes *SI, + const MachineLoopInfo *Loops) + : LIS(LIS), SI(SI), Loops(Loops) {} + + bool run(MachineFunction &MF); +}; + +class RegisterCoalescerLegacy : public MachineFunctionPass { public: static char ID; ///< Class identification, replacement for typeinfo - RegisterCoalescer() : MachineFunctionPass(ID) { - initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry()); + RegisterCoalescerLegacy() : MachineFunctionPass(ID) { + initializeRegisterCoalescerLegacyPass(*PassRegistry::getPassRegistry()); } void getAnalysisUsage(AnalysisUsage &AU) const override; @@ -386,24 +402,22 @@ class RegisterCoalescer : public MachineFunctionPass, MachineFunctionProperties::Property::IsSSA); } - void releaseMemory() override; - /// This is the pass entry point. bool runOnMachineFunction(MachineFunction &) override; }; } // end anonymous namespace -char RegisterCoalescer::ID = 0; +char RegisterCoalescerLegacy::ID = 0; -char &llvm::RegisterCoalescerID = RegisterCoalescer::ID; +char &llvm::RegisterCoalescerID = RegisterCoalescerLegacy::ID; -INITIALIZE_PASS_BEGIN(RegisterCoalescer, "register-coalescer", +INITIALIZE_PASS_BEGIN(RegisterCoalescerLegacy, "register-coalescer", "Register Coalescer", false, false) INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass) INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass) INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass) -INITIALIZE_PASS_END(RegisterCoalescer, "register-coalescer", +INITIALIZE_PASS_END(RegisterCoalescerLegacy, "register-coalescer", "Register Coalescer", false, false) [[nodiscard]] static bool isMoveInstr(const TargetRegisterInfo &tri, @@ -580,8 +594,9 @@ bool CoalescerPair::isCoalescable(const MachineInstr *MI) const { } } -void RegisterCoalescer::getAnalysisUsage(AnalysisUsage &AU) const { +void RegisterCoalescerLegacy::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); + AU.addUsedIfAvailable(); AU.addRequired(); AU.addPreserved(); AU.addPreserved(); @@ -4226,15 +4241,35 @@ void RegisterCoalescer::joinAllIntervals() { lateLiveIntervalUpdate(); } -void RegisterCoalescer::releaseMemory() { - ErasedInstrs.clear(); - WorkList.clear(); - DeadDefs.clear(); - InflateRegs.clear(); - LargeLIVisitCounter.clear(); +PreservedAnalyses +RegisterCoalescerPass::run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM) { + MFPropsModifier _(*this, MF); + auto &LIS = MFAM.getResult(MF); + auto &Loops = MFAM.getResult(MF); + auto *SI = MFAM.getCachedResult(MF); + RegisterCoalescer Impl(&LIS, SI, &Loops); + if (!Impl.run(MF)) + return PreservedAnalyses::all(); + auto PA = getMachineFunctionPassPreservedAnalyses(); + PA.preserveSet(); + PA.preserve(); + PA.preserve(); + PA.preserve(); + PA.preserve(); + return PA; +} + +bool RegisterCoalescerLegacy::runOnMachineFunction(MachineFunction &MF) { + auto *LIS = &getAnalysis().getLIS(); + auto *Loops = &getAnalysis().getLI(); + auto *SIWrapper = getAnalysisIfAvailable(); + SlotIndexes *SI = SIWrapper ? &SIWrapper->getSI() : nullptr; + RegisterCoalescer Impl(LIS, SI, Loops); + return Impl.run(MF); } -bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { +bool RegisterCoalescer::run(MachineFunction &fn) { LLVM_DEBUG(dbgs() << "********** REGISTER COALESCER **********\n" << "********** Function: " << fn.getName() << '\n'); @@ -4257,8 +4292,6 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { const TargetSubtargetInfo &STI = fn.getSubtarget(); TRI = STI.getRegisterInfo(); TII = STI.getInstrInfo(); - LIS = &getAnalysis().getLIS(); - Loops = &getAnalysis().getLI(); if (EnableGlobalCopies == cl::BOU_UNSET) JoinGlobalCopies = STI.enableJoinGlobalCopies(); else @@ -4283,7 +4316,7 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { JoinSplitEdges = EnableJoinSplits; if (VerifyCoalescing) - MF->verify(this, "Before register coalescing", &errs()); + MF->verify(LIS, SI, "Before register coalescing", &errs()); DbgVRegToValues.clear(); buildVRegToDbgValueMap(fn); @@ -4342,7 +4375,8 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { RegToPHIIdx.clear(); LLVM_DEBUG(LIS->dump()); + if (VerifyCoalescing) - MF->verify(this, "After register coalescing", &errs()); + MF->verify(LIS, SI, "After register coalescing", &errs()); return true; } diff --git a/llvm/lib/CodeGen/RegisterCoalescer.h b/llvm/lib/CodeGen/RegisterCoalescer.h index 6926e9b5d188f..ec1940805ea2e 100644 --- a/llvm/lib/CodeGen/RegisterCoalescer.h +++ b/llvm/lib/CodeGen/RegisterCoalescer.h @@ -14,6 +14,7 @@ #ifndef LLVM_LIB_CODEGEN_REGISTERCOALESCER_H #define LLVM_LIB_CODEGEN_REGISTERCOALESCER_H +#include "llvm/CodeGen/MachinePassManager.h" #include "llvm/CodeGen/Register.h" namespace llvm { diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 9b93ebc36ae10..d9096edd3ba07 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -127,6 +127,7 @@ #include "llvm/CodeGen/RegAllocFast.h" #include "llvm/CodeGen/RegUsageInfoCollector.h" #include "llvm/CodeGen/RegUsageInfoPropagate.h" +#include "llvm/CodeGen/RegisterCoalescerPass.h" #include "llvm/CodeGen/RegisterUsageInfo.h" #include "llvm/CodeGen/SafeStack.h" #include "llvm/CodeGen/SelectOptimize.h" diff --git a/llvm/test/CodeGen/AArch64/coalescer-drop-subreg-to-reg-imm-ops.mir b/llvm/test/CodeGen/AArch64/coalescer-drop-subreg-to-reg-imm-ops.mir index f54c612303c0e..b60f4ffdd880b 100644 --- a/llvm/test/CodeGen/AArch64/coalescer-drop-subreg-to-reg-imm-ops.mir +++ b/llvm/test/CodeGen/AArch64/coalescer-drop-subreg-to-reg-imm-ops.mir @@ -1,5 +1,6 @@ # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4 # RUN: llc -mtriple=arm64-apple-macosx -mcpu=apple-m1 -verify-coalescing -run-pass=register-coalescer -o - %s | FileCheck %s +# RUN: llc -mtriple=arm64-apple-macosx -mcpu=apple-m1 -verify-coalescing -passes=register-coalescer -o - %s | FileCheck %s # Hits assert "Trying to add an operand to a machine instr that is # already done!" when rematerializing during greedy. This was because diff --git a/llvm/test/CodeGen/AMDGPU/blender-coalescer-verifier-error-empty-subrange.mir b/llvm/test/CodeGen/AMDGPU/blender-coalescer-verifier-error-empty-subrange.mir index 007c4c094029c..c9b47a4575200 100644 --- a/llvm/test/CodeGen/AMDGPU/blender-coalescer-verifier-error-empty-subrange.mir +++ b/llvm/test/CodeGen/AMDGPU/blender-coalescer-verifier-error-empty-subrange.mir @@ -1,5 +1,6 @@ # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2 # RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1031 -run-pass=register-coalescer -verify-coalescing -o - %s | FileCheck %s +# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1031 -passes=register-coalescer -verify-coalescing -o - %s | FileCheck %s # Testcase variants from # liveout-implicit-def-subreg-redef-blender-verifier-error.mir which diff --git a/llvm/test/CodeGen/X86/coalesce-dead-lanes.mir b/llvm/test/CodeGen/X86/coalesce-dead-lanes.mir index f599ed00a3e5c..e4af5995c3a53 100644 --- a/llvm/test/CodeGen/X86/coalesce-dead-lanes.mir +++ b/llvm/test/CodeGen/X86/coalesce-dead-lanes.mir @@ -1,4 +1,5 @@ # RUN: llc -run-pass register-coalescer -O0 -mtriple x86_64-pc-linux-gnu -o - %s | FileCheck %s +# RUN: llc -passes register-coalescer -O0 -mtriple x86_64-pc-linux-gnu -o - %s | FileCheck %s --- name: foo diff --git a/llvm/test/CodeGen/X86/late-remat-update.mir b/llvm/test/CodeGen/X86/late-remat-update.mir index dd4e99c6df141..32123124a924c 100644 --- a/llvm/test/CodeGen/X86/late-remat-update.mir +++ b/llvm/test/CodeGen/X86/late-remat-update.mir @@ -1,5 +1,5 @@ # REQUIRES: asserts -# RUN: llc -mtriple=x86_64-- -run-pass=register-coalescer -late-remat-update-threshold=1 -stats %s -o /dev/null 2>&1 | FileCheck %s +# RUN: llc -mtriple=x86_64-- -passes=register-coalescer -late-remat-update-threshold=1 -stats %s -o /dev/null 2>&1 | FileCheck %s # Check the test will rematerialize for three copies, but will call shrinkToUses # only once to update live range because of late rematerialization update. # CHECK: 3 regalloc - Number of instructions re-materialized