[llvm] [WebAssembly] Port PreLegalizerCombiner (PR #218098)
Aiden Grossman via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 21 21:49:34 PDT 2026
https://github.com/boomanaiden154 created https://github.com/llvm/llvm-project/pull/218098
Standard NewPM pass porting. We have to stick the RuleConfig option
parsing into the per-function implementation to avoid needing to put the
type definition in WebAssembly.h which probably isn't desirable with the
include file logic and given the parsing should be pretty cheap.
>From c899f6b08854dec27e14b58d667887bcbe7d8858 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Sat, 22 Aug 2026 04:49:22 +0000
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.7
---
.../GISel/WebAssemblyPreLegalizerCombiner.cpp | 86 +++++++++++++------
llvm/lib/Target/WebAssembly/WebAssembly.h | 11 ++-
.../WebAssemblyCodeGenPassBuilder.cpp | 6 +-
.../WebAssembly/WebAssemblyPassRegistry.def | 1 +
.../WebAssembly/WebAssemblyTargetMachine.cpp | 4 +-
5 files changed, 72 insertions(+), 36 deletions(-)
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyPreLegalizerCombiner.cpp b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyPreLegalizerCombiner.cpp
index 40a839792377a..c1261263c92c7 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyPreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyPreLegalizerCombiner.cpp
@@ -22,8 +22,12 @@
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.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/Analysis.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetMachine.h"
#define GET_GICOMBINER_DEPS
@@ -86,11 +90,11 @@ WebAssemblyPreLegalizerCombinerImpl::WebAssemblyPreLegalizerCombinerImpl(
// Pass boilerplate
// ================
-class WebAssemblyPreLegalizerCombiner : public MachineFunctionPass {
+class WebAssemblyPreLegalizerCombinerLegacy : public MachineFunctionPass {
public:
static char ID;
- WebAssemblyPreLegalizerCombiner();
+ WebAssemblyPreLegalizerCombinerLegacy();
StringRef getPassName() const override {
return "WebAssemblyPreLegalizerCombiner";
@@ -99,13 +103,10 @@ class WebAssemblyPreLegalizerCombiner : public MachineFunctionPass {
bool runOnMachineFunction(MachineFunction &MF) override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
-
-private:
- WebAssemblyPreLegalizerCombinerImplRuleConfig RuleConfig;
};
} // end anonymous namespace
-void WebAssemblyPreLegalizerCombiner::getAnalysisUsage(
+void WebAssemblyPreLegalizerCombinerLegacy::getAnalysisUsage(
AnalysisUsage &AU) const {
AU.addRequired<TargetPassConfig>();
AU.setPreservesCFG();
@@ -118,33 +119,30 @@ void WebAssemblyPreLegalizerCombiner::getAnalysisUsage(
MachineFunctionPass::getAnalysisUsage(AU);
}
-WebAssemblyPreLegalizerCombiner::WebAssemblyPreLegalizerCombiner()
- : MachineFunctionPass(ID) {
- if (!RuleConfig.parseCommandLineOption())
- report_fatal_error("Invalid rule identifier");
-}
+WebAssemblyPreLegalizerCombinerLegacy::WebAssemblyPreLegalizerCombinerLegacy()
+ : MachineFunctionPass(ID) {}
-bool WebAssemblyPreLegalizerCombiner::runOnMachineFunction(
- MachineFunction &MF) {
+static bool runCombinerOnMachineFunction(
+ MachineFunction &MF, function_ref<GISelCSEInfo *()> GetCSEInfo,
+ function_ref<bool()> ShouldSkip, function_ref<GISelValueTracking *()> GetVT,
+ function_ref<MachineDominatorTree *()> GetMDT) {
if (MF.getProperties().hasFailedISel())
return false;
- auto &TPC = getAnalysis<TargetPassConfig>();
- // Enable CSE.
- GISelCSEAnalysisWrapper &Wrapper =
- getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
- auto *CSEInfo = &Wrapper.get(TPC.getCSEConfig());
+ WebAssemblyPreLegalizerCombinerImplRuleConfig RuleConfig;
+ if (!RuleConfig.parseCommandLineOption())
+ reportFatalUsageError("Invalid rule identifier");
+
+ GISelCSEInfo *CSEInfo = GetCSEInfo();
const WebAssemblySubtarget &ST = MF.getSubtarget<WebAssemblySubtarget>();
const auto *LI = ST.getLegalizerInfo();
const Function &F = MF.getFunction();
bool EnableOpt =
- MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
- GISelValueTracking *VT =
- &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
- MachineDominatorTree *MDT =
- &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
+ MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !ShouldSkip();
+ GISelValueTracking *VT = GetVT();
+ MachineDominatorTree *MDT = GetMDT();
CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
/*LegalizerInfo*/ nullptr, EnableOpt, F.hasOptSize(),
F.hasMinSize());
@@ -159,17 +157,49 @@ bool WebAssemblyPreLegalizerCombiner::runOnMachineFunction(
return Impl.combineMachineInstrs();
}
-char WebAssemblyPreLegalizerCombiner::ID = 0;
-INITIALIZE_PASS_BEGIN(WebAssemblyPreLegalizerCombiner, DEBUG_TYPE,
+char WebAssemblyPreLegalizerCombinerLegacy::ID = 0;
+INITIALIZE_PASS_BEGIN(WebAssemblyPreLegalizerCombinerLegacy, DEBUG_TYPE,
"Combine WebAssembly machine instrs before legalization",
false, false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
-INITIALIZE_PASS_END(WebAssemblyPreLegalizerCombiner, DEBUG_TYPE,
+INITIALIZE_PASS_END(WebAssemblyPreLegalizerCombinerLegacy, DEBUG_TYPE,
"Combine WebAssembly machine instrs before legalization",
false, false)
-FunctionPass *llvm::createWebAssemblyPreLegalizerCombiner() {
- return new WebAssemblyPreLegalizerCombiner();
+FunctionPass *llvm::createWebAssemblyPreLegalizerCombinerLegacyPass() {
+ return new WebAssemblyPreLegalizerCombinerLegacy();
+}
+
+bool WebAssemblyPreLegalizerCombinerLegacy::runOnMachineFunction(
+ MachineFunction &MF) {
+ return runCombinerOnMachineFunction(
+ MF,
+ [&]() {
+ TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
+ GISelCSEAnalysisWrapper &Wrapper =
+ getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
+ return &Wrapper.get(TPC.getCSEConfig());
+ },
+ [&]() { return skipFunction(MF.getFunction()); },
+ [&]() {
+ return &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
+ },
+ [&]() {
+ return &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
+ });
+}
+
+PreservedAnalyses
+WebAssemblyPreLegalizerCombinerPass::run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM) {
+ bool Changed = runCombinerOnMachineFunction(
+ MF, [&]() { return MFAM.getResult<GISelCSEAnalysis>(MF).get(); },
+ [&]() { return MF.getFunction().hasOptNone(); },
+ [&]() { return &MFAM.getResult<GISelValueTrackingAnalysis>(MF); },
+ [&]() { return &MFAM.getResult<MachineDominatorTreeAnalysis>(MF); });
+ return Changed ? getMachineFunctionPassPreservedAnalyses()
+ .preserveSet<CFGAnalyses>()
+ : PreservedAnalyses::all();
}
diff --git a/llvm/lib/Target/WebAssembly/WebAssembly.h b/llvm/lib/Target/WebAssembly/WebAssembly.h
index fc28aff21aa42..a899da2ecfb73 100644
--- a/llvm/lib/Target/WebAssembly/WebAssembly.h
+++ b/llvm/lib/Target/WebAssembly/WebAssembly.h
@@ -111,8 +111,14 @@ createWebAssemblyInstructionSelector(const WebAssemblyTargetMachine &,
FunctionPass *createWebAssemblyPostLegalizerCombiner();
void initializeWebAssemblyPostLegalizerCombinerPass(PassRegistry &);
-FunctionPass *createWebAssemblyPreLegalizerCombiner();
-void initializeWebAssemblyPreLegalizerCombinerPass(PassRegistry &);
+class WebAssemblyPreLegalizerCombinerPass
+ : public RequiredPassInfoMixin<WebAssemblyPreLegalizerCombinerPass> {
+public:
+ PreservedAnalyses run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createWebAssemblyPreLegalizerCombinerLegacyPass();
// ISel and immediate followup passes.
class WebAssemblyISelDAGToDAGPass : public SelectionDAGISelPass {
@@ -333,6 +339,7 @@ void initializeWebAssemblyMemIntrinsicResultsLegacyPass(PassRegistry &);
void initializeWebAssemblyNullifyDebugValueListsLegacyPass(PassRegistry &);
void initializeWebAssemblyOptimizeLiveIntervalsLegacyPass(PassRegistry &);
void initializeWebAssemblyPeepholeLegacyPass(PassRegistry &);
+void initializeWebAssemblyPreLegalizerCombinerLegacyPass(PassRegistry &);
void initializeWebAssemblyRegColoringLegacyPass(PassRegistry &);
void initializeWebAssemblyRegNumberingLegacyPass(PassRegistry &);
void initializeWebAssemblyRegStackifyLegacyPass(PassRegistry &);
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
index 72fc88ef04db6..106c91c89f9bd 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
@@ -197,10 +197,8 @@ Error WebAssemblyCodeGenPassBuilder::addIRTranslator(PassManagerWrapper &PMW) {
void WebAssemblyCodeGenPassBuilder::addPreLegalizeMachineIR(
PassManagerWrapper &PMW) {
- if (getOptLevel() != CodeGenOptLevel::None) {
- // TODO(boomanaiden154): Add WebAssemblyPreLegalizerCombiner when it has
- // been ported.
- }
+ if (getOptLevel() != CodeGenOptLevel::None)
+ addMachineFunctionPass(WebAssemblyPreLegalizerCombinerPass(), PMW);
}
Error WebAssemblyCodeGenPassBuilder::addLegalizeMachineIR(
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def b/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
index 01915b35a41fc..6bfc64195af72 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
@@ -67,6 +67,7 @@ MACHINE_FUNCTION_PASS("wasm-nullify-dbg-value-lists",
MACHINE_FUNCTION_PASS("wasm-optimize-live-intervals",
WebAssemblyOptimizeLiveIntervalsPass())
MACHINE_FUNCTION_PASS("wasm-peephole", WebAssemblyPeepholePass())
+MACHINE_FUNCTION_PASS("wasm-prelegalizer-combiner", WebAssemblyPreLegalizerCombinerPass())
MACHINE_FUNCTION_PASS("wasm-reg-coloring", WebAssemblyRegColoringPass())
MACHINE_FUNCTION_PASS("wasm-reg-numbering", WebAssemblyRegNumberingPass())
MACHINE_FUNCTION_PASS("wasm-reg-stackify", WebAssemblyRegStackifyPass(getOptLevel()))
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
index be82cdf03f4bd..265ff20244f87 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -91,7 +91,7 @@ LLVMInitializeWebAssemblyTarget() {
// Register backend passes
auto &PR = *PassRegistry::getPassRegistry();
initializeGlobalISel(PR);
- initializeWebAssemblyPreLegalizerCombinerPass(PR);
+ initializeWebAssemblyPreLegalizerCombinerLegacyPass(PR);
initializeWebAssemblyPostLegalizerCombinerPass(PR);
initializeWebAssemblyAddMissingPrototypesLegacyPass(PR);
initializeWebAssemblyLowerEmscriptenEHSjLjLegacyPass(PR);
@@ -522,7 +522,7 @@ bool WebAssemblyPassConfig::addIRTranslator() {
void WebAssemblyPassConfig::addPreLegalizeMachineIR() {
if (getOptLevel() != CodeGenOptLevel::None) {
- addPass(createWebAssemblyPreLegalizerCombiner());
+ addPass(createWebAssemblyPreLegalizerCombinerLegacyPass());
}
}
bool WebAssemblyPassConfig::addLegalizeMachineIR() {
More information about the llvm-commits
mailing list