[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