From 101799100b7326d1192f5bb9b605ea030324b31b Mon Sep 17 00:00:00 2001 From: Gergo Stomfai Date: Thu, 19 Mar 2026 20:21:17 +0000 Subject: [PATCH] [X86][GISEL] Port X86PostLegalizerCombiner to npm (#182787) Port X86PostLegalizerCombiner to npm as part of llvm/llvm-project#178192 Also added cli option for lpm X86PostLegalizerCombiner pass for testing. --- .../X86/GISel/X86PostLegalizerCombiner.cpp | 95 +++++++++++++------ llvm/lib/Target/X86/X86.h | 11 ++- llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp | 5 + llvm/lib/Target/X86/X86PassRegistry.def | 1 + llvm/lib/Target/X86/X86TargetMachine.cpp | 4 +- 5 files changed, 83 insertions(+), 33 deletions(-) diff --git a/llvm/lib/Target/X86/GISel/X86PostLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PostLegalizerCombiner.cpp index 373d46d1b53a..1122da0dc619 100644 --- a/llvm/lib/Target/X86/GISel/X86PostLegalizerCombiner.cpp +++ b/llvm/lib/Target/X86/GISel/X86PostLegalizerCombiner.cpp @@ -51,6 +51,19 @@ using namespace MIPatternMatch; namespace { +CombinerInfo createCombinerInfo(bool OptEnabled, const Function &F) { + CombinerInfo CInfo(/*AllowIllegalOps=*/true, + /*ShouldLegalizeIllegal=*/false, + /*LInfo=*/nullptr, /*OptEnabled=*/OptEnabled, + /*OptSize=*/F.hasOptSize(), /*MinSize=*/F.hasMinSize()); + // Disable fixed-point iteration to reduce compile-time + CInfo.MaxIterations = 1; + CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass; + // Legalizer performs DCE, so a full DCE pass is unnecessary. + CInfo.EnableFullDCE = false; + return CInfo; +} + #define GET_GICOMBINER_TYPES #include "X86GenPostLegalizeGICombiner.inc" #undef GET_GICOMBINER_TYPES @@ -66,8 +79,7 @@ public: MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, GISelValueTracking &VT, GISelCSEInfo *CSEInfo, const X86PostLegalizerCombinerImplRuleConfig &RuleConfig, - const X86Subtarget &STI, MachineDominatorTree *MDT, - const LegalizerInfo *LI); + MachineDominatorTree *MDT); static const char *getName() { return "X86PostLegalizerCombiner"; } @@ -88,10 +100,11 @@ X86PostLegalizerCombinerImpl::X86PostLegalizerCombinerImpl( MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, GISelValueTracking &VT, GISelCSEInfo *CSEInfo, const X86PostLegalizerCombinerImplRuleConfig &RuleConfig, - const X86Subtarget &STI, MachineDominatorTree *MDT, const LegalizerInfo *LI) + MachineDominatorTree *MDT) : Combiner(MF, CInfo, TPC, &VT, CSEInfo), - Helper(Observer, B, /*IsPreLegalize=*/false, &VT, MDT, LI), - RuleConfig(RuleConfig), STI(STI), + Helper(Observer, B, /*IsPreLegalize=*/false, &VT, MDT, + MF.getSubtarget().getLegalizerInfo()), + RuleConfig(RuleConfig), STI(MF.getSubtarget()), #define GET_GICOMBINER_CONSTRUCTOR_INITS #include "X86GenPostLegalizeGICombiner.inc" #undef GET_GICOMBINER_CONSTRUCTOR_INITS @@ -102,13 +115,15 @@ bool X86PostLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const { return tryCombineAllImpl(MI); } -class X86PostLegalizerCombiner : public MachineFunctionPass { +class X86PostLegalizerCombinerLegacy : public MachineFunctionPass { public: static char ID; - X86PostLegalizerCombiner(); + X86PostLegalizerCombinerLegacy(); - StringRef getPassName() const override { return "X86PostLegalizerCombiner"; } + StringRef getPassName() const override { + return "X86PostLegalizerCombinerLegacy"; + } bool runOnMachineFunction(MachineFunction &MF) override; void getAnalysisUsage(AnalysisUsage &AU) const override; @@ -118,7 +133,7 @@ private: }; } // end anonymous namespace -void X86PostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { +void X86PostLegalizerCombinerLegacy::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.setPreservesCFG(); getSelectionDAGFallbackAnalysisUsage(AU); @@ -133,21 +148,19 @@ void X86PostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { MachineFunctionPass::getAnalysisUsage(AU); } -X86PostLegalizerCombiner::X86PostLegalizerCombiner() : MachineFunctionPass(ID) { +X86PostLegalizerCombinerLegacy::X86PostLegalizerCombinerLegacy() + : MachineFunctionPass(ID) { if (!RuleConfig.parseCommandLineOption()) reportFatalInternalError("Invalid rule identifier"); } -bool X86PostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { +bool X86PostLegalizerCombinerLegacy::runOnMachineFunction(MachineFunction &MF) { if (MF.getProperties().hasFailedISel()) return false; assert(MF.getProperties().hasLegalized() && "Expected a legalized function?"); auto *TPC = &getAnalysis(); const Function &F = MF.getFunction(); - const X86Subtarget &ST = MF.getSubtarget(); - const auto *LI = ST.getLegalizerInfo(); - GISelValueTracking *VT = &getAnalysis().get(MF); MachineDominatorTree *MDT = @@ -156,32 +169,56 @@ bool X86PostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { getAnalysis().getCSEWrapper(); auto *CSEInfo = &Wrapper.get(TPC->getCSEConfig()); - CombinerInfo CInfo(/*AllowIllegalOps=*/true, - /*ShouldLegalizeIllegal=*/false, - /*LegalizerInfo=*/nullptr, !skipFunction(F), - F.hasOptSize(), F.hasMinSize()); - // Disable fixed-point iteration to reduce compile-time - CInfo.MaxIterations = 1; - CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass; - // Legalizer performs DCE, so a full DCE pass is unnecessary. - CInfo.EnableFullDCE = false; + CombinerInfo CInfo = createCombinerInfo(!skipFunction(F), F); + X86PostLegalizerCombinerImpl Impl(MF, CInfo, TPC, *VT, CSEInfo, RuleConfig, - ST, MDT, LI); + MDT); return Impl.combineMachineInstrs(); } -char X86PostLegalizerCombiner::ID = 0; -INITIALIZE_PASS_BEGIN(X86PostLegalizerCombiner, DEBUG_TYPE, +char X86PostLegalizerCombinerLegacy::ID = 0; +INITIALIZE_PASS_BEGIN(X86PostLegalizerCombinerLegacy, DEBUG_TYPE, "Combine X86 MachineInstrs after legalization", false, false) INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy) -INITIALIZE_PASS_END(X86PostLegalizerCombiner, DEBUG_TYPE, +INITIALIZE_PASS_END(X86PostLegalizerCombinerLegacy, DEBUG_TYPE, "Combine X86 MachineInstrs after legalization", false, false) namespace llvm { -FunctionPass *createX86PostLegalizerCombiner() { - return new X86PostLegalizerCombiner(); + +PreservedAnalyses +X86PostLegalizerCombinerPass::run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM) { + if (MF.getProperties().hasFailedISel()) + return PreservedAnalyses::all(); + assert(MF.getProperties().hasLegalized() && "Expected a legalized function."); + const Function &F = MF.getFunction(); + + GISelValueTracking VT = MFAM.getResult(MF); + MachineDominatorTree &MDT = MFAM.getResult(MF); + auto &CSEInfo = MFAM.getResult(MF); + + CombinerInfo CInfo = createCombinerInfo(true, F); + + X86PostLegalizerCombinerImplRuleConfig RuleConfig; + if (!RuleConfig.parseCommandLineOption()) + reportFatalInternalError("Invalid rule identifier"); + + X86PostLegalizerCombinerImpl Impl(MF, CInfo, nullptr, VT, CSEInfo.get(), + RuleConfig, &MDT); + if (!Impl.combineMachineInstrs()) + return PreservedAnalyses::all(); + + PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses(); + PA.preserveSet(); + PA.preserve(); + PA.preserve(); + return PA; +} + +FunctionPass *createX86PostLegalizerCombinerLegacy() { + return new X86PostLegalizerCombinerLegacy(); } } // end namespace llvm diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h index 9e67c7142785..5ff33a48b63a 100644 --- a/llvm/lib/Target/X86/X86.h +++ b/llvm/lib/Target/X86/X86.h @@ -391,7 +391,14 @@ InstructionSelector *createX86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &, const X86RegisterBankInfo &); -FunctionPass *createX86PostLegalizerCombiner(); +class X86PostLegalizerCombinerPass + : public PassInfoMixin { +public: + PreservedAnalyses run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM); +}; + +FunctionPass *createX86PostLegalizerCombinerLegacy(); FunctionPass *createX86PreLegalizerCombiner(); class X86LoadValueInjectionLoadHardeningPass @@ -478,7 +485,7 @@ void initializeX86SuppressAPXForRelocationLegacyPass(PassRegistry &); void initializeX86TileConfigLegacyPass(PassRegistry &); void initializeX86WinEHUnwindV2LegacyPass(PassRegistry &); void initializeX86PreLegalizerCombinerPass(PassRegistry &); -void initializeX86PostLegalizerCombinerPass(PassRegistry &); +void initializeX86PostLegalizerCombinerLegacyPass(PassRegistry &); namespace X86AS { enum : unsigned { diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp index 53932675c68b..8ea34c764975 100644 --- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp +++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp @@ -46,6 +46,7 @@ public: void addPreISel(PassManagerWrapper &PMW) const; Error addInstSelector(PassManagerWrapper &PMW) const; void addILPOpts(PassManagerWrapper &PMW) const; + void addPreRegBankSelect(PassManagerWrapper &PMW) const; void addMachineSSAOptimization(PassManagerWrapper &PMW) const; void addPreRegAlloc(PassManagerWrapper &PMW) const; // TODO(boomanaiden154): We need to add addPostFastRegAllocRewrite here once @@ -129,6 +130,10 @@ void X86CodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) const { addMachineFunctionPass(X86CmovConversionPass(), PMW); } +void X86CodeGenPassBuilder::addPreRegBankSelect(PassManagerWrapper &PMW) const { + addMachineFunctionPass(X86PostLegalizerCombinerPass(), PMW); +} + void X86CodeGenPassBuilder::addMachineSSAOptimization( PassManagerWrapper &PMW) const { addMachineFunctionPass(X86DomainReassignmentPass(), PMW); diff --git a/llvm/lib/Target/X86/X86PassRegistry.def b/llvm/lib/Target/X86/X86PassRegistry.def index 14235f27a55f..be85b7cf216c 100644 --- a/llvm/lib/Target/X86/X86PassRegistry.def +++ b/llvm/lib/Target/X86/X86PassRegistry.def @@ -56,6 +56,7 @@ MACHINE_FUNCTION_PASS("x86-lower-tile-copy", X86LowerTileCopyPass()) MACHINE_FUNCTION_PASS("x86-lvi-load", X86LoadValueInjectionLoadHardeningPass()) MACHINE_FUNCTION_PASS("x86-lvi-ret", X86LoadValueInjectionRetHardeningPass()) MACHINE_FUNCTION_PASS("x86-optimize-leas", X86OptimizeLEAsPass()) +MACHINE_FUNCTION_PASS("x86-postlegalizer-combiner-pass", X86PostLegalizerCombinerPass()) MACHINE_FUNCTION_PASS("x86-pre-tile-config", X86PreTileConfigPass()) MACHINE_FUNCTION_PASS("x86-return-thunks", X86ReturnThunksPass()) MACHINE_FUNCTION_PASS("x86-seses", X86SpeculativeExecutionSideEffectSuppressionPass()) diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp index 1e153c4a6105..bb7e4d439630 100644 --- a/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -108,7 +108,7 @@ extern "C" LLVM_C_ABI void LLVMInitializeX86Target() { initializeX86SuppressAPXForRelocationLegacyPass(PR); initializeX86WinEHUnwindV2LegacyPass(PR); initializeX86PreLegalizerCombinerPass(PR); - initializeX86PostLegalizerCombinerPass(PR); + initializeX86PostLegalizerCombinerLegacyPass(PR); } static std::unique_ptr createTLOF(const Triple &TT) { @@ -476,7 +476,7 @@ bool X86PassConfig::addIRTranslator() { void X86PassConfig::addPreRegBankSelect() { bool IsOptNone = getOptLevel() == CodeGenOptLevel::None; if (!IsOptNone) { - addPass(createX86PostLegalizerCombiner()); + addPass(createX86PostLegalizerCombinerLegacy()); } } bool X86PassConfig::addLegalizeMachineIR() {