[NewPM] Adds a port for AArch64O0PreLegalizerCombiner (#189776)

Adds a standard porting for AArch64O0PreLegalizerCombiner.

Note:

- Moves the AArch64GenO0PreLegalizeGICombiner.inc import outside of
anonymous namespace to use it as a member in the NewPM class (which
needs to be declared in AArch64.h)
- Test update needed a requires directive for the libcall-lowering-info
dependency

---------

Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
This commit is contained in:
Anshul Nigham 2026-04-02 10:29:29 -07:00 committed by GitHub
parent 598029333d
commit 2fc712d8d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 102 additions and 23 deletions

View File

@ -21,6 +21,9 @@
#include "llvm/PassRegistry.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Target/TargetMachine.h"
#include <memory>
struct AArch64O0PreLegalizerCombinerImplRuleConfig;
namespace llvm {
@ -71,6 +74,19 @@ InstructionSelector *
createAArch64InstructionSelector(const AArch64TargetMachine &,
const AArch64Subtarget &,
const AArch64RegisterBankInfo &);
class AArch64O0PreLegalizerCombinerPass
: public PassInfoMixin<AArch64O0PreLegalizerCombinerPass> {
std::unique_ptr<AArch64O0PreLegalizerCombinerImplRuleConfig> RuleConfig;
public:
AArch64O0PreLegalizerCombinerPass();
AArch64O0PreLegalizerCombinerPass(AArch64O0PreLegalizerCombinerPass &&);
~AArch64O0PreLegalizerCombinerPass();
PreservedAnalyses run(MachineFunction &MF,
MachineFunctionAnalysisManager &MFAM);
};
FunctionPass *createAArch64O0PreLegalizerCombiner();
FunctionPass *createAArch64PreLegalizerCombiner();
FunctionPass *createAArch64PostLegalizerCombiner(bool IsOptNone);
@ -98,7 +114,7 @@ void initializeAArch64ExpandPseudoLegacyPass(PassRegistry &);
void initializeAArch64LoadStoreOptLegacyPass(PassRegistry &);
void initializeAArch64LowerHomogeneousPrologEpilogPass(PassRegistry &);
void initializeAArch64MIPeepholeOptLegacyPass(PassRegistry &);
void initializeAArch64O0PreLegalizerCombinerPass(PassRegistry &);
void initializeAArch64O0PreLegalizerCombinerLegacyPass(PassRegistry &);
void initializeAArch64PostCoalescerLegacyPass(PassRegistry &);
void initializeAArch64PostLegalizerCombinerPass(PassRegistry &);
void initializeAArch64PostLegalizerLoweringPass(PassRegistry &);

View File

@ -38,4 +38,6 @@ MACHINE_FUNCTION_PASS("aarch64-mi-peephole-opt", AArch64MIPeepholeOptPass())
MACHINE_FUNCTION_PASS("aarch64-post-coalescer", AArch64PostCoalescerPass())
MACHINE_FUNCTION_PASS("aarch64-ptrauth", AArch64PointerAuthPass())
MACHINE_FUNCTION_PASS("aarch64-simd-scalar", AArch64AdvSIMDScalarPass())
MACHINE_FUNCTION_PASS("aarch64-O0-prelegalizer-combiner",
AArch64O0PreLegalizerCombinerPass())
#undef MACHINE_FUNCTION_PASS

View File

@ -257,7 +257,7 @@ LLVMInitializeAArch64Target() {
initializeAArch64LoadStoreOptLegacyPass(PR);
initializeAArch64MIPeepholeOptLegacyPass(PR);
initializeAArch64SIMDInstrOptPass(PR);
initializeAArch64O0PreLegalizerCombinerPass(PR);
initializeAArch64O0PreLegalizerCombinerLegacyPass(PR);
initializeAArch64PreLegalizerCombinerPass(PR);
initializeAArch64PointerAuthLegacyPass(PR);
initializeAArch64PostCoalescerLegacyPass(PR);

View File

@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
#include "AArch64.h"
#include "AArch64GlobalISelUtils.h"
#include "AArch64TargetMachine.h"
#include "llvm/CodeGen/GlobalISel/Combiner.h"
@ -20,11 +21,15 @@
#include "llvm/CodeGen/GlobalISel/GISelValueTracking.h"
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/LibcallLoweringInfo.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/Instructions.h"
#include <memory>
#define GET_GICOMBINER_DEPS
#include "AArch64GenO0PreLegalizeGICombiner.inc"
@ -34,11 +39,13 @@
using namespace llvm;
using namespace MIPatternMatch;
namespace {
#define GET_GICOMBINER_TYPES
#include "AArch64GenO0PreLegalizeGICombiner.inc"
#undef GET_GICOMBINER_TYPES
namespace {
class AArch64O0PreLegalizerCombinerImpl : public Combiner {
protected:
const CombinerHelper Helper;
@ -111,14 +118,34 @@ bool AArch64O0PreLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
return false;
}
bool runCombiner(
MachineFunction &MF, GISelValueTracking *VT,
const LibcallLoweringInfo &Libcalls,
const AArch64O0PreLegalizerCombinerImplRuleConfig &RuleConfig) {
const Function &F = MF.getFunction();
const AArch64Subtarget &ST = MF.getSubtarget<AArch64Subtarget>();
CombinerInfo CInfo(/*AllowIllegalOps=*/true, /*ShouldLegalizeIllegal=*/false,
/*LegalizerInfo=*/nullptr, /*EnableOpt=*/false,
F.hasOptSize(), F.hasMinSize());
// Disable fixed-point iteration in the Combiner. This improves compile-time
// at the cost of possibly missing optimizations. See PR#94291 for details.
CInfo.MaxIterations = 1;
AArch64O0PreLegalizerCombinerImpl Impl(MF, CInfo, *VT,
/*CSEInfo*/ nullptr, RuleConfig, ST,
Libcalls);
return Impl.combineMachineInstrs();
}
// Pass boilerplate
// ================
class AArch64O0PreLegalizerCombiner : public MachineFunctionPass {
class AArch64O0PreLegalizerCombinerLegacy : public MachineFunctionPass {
public:
static char ID;
AArch64O0PreLegalizerCombiner();
AArch64O0PreLegalizerCombinerLegacy();
StringRef getPassName() const override {
return "AArch64O0PreLegalizerCombiner";
@ -133,7 +160,8 @@ private:
};
} // end anonymous namespace
void AArch64O0PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
void AArch64O0PreLegalizerCombinerLegacy::getAnalysisUsage(
AnalysisUsage &AU) const {
AU.setPreservesCFG();
getSelectionDAGFallbackAnalysisUsage(AU);
AU.addRequired<GISelValueTrackingAnalysisLegacy>();
@ -142,13 +170,14 @@ void AArch64O0PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
MachineFunctionPass::getAnalysisUsage(AU);
}
AArch64O0PreLegalizerCombiner::AArch64O0PreLegalizerCombiner()
AArch64O0PreLegalizerCombinerLegacy::AArch64O0PreLegalizerCombinerLegacy()
: MachineFunctionPass(ID) {
if (!RuleConfig.parseCommandLineOption())
report_fatal_error("Invalid rule identifier");
}
bool AArch64O0PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
bool AArch64O0PreLegalizerCombinerLegacy::runOnMachineFunction(
MachineFunction &MF) {
if (MF.getProperties().hasFailedISel())
return false;
@ -161,32 +190,63 @@ bool AArch64O0PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
*F.getParent(), ST);
CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
/*LegalizerInfo*/ nullptr, /*EnableOpt*/ false,
F.hasOptSize(), F.hasMinSize());
// Disable fixed-point iteration in the Combiner. This improves compile-time
// at the cost of possibly missing optimizations. See PR#94291 for details.
CInfo.MaxIterations = 1;
AArch64O0PreLegalizerCombinerImpl Impl(MF, CInfo, *VT,
/*CSEInfo*/ nullptr, RuleConfig, ST,
Libcalls);
return Impl.combineMachineInstrs();
return runCombiner(MF, VT, Libcalls, RuleConfig);
}
char AArch64O0PreLegalizerCombiner::ID = 0;
INITIALIZE_PASS_BEGIN(AArch64O0PreLegalizerCombiner, DEBUG_TYPE,
char AArch64O0PreLegalizerCombinerLegacy::ID = 0;
INITIALIZE_PASS_BEGIN(AArch64O0PreLegalizerCombinerLegacy, DEBUG_TYPE,
"Combine AArch64 machine instrs before legalization",
false, false)
INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LibcallLoweringInfoWrapper)
INITIALIZE_PASS_END(AArch64O0PreLegalizerCombiner, DEBUG_TYPE,
INITIALIZE_PASS_END(AArch64O0PreLegalizerCombinerLegacy, DEBUG_TYPE,
"Combine AArch64 machine instrs before legalization", false,
false)
AArch64O0PreLegalizerCombinerPass::AArch64O0PreLegalizerCombinerPass()
: RuleConfig(
std::make_unique<AArch64O0PreLegalizerCombinerImplRuleConfig>()) {
if (!RuleConfig->parseCommandLineOption())
report_fatal_error("Invalid rule identifier");
}
AArch64O0PreLegalizerCombinerPass::AArch64O0PreLegalizerCombinerPass(
AArch64O0PreLegalizerCombinerPass &&) = default;
AArch64O0PreLegalizerCombinerPass::~AArch64O0PreLegalizerCombinerPass() =
default;
PreservedAnalyses
AArch64O0PreLegalizerCombinerPass::run(MachineFunction &MF,
MachineFunctionAnalysisManager &MFAM) {
if (MF.getProperties().hasFailedISel())
return PreservedAnalyses::all();
GISelValueTracking &VT = MFAM.getResult<GISelValueTrackingAnalysis>(MF);
const AArch64Subtarget &ST = MF.getSubtarget<AArch64Subtarget>();
auto &MAMProxy =
MFAM.getResult<ModuleAnalysisManagerMachineFunctionProxy>(MF);
const LibcallLoweringModuleAnalysisResult *LibcallResult =
MAMProxy.getCachedResult<LibcallLoweringModuleAnalysis>(
*MF.getFunction().getParent());
if (!LibcallResult)
reportFatalUsageError("LibcallLoweringModuleAnalysis result not available");
const LibcallLoweringInfo &Libcalls = LibcallResult->getLibcallLowering(ST);
if (!runCombiner(MF, &VT, Libcalls, *RuleConfig))
return PreservedAnalyses::all();
PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
PA.preserveSet<CFGAnalyses>();
PA.preserve<GISelValueTrackingAnalysis>();
return PA;
}
namespace llvm {
FunctionPass *createAArch64O0PreLegalizerCombiner() {
return new AArch64O0PreLegalizerCombiner();
return new AArch64O0PreLegalizerCombinerLegacy();
}
} // end namespace llvm

View File

@ -1,4 +1,5 @@
# RUN: llc -global-isel=1 -O0 -run-pass=aarch64-O0-prelegalizer-combiner %s -o - -verify-machineinstrs | FileCheck %s --check-prefix=CHECK
# RUN: llc -global-isel=1 -O0 -passes='require<libcall-lowering-info>,function(machine-function(aarch64-O0-prelegalizer-combiner))' %s -o - | FileCheck %s --check-prefix=CHECK
--- |
; ModuleID = 'salvage-debug-info-dead.mir'