diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.h b/llvm/lib/Target/AMDGPU/AMDGPU.h index 95d0ad0f9dc96..198ea3af9bed2 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPU.h +++ b/llvm/lib/Target/AMDGPU/AMDGPU.h @@ -44,7 +44,7 @@ FunctionPass *createSILoadStoreOptimizerLegacyPass(); FunctionPass *createSIWholeQuadModePass(); FunctionPass *createSIFixControlFlowLiveIntervalsPass(); FunctionPass *createSIOptimizeExecMaskingPreRAPass(); -FunctionPass *createSIOptimizeVGPRLiveRangePass(); +FunctionPass *createSIOptimizeVGPRLiveRangeLegacyPass(); FunctionPass *createSIFixSGPRCopiesLegacyPass(); FunctionPass *createLowerWWMCopiesPass(); FunctionPass *createSIMemoryLegalizerPass(); @@ -361,8 +361,8 @@ struct AMDGPUUnifyMetadataPass : PassInfoMixin { void initializeSIOptimizeExecMaskingPreRAPass(PassRegistry&); extern char &SIOptimizeExecMaskingPreRAID; -void initializeSIOptimizeVGPRLiveRangePass(PassRegistry &); -extern char &SIOptimizeVGPRLiveRangeID; +void initializeSIOptimizeVGPRLiveRangeLegacyPass(PassRegistry &); +extern char &SIOptimizeVGPRLiveRangeLegacyID; void initializeAMDGPUAnnotateUniformValuesLegacyPass(PassRegistry &); extern char &AMDGPUAnnotateUniformValuesLegacyPassID; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def b/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def index 174a90f0aa419..182e825a59a41 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def +++ b/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def @@ -101,6 +101,7 @@ MACHINE_FUNCTION_PASS("si-fold-operands", SIFoldOperandsPass()); MACHINE_FUNCTION_PASS("gcn-dpp-combine", GCNDPPCombinePass()) MACHINE_FUNCTION_PASS("si-load-store-opt", SILoadStoreOptimizerPass()) MACHINE_FUNCTION_PASS("si-lower-sgpr-spills", SILowerSGPRSpillsPass()) +MACHINE_FUNCTION_PASS("si-opt-vgpr-liverange", SIOptimizeVGPRLiveRangePass()) MACHINE_FUNCTION_PASS("si-peephole-sdwa", SIPeepholeSDWAPass()) MACHINE_FUNCTION_PASS("si-pre-allocate-wwm-regs", SIPreAllocateWWMRegsPass()) MACHINE_FUNCTION_PASS("si-shrink-instructions", SIShrinkInstructionsPass()) diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp index da18f2b20f142..381019edfd6c2 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -40,6 +40,7 @@ #include "SILowerSGPRSpills.h" #include "SIMachineFunctionInfo.h" #include "SIMachineScheduler.h" +#include "SIOptimizeVGPRLiveRange.h" #include "SIPeepholeSDWA.h" #include "SIPreAllocateWWMRegs.h" #include "SIShrinkInstructions.h" @@ -473,7 +474,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUTarget() { initializeSIPeepholeSDWALegacyPass(*PR); initializeSIShrinkInstructionsLegacyPass(*PR); initializeSIOptimizeExecMaskingPreRAPass(*PR); - initializeSIOptimizeVGPRLiveRangePass(*PR); + initializeSIOptimizeVGPRLiveRangeLegacyPass(*PR); initializeSILoadStoreOptimizerLegacyPass(*PR); initializeAMDGPUCtorDtorLoweringLegacyPass(*PR); initializeAMDGPUAlwaysInlinePass(*PR); @@ -1423,7 +1424,7 @@ void GCNPassConfig::addOptimizedRegAlloc() { // the register in LiveVariables, this would trigger a failure in verifier, // we should fix it and enable the verifier. if (OptVGPRLiveRange) - insertPass(&LiveVariablesID, &SIOptimizeVGPRLiveRangeID); + insertPass(&LiveVariablesID, &SIOptimizeVGPRLiveRangeLegacyID); // This must be run immediately after phi elimination and before // TwoAddressInstructions, otherwise the processing of the tied operand of diff --git a/llvm/lib/Target/AMDGPU/SIOptimizeVGPRLiveRange.cpp b/llvm/lib/Target/AMDGPU/SIOptimizeVGPRLiveRange.cpp index e173d365ca503..e0ba5fa06f37a 100644 --- a/llvm/lib/Target/AMDGPU/SIOptimizeVGPRLiveRange.cpp +++ b/llvm/lib/Target/AMDGPU/SIOptimizeVGPRLiveRange.cpp @@ -71,6 +71,7 @@ // //===----------------------------------------------------------------------===// +#include "SIOptimizeVGPRLiveRange.h" #include "AMDGPU.h" #include "GCNSubtarget.h" #include "MCTargetDesc/AMDGPUMCTargetDesc.h" @@ -86,7 +87,7 @@ using namespace llvm; namespace { -class SIOptimizeVGPRLiveRange : public MachineFunctionPass { +class SIOptimizeVGPRLiveRange { private: const SIRegisterInfo *TRI = nullptr; const SIInstrInfo *TII = nullptr; @@ -96,7 +97,10 @@ class SIOptimizeVGPRLiveRange : public MachineFunctionPass { MachineRegisterInfo *MRI = nullptr; public: - static char ID; + SIOptimizeVGPRLiveRange(LiveVariables *LV, MachineDominatorTree *MDT, + MachineLoopInfo *Loops) + : LV(LV), MDT(MDT), Loops(Loops) {} + bool run(MachineFunction &MF); MachineBasicBlock *getElseTarget(MachineBasicBlock *MBB) const; @@ -136,8 +140,13 @@ class SIOptimizeVGPRLiveRange : public MachineFunctionPass { Register Reg, MachineBasicBlock *LoopHeader, SmallSetVector &LoopBlocks, SmallVectorImpl &Instructions) const; +}; - SIOptimizeVGPRLiveRange() : MachineFunctionPass(ID) {} +class SIOptimizeVGPRLiveRangeLegacy : public MachineFunctionPass { +public: + static char ID; + + SIOptimizeVGPRLiveRangeLegacy() : MachineFunctionPass(ID) {} bool runOnMachineFunction(MachineFunction &MF) override; @@ -611,35 +620,59 @@ void SIOptimizeVGPRLiveRange::optimizeWaterfallLiveRange( } } -char SIOptimizeVGPRLiveRange::ID = 0; +char SIOptimizeVGPRLiveRangeLegacy::ID = 0; -INITIALIZE_PASS_BEGIN(SIOptimizeVGPRLiveRange, DEBUG_TYPE, +INITIALIZE_PASS_BEGIN(SIOptimizeVGPRLiveRangeLegacy, DEBUG_TYPE, "SI Optimize VGPR LiveRange", false, false) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(LiveVariablesWrapperPass) -INITIALIZE_PASS_END(SIOptimizeVGPRLiveRange, DEBUG_TYPE, +INITIALIZE_PASS_END(SIOptimizeVGPRLiveRangeLegacy, DEBUG_TYPE, "SI Optimize VGPR LiveRange", false, false) -char &llvm::SIOptimizeVGPRLiveRangeID = SIOptimizeVGPRLiveRange::ID; +char &llvm::SIOptimizeVGPRLiveRangeLegacyID = SIOptimizeVGPRLiveRangeLegacy::ID; + +FunctionPass *llvm::createSIOptimizeVGPRLiveRangeLegacyPass() { + return new SIOptimizeVGPRLiveRangeLegacy(); +} + +bool SIOptimizeVGPRLiveRangeLegacy::runOnMachineFunction(MachineFunction &MF) { + if (skipFunction(MF.getFunction())) + return false; -FunctionPass *llvm::createSIOptimizeVGPRLiveRangePass() { - return new SIOptimizeVGPRLiveRange(); + LiveVariables *LV = &getAnalysis().getLV(); + MachineDominatorTree *MDT = + &getAnalysis().getDomTree(); + MachineLoopInfo *Loops = &getAnalysis().getLI(); + return SIOptimizeVGPRLiveRange(LV, MDT, Loops).run(MF); } -bool SIOptimizeVGPRLiveRange::runOnMachineFunction(MachineFunction &MF) { +PreservedAnalyses +SIOptimizeVGPRLiveRangePass::run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM) { + MFPropsModifier _(*this, MF); + LiveVariables *LV = &MFAM.getResult(MF); + MachineDominatorTree *MDT = &MFAM.getResult(MF); + MachineLoopInfo *Loops = &MFAM.getResult(MF); + + bool Changed = SIOptimizeVGPRLiveRange(LV, MDT, Loops).run(MF); + if (!Changed) + return PreservedAnalyses::all(); + + auto PA = getMachineFunctionPassPreservedAnalyses(); + PA.preserve(); + PA.preserve(); + PA.preserve(); + PA.preserveSet(); + return PA; +} +bool SIOptimizeVGPRLiveRange::run(MachineFunction &MF) { const GCNSubtarget &ST = MF.getSubtarget(); TII = ST.getInstrInfo(); TRI = &TII->getRegisterInfo(); - MDT = &getAnalysis().getDomTree(); - Loops = &getAnalysis().getLI(); - LV = &getAnalysis().getLV(); MRI = &MF.getRegInfo(); - if (skipFunction(MF.getFunction())) - return false; - bool MadeChange = false; // TODO: we need to think about the order of visiting the blocks to get diff --git a/llvm/lib/Target/AMDGPU/SIOptimizeVGPRLiveRange.h b/llvm/lib/Target/AMDGPU/SIOptimizeVGPRLiveRange.h new file mode 100644 index 0000000000000..1139a9c18581e --- /dev/null +++ b/llvm/lib/Target/AMDGPU/SIOptimizeVGPRLiveRange.h @@ -0,0 +1,33 @@ +//===- SIOptimizeVGPRLiveRange.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_LIB_TARGET_AMDGPU_SIOPTIMIZEVGPRLIVERANGE_H +#define LLVM_LIB_TARGET_AMDGPU_SIOPTIMIZEVGPRLIVERANGE_H + +#include "llvm/CodeGen/MachinePassManager.h" + +namespace llvm { +class SIOptimizeVGPRLiveRangePass + : public PassInfoMixin { +public: + PreservedAnalyses run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM); + + MachineFunctionProperties getRequiredProperties() const { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::IsSSA); + } + + MachineFunctionProperties getClearedProperties() const { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::NoPHIs); + } +}; +} // namespace llvm + +#endif // LLVM_LIB_TARGET_AMDGPU_SIOPTIMIZEVGPRLIVERANGE_H diff --git a/llvm/test/CodeGen/AMDGPU/opt-vgpr-live-range-verifier-error.mir b/llvm/test/CodeGen/AMDGPU/opt-vgpr-live-range-verifier-error.mir index 0ef3b4e54cf07..9295562529438 100644 --- a/llvm/test/CodeGen/AMDGPU/opt-vgpr-live-range-verifier-error.mir +++ b/llvm/test/CodeGen/AMDGPU/opt-vgpr-live-range-verifier-error.mir @@ -1,4 +1,5 @@ # RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -verify-machineinstrs -run-pass=si-opt-vgpr-liverange -o - %s | FileCheck %s +# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -passes=si-opt-vgpr-liverange -o - %s | FileCheck %s # # This is a very rare case which comes from llvm-reduce. The SI_IF/SI_ELSE usage is quite different from normal. # diff --git a/llvm/test/CodeGen/AMDGPU/si-opt-vgpr-liverange-bug-deadlanes.mir b/llvm/test/CodeGen/AMDGPU/si-opt-vgpr-liverange-bug-deadlanes.mir index f234ea24a9fe7..93796b3049b5b 100644 --- a/llvm/test/CodeGen/AMDGPU/si-opt-vgpr-liverange-bug-deadlanes.mir +++ b/llvm/test/CodeGen/AMDGPU/si-opt-vgpr-liverange-bug-deadlanes.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 -mcpu=gfx1100 -verify-machineinstrs -run-pass=si-opt-vgpr-liverange -o - %s | FileCheck -check-prefixes=CHECK %s +# RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -passes=si-opt-vgpr-liverange -o - %s | FileCheck -check-prefixes=CHECK %s # Tests a case that used to assert in SIOptimizeVGPRLiveRange when trying to optimize %3 which still appears # (though in an undef operand) in the REG_SEQUENCE of the "endif block". This undef pattern was caused by diff --git a/llvm/test/CodeGen/AMDGPU/si-optimize-vgpr-live-range-dbg-instr.mir b/llvm/test/CodeGen/AMDGPU/si-optimize-vgpr-live-range-dbg-instr.mir index 3bdcc14936fb9..7c7b930b6c318 100644 --- a/llvm/test/CodeGen/AMDGPU/si-optimize-vgpr-live-range-dbg-instr.mir +++ b/llvm/test/CodeGen/AMDGPU/si-optimize-vgpr-live-range-dbg-instr.mir @@ -1,4 +1,5 @@ # RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 -run-pass=si-opt-vgpr-liverange %s -o - | FileCheck -check-prefix=GCN %s +# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 -passes=si-opt-vgpr-liverange %s -o - | FileCheck -check-prefix=GCN %s # SIOptimizeVGPRLiveRange shouldn't try to modify use of %5 in DBG_VALUE_LIST