[llvm-branch-commits] [llvm] [WebAssembly] Port WebAssemblyCFGStackifyPass (PR #210255)

Aiden Grossman via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jul 22 20:51:29 PDT 2026


https://github.com/boomanaiden154 updated https://github.com/llvm/llvm-project/pull/210255

>From 804b2f4e7650ab6a5d885eb38514d7e819e0bc77 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Fri, 17 Jul 2026 06:29:12 +0000
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?=
 =?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.7

[skip ci]
---
 llvm/lib/Target/WebAssembly/WebAssembly.h     |  90 ++++++++++++---
 .../Target/WebAssembly/WebAssemblyCFGSort.cpp |  46 ++++++--
 .../WebAssembly/WebAssemblyCFGStackify.cpp    |   8 +-
 .../WebAssemblyCodeGenPassBuilder.cpp         |  18 +--
 .../WebAssembly/WebAssemblyExceptionInfo.cpp  |  66 +++++++++--
 .../WebAssembly/WebAssemblyExceptionInfo.h    |  51 +++++++--
 .../WebAssembly/WebAssemblyLateEHPrepare.cpp  |  67 +++++++----
 .../WebAssemblyMemIntrinsicResults.cpp        | 108 +++++++++++++-----
 .../WebAssemblyOptimizeLiveIntervals.cpp      |  39 +++++--
 .../WebAssembly/WebAssemblyPassRegistry.def   |  14 +++
 .../WebAssembly/WebAssemblyRegColoring.cpp    |  48 ++++++--
 .../WebAssembly/WebAssemblyRegStackify.cpp    |  57 +++++++--
 .../WebAssemblyReplacePhysRegs.cpp            |  36 ++++--
 .../WebAssembly/WebAssemblyTargetMachine.cpp  |  30 ++---
 14 files changed, 510 insertions(+), 168 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssembly.h b/llvm/lib/Target/WebAssembly/WebAssembly.h
index cf90353f963b9..57a1cc0282690 100644
--- a/llvm/lib/Target/WebAssembly/WebAssembly.h
+++ b/llvm/lib/Target/WebAssembly/WebAssembly.h
@@ -152,7 +152,14 @@ class WebAssemblyCleanCodeAfterTrapPass
 FunctionPass *createWebAssemblyCleanCodeAfterTrapLegacyPass();
 
 // Late passes.
-FunctionPass *createWebAssemblyReplacePhysRegs();
+class WebAssemblyReplacePhysRegsPass
+    : public RequiredPassInfoMixin<WebAssemblyReplacePhysRegsPass> {
+public:
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createWebAssemblyReplacePhysRegsLegacyPass();
 
 class WebAssemblyNullifyDebugValueListsPass
     : public RequiredPassInfoMixin<WebAssemblyNullifyDebugValueListsPass> {
@@ -162,10 +169,47 @@ class WebAssemblyNullifyDebugValueListsPass
 };
 
 FunctionPass *createWebAssemblyNullifyDebugValueListsLegacyPass();
-FunctionPass *createWebAssemblyOptimizeLiveIntervals();
-FunctionPass *createWebAssemblyMemIntrinsicResults();
-FunctionPass *createWebAssemblyRegStackify(CodeGenOptLevel OptLevel);
-FunctionPass *createWebAssemblyRegColoring();
+
+class WebAssemblyOptimizeLiveIntervalsPass
+    : public RequiredPassInfoMixin<WebAssemblyOptimizeLiveIntervalsPass> {
+public:
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createWebAssemblyOptimizeLiveIntervalsLegacyPass();
+
+class WebAssemblyMemIntrinsicResultsPass
+    : public RequiredPassInfoMixin<WebAssemblyMemIntrinsicResultsPass> {
+public:
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createWebAssemblyMemIntrinsicResultsLegacyPass();
+
+class WebAssemblyRegStackifyPass
+    : public RequiredPassInfoMixin<WebAssemblyRegStackifyPass> {
+private:
+  bool Optimize = false;
+
+public:
+  WebAssemblyRegStackifyPass(CodeGenOptLevel OptLevel)
+      : Optimize(OptLevel != CodeGenOptLevel::None) {}
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createWebAssemblyRegStackifyLegacyPass(CodeGenOptLevel OptLevel);
+
+class WebAssemblyRegColoringPass
+    : public RequiredPassInfoMixin<WebAssemblyRegColoringPass> {
+public:
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createWebAssemblyRegColoringLegacyPass();
 
 class WebAssemblyFixBrTableDefaultsPass
     : public RequiredPassInfoMixin<WebAssemblyFixBrTableDefaultsPass> {
@@ -184,8 +228,24 @@ class WebAssemblyFixIrreducibleControlFlowPass
 };
 
 FunctionPass *createWebAssemblyFixIrreducibleControlFlowLegacyPass();
-FunctionPass *createWebAssemblyLateEHPrepare();
-FunctionPass *createWebAssemblyCFGSort();
+
+class WebAssemblyLateEHPreparePass
+    : public RequiredPassInfoMixin<WebAssemblyLateEHPreparePass> {
+public:
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createWebAssemblyLateEHPrepareLegacyPass();
+
+class WebAssemblyCFGSortPass
+    : public RequiredPassInfoMixin<WebAssemblyCFGSortPass> {
+public:
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createWebAssemblyCFGSortLegacyPass();
 FunctionPass *createWebAssemblyCFGStackify();
 FunctionPass *createWebAssemblyExplicitLocals();
 FunctionPass *createWebAssemblyLowerBrUnless();
@@ -202,27 +262,27 @@ void initializeWebAssemblyAddMissingPrototypesLegacyPass(PassRegistry &);
 void initializeWebAssemblyArgumentMoveLegacyPass(PassRegistry &);
 void initializeWebAssemblyAsmPrinterPass(PassRegistry &);
 void initializeWebAssemblyCleanCodeAfterTrapLegacyPass(PassRegistry &);
-void initializeWebAssemblyCFGSortPass(PassRegistry &);
+void initializeWebAssemblyCFGSortLegacyPass(PassRegistry &);
 void initializeWebAssemblyCFGStackifyPass(PassRegistry &);
 void initializeWebAssemblyDAGToDAGISelLegacyPass(PassRegistry &);
 void initializeWebAssemblyDebugFixupPass(PassRegistry &);
-void initializeWebAssemblyExceptionInfoPass(PassRegistry &);
+void initializeWebAssemblyExceptionInfoWrapperPassPass(PassRegistry &);
 void initializeWebAssemblyExplicitLocalsPass(PassRegistry &);
 void initializeWebAssemblyFixBrTableDefaultsLegacyPass(PassRegistry &);
 void initializeWebAssemblyFixFunctionBitcastsLegacyPass(PassRegistry &);
 void initializeWebAssemblyFixIrreducibleControlFlowLegacyPass(PassRegistry &);
-void initializeWebAssemblyLateEHPreparePass(PassRegistry &);
+void initializeWebAssemblyLateEHPrepareLegacyPass(PassRegistry &);
 void initializeWebAssemblyLowerBrUnlessPass(PassRegistry &);
 void initializeWebAssemblyLowerEmscriptenEHSjLjLegacyPass(PassRegistry &);
 void initializeWebAssemblyMCLowerPrePassPass(PassRegistry &);
-void initializeWebAssemblyMemIntrinsicResultsPass(PassRegistry &);
+void initializeWebAssemblyMemIntrinsicResultsLegacyPass(PassRegistry &);
 void initializeWebAssemblyNullifyDebugValueListsLegacyPass(PassRegistry &);
-void initializeWebAssemblyOptimizeLiveIntervalsPass(PassRegistry &);
+void initializeWebAssemblyOptimizeLiveIntervalsLegacyPass(PassRegistry &);
 void initializeWebAssemblyPeepholePass(PassRegistry &);
-void initializeWebAssemblyRegColoringPass(PassRegistry &);
+void initializeWebAssemblyRegColoringLegacyPass(PassRegistry &);
 void initializeWebAssemblyRegNumberingPass(PassRegistry &);
-void initializeWebAssemblyRegStackifyPass(PassRegistry &);
-void initializeWebAssemblyReplacePhysRegsPass(PassRegistry &);
+void initializeWebAssemblyRegStackifyLegacyPass(PassRegistry &);
+void initializeWebAssemblyReplacePhysRegsLegacyPass(PassRegistry &);
 void initializeWebAssemblySetP2AlignOperandsLegacyPass(PassRegistry &);
 void initializeWebAssemblyCoalesceFeaturesAndStripAtomicsLegacyPass(
     PassRegistry &);
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp
index 78a34f20e335d..810190b956485 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp
@@ -23,9 +23,12 @@
 #include "llvm/ADT/PriorityQueue.h"
 #include "llvm/CodeGen/MachineDominators.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
 #include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachinePassManager.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Analysis.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
@@ -44,7 +47,7 @@ static cl::opt<bool> WasmDisableEHPadSort(
 
 namespace {
 
-class WebAssemblyCFGSort final : public MachineFunctionPass {
+class WebAssemblyCFGSortLegacy final : public MachineFunctionPass {
   StringRef getPassName() const override { return "WebAssembly CFG Sort"; }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -53,8 +56,8 @@ class WebAssemblyCFGSort final : public MachineFunctionPass {
     AU.addPreserved<MachineDominatorTreeWrapperPass>();
     AU.addRequired<MachineLoopInfoWrapperPass>();
     AU.addPreserved<MachineLoopInfoWrapperPass>();
-    AU.addRequired<WebAssemblyExceptionInfo>();
-    AU.addPreserved<WebAssemblyExceptionInfo>();
+    AU.addRequired<WebAssemblyExceptionInfoWrapperPass>();
+    AU.addPreserved<WebAssemblyExceptionInfoWrapperPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
 
@@ -62,16 +65,16 @@ class WebAssemblyCFGSort final : public MachineFunctionPass {
 
 public:
   static char ID; // Pass identification, replacement for typeid
-  WebAssemblyCFGSort() : MachineFunctionPass(ID) {}
+  WebAssemblyCFGSortLegacy() : MachineFunctionPass(ID) {}
 };
 } // end anonymous namespace
 
-char WebAssemblyCFGSort::ID = 0;
-INITIALIZE_PASS(WebAssemblyCFGSort, DEBUG_TYPE,
+char WebAssemblyCFGSortLegacy::ID = 0;
+INITIALIZE_PASS(WebAssemblyCFGSortLegacy, DEBUG_TYPE,
                 "Reorders blocks in topological order", false, false)
 
-FunctionPass *llvm::createWebAssemblyCFGSort() {
-  return new WebAssemblyCFGSort();
+FunctionPass *llvm::createWebAssemblyCFGSortLegacyPass() {
+  return new WebAssemblyCFGSortLegacy();
 }
 
 static void maybeUpdateTerminator(MachineBasicBlock *MBB) {
@@ -379,14 +382,12 @@ static void sortBlocks(MachineFunction &MF, const MachineLoopInfo &MLI,
 #endif
 }
 
-bool WebAssemblyCFGSort::runOnMachineFunction(MachineFunction &MF) {
+static bool sortCFG(MachineFunction &MF, MachineLoopInfo &MLI,
+                    WebAssemblyExceptionInfo &WEI, MachineDominatorTree &MDT) {
   LLVM_DEBUG(dbgs() << "********** CFG Sorting **********\n"
                        "********** Function: "
                     << MF.getName() << '\n');
 
-  const auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
-  const auto &WEI = getAnalysis<WebAssemblyExceptionInfo>();
-  auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
   // Liveness is not tracked for VALUE_STACK physreg.
   MF.getRegInfo().invalidateLiveness();
 
@@ -395,3 +396,24 @@ bool WebAssemblyCFGSort::runOnMachineFunction(MachineFunction &MF) {
 
   return true;
 }
+
+bool WebAssemblyCFGSortLegacy::runOnMachineFunction(MachineFunction &MF) {
+  MachineLoopInfo &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
+  WebAssemblyExceptionInfo &WEI =
+      getAnalysis<WebAssemblyExceptionInfoWrapperPass>().getWEI();
+  MachineDominatorTree &MDT =
+      getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
+  return sortCFG(MF, MLI, WEI, MDT);
+}
+
+PreservedAnalyses
+WebAssemblyCFGSortPass::run(MachineFunction &MF,
+                            MachineFunctionAnalysisManager &MFAM) {
+  MachineLoopInfo &MLI = MFAM.getResult<MachineLoopAnalysis>(MF);
+  WebAssemblyExceptionInfo &WEI =
+      MFAM.getResult<WebAssemblyExceptionAnalysis>(MF);
+  MachineDominatorTree &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
+  return sortCFG(MF, MLI, WEI, MDT) ? getMachineFunctionPassPreservedAnalyses()
+                                          .preserveSet<CFGAnalyses>()
+                                    : PreservedAnalyses::all();
+}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
index 7e12b0861116e..be781af1c20a9 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
@@ -54,7 +54,7 @@ class WebAssemblyCFGStackify final : public MachineFunctionPass {
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequired<MachineDominatorTreeWrapperPass>();
     AU.addRequired<MachineLoopInfoWrapperPass>();
-    AU.addRequired<WebAssemblyExceptionInfo>();
+    AU.addRequired<WebAssemblyExceptionInfoWrapperPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
 
@@ -434,7 +434,7 @@ void WebAssemblyCFGStackify::placeBlockMarker(MachineBasicBlock &MBB) {
 void WebAssemblyCFGStackify::placeLoopMarker(MachineBasicBlock &MBB) {
   MachineFunction &MF = *MBB.getParent();
   const auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
-  const auto &WEI = getAnalysis<WebAssemblyExceptionInfo>();
+  const auto &WEI = getAnalysis<WebAssemblyExceptionInfoWrapperPass>().getWEI();
   SortRegionInfo SRI(MLI, WEI);
   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
 
@@ -504,7 +504,7 @@ void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) {
   auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
   const auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
-  const auto &WEI = getAnalysis<WebAssemblyExceptionInfo>();
+  const auto &WEI = getAnalysis<WebAssemblyExceptionInfoWrapperPass>().getWEI();
   SortRegionInfo SRI(MLI, WEI);
   const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
 
@@ -698,7 +698,7 @@ void WebAssemblyCFGStackify::placeTryTableMarker(MachineBasicBlock &MBB) {
   auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
   const auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
-  const auto &WEI = getAnalysis<WebAssemblyExceptionInfo>();
+  const auto &WEI = getAnalysis<WebAssemblyExceptionInfoWrapperPass>().getWEI();
   SortRegionInfo SRI(MLI, WEI);
   const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
 
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
index afd970ea8f577..4cf950fa5e332 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "WebAssembly.h"
+#include "WebAssemblyExceptionInfo.h"
 #include "WebAssemblyTargetMachine.h"
 #include "llvm/CodeGen/AtomicExpand.h"
 #include "llvm/CodeGen/IndirectBrExpand.h"
@@ -183,22 +184,21 @@ void WebAssemblyCodeGenPassBuilder::addPreEmitPass(
 
   // Do various transformations for exception handling.
   // Every CFG-changing optimizations should come before this.
-  if (TM.Options.ExceptionModel == ExceptionHandling::Wasm) {
-    // TODO(boomanaiden154): WebAssemblyLateEHPrepare
-  }
+  if (TM.Options.ExceptionModel == ExceptionHandling::Wasm)
+    addMachineFunctionPass(WebAssemblyLateEHPreparePass(), PMW);
 
   // Now that we have a prologue and epilogue and all frame indices are
   // rewritten, eliminate SP and FP. This allows them to be stackified,
   // colored, and numbered with the rest of the registers.
-  // TODO(boomanaiden154): WebAssemblyReplacePhysRegs
+  addMachineFunctionPass(WebAssemblyReplacePhysRegsPass(), PMW);
 
   // Preparations and optimizations related to register stackification.
   if (getOptLevel() != CodeGenOptLevel::None) {
     // Depend on LiveIntervals and perform some optimizations on it.
-    // TODO(boomanaiden154): WebAssemblyOptimizeLiveIntervals
+    addMachineFunctionPass(WebAssemblyOptimizeLiveIntervalsPass(), PMW);
 
     // Prepare memory intrinsic calls for register stackifying.
-    // TODO(boomanaiden154): WebAssemblyMemIntrinsicResults
+    addMachineFunctionPass(WebAssemblyMemIntrinsicResultsPass(), PMW);
   }
 
   // Mark registers as representing wasm's value stack. This is a key
@@ -206,18 +206,18 @@ void WebAssemblyCodeGenPassBuilder::addPreEmitPass(
   // MemIntrinsicResults above) very late, so that it sees as much code as
   // possible, including code emitted by PEI and expanded by late tail
   // duplication.
-  // TODO(boomanaiden154): WebAssemblyRegStackify
+  addMachineFunctionPass(WebAssemblyRegStackifyPass(getOptLevel()), PMW);
 
   if (getOptLevel() != CodeGenOptLevel::None) {
     // Run the register coloring pass to reduce the total number of registers.
     // This runs after stackification so that it doesn't consider registers
     // that become stackified.
-    // TODO(boomanaiden154): WebAssemblyRegColoring
+    addMachineFunctionPass(WebAssemblyRegColoringPass(), PMW);
   }
 
   // Sort the blocks of the CFG into topological order, a prerequisite for
   // BLOCK and LOOP markers.
-  // TODO(boomanaiden154): WebAssemblyCFGSort
+  addMachineFunctionPass(WebAssemblyCFGSortPass(), PMW);
 
   // Insert BLOCK and LOOP markers.
   // TODO(boomanaiden154): WebAssemblyCFGStackify
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp
index ae6a7fb79aead..0596fdad12821 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp
@@ -16,6 +16,8 @@
 #include "llvm/ADT/PostOrderIterator.h"
 #include "llvm/CodeGen/MachineDominanceFrontier.h"
 #include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
+#include "llvm/IR/Analysis.h"
 #include "llvm/IR/Function.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/MC/MCAsmInfo.h"
@@ -25,31 +27,61 @@ using namespace llvm;
 
 #define DEBUG_TYPE "wasm-exception-info"
 
-char WebAssemblyExceptionInfo::ID = 0;
+char WebAssemblyExceptionInfoWrapperPass::ID = 0;
 
-INITIALIZE_PASS_BEGIN(WebAssemblyExceptionInfo, DEBUG_TYPE,
+INITIALIZE_PASS_BEGIN(WebAssemblyExceptionInfoWrapperPass, DEBUG_TYPE,
                       "WebAssembly Exception Information", true, true)
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontierWrapperPass)
-INITIALIZE_PASS_END(WebAssemblyExceptionInfo, DEBUG_TYPE,
+INITIALIZE_PASS_END(WebAssemblyExceptionInfoWrapperPass, DEBUG_TYPE,
                     "WebAssembly Exception Information", true, true)
 
-bool WebAssemblyExceptionInfo::runOnMachineFunction(MachineFunction &MF) {
+static void computeWEI(WebAssemblyExceptionInfo &WEI, MachineFunction &MF,
+                       function_ref<MachineDominatorTree &()> GetMDT,
+                       function_ref<MachineDominanceFrontier &()> GetMDF) {
   LLVM_DEBUG(dbgs() << "********** Exception Info Calculation **********\n"
                        "********** Function: "
                     << MF.getName() << '\n');
-  releaseMemory();
   if (MF.getTarget().getMCAsmInfo().getExceptionHandlingType() !=
           ExceptionHandling::Wasm ||
       !MF.getFunction().hasPersonalityFn())
-    return false;
-  auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
-  auto &MDF = getAnalysis<MachineDominanceFrontierWrapperPass>().getMDF();
-  recalculate(MF, MDT, MDF);
-  LLVM_DEBUG(dump());
+    return;
+  MachineDominatorTree &MDT = GetMDT();
+  MachineDominanceFrontier &MDF = GetMDF();
+  WEI.recalculate(MF, MDT, MDF);
+}
+
+bool WebAssemblyExceptionInfoWrapperPass::runOnMachineFunction(
+    MachineFunction &MF) {
+  releaseMemory();
+  computeWEI(
+      WasmExceptionInfo, MF,
+      [&]() -> MachineDominatorTree & {
+        return getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
+      },
+      [&]() -> MachineDominanceFrontier & {
+        return getAnalysis<MachineDominanceFrontierWrapperPass>().getMDF();
+      });
   return false;
 }
 
+WebAssemblyExceptionAnalysis::Result
+WebAssemblyExceptionAnalysis::run(MachineFunction &MF,
+                                  MachineFunctionAnalysisManager &MFAM) {
+  WebAssemblyExceptionInfo WEI;
+  computeWEI(
+      WEI, MF,
+      [&]() -> MachineDominatorTree & {
+        return MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
+      },
+      [&]() -> MachineDominanceFrontier & {
+        return MFAM.getResult<MachineDominanceFrontierAnalysis>(MF);
+      });
+  return WEI;
+}
+
+AnalysisKey WebAssemblyExceptionAnalysis::Key;
+
 void WebAssemblyExceptionInfo::recalculate(
     MachineFunction &MF, MachineDominatorTree &MDT,
     const MachineDominanceFrontier &MDF) {
@@ -107,7 +139,8 @@ void WebAssemblyExceptionInfo::releaseMemory() {
   TopLevelExceptions.clear();
 }
 
-void WebAssemblyExceptionInfo::getAnalysisUsage(AnalysisUsage &AU) const {
+void WebAssemblyExceptionInfoWrapperPass::getAnalysisUsage(
+    AnalysisUsage &AU) const {
   AU.setPreservesAll();
   AU.addRequired<MachineDominatorTreeWrapperPass>();
   AU.addRequired<MachineDominanceFrontierWrapperPass>();
@@ -205,3 +238,14 @@ void WebAssemblyExceptionInfo::print(raw_ostream &OS, const Module *) const {
   for (auto &WE : TopLevelExceptions)
     WE->print(OS);
 }
+
+bool WebAssemblyExceptionInfo::invalidate(
+    MachineFunction &MF, const PreservedAnalyses &PA,
+    MachineFunctionAnalysisManager::Invalidator &) {
+  // Check whether the analysis, all analyses on machine functions, or the
+  // machine function's CFG have been preserved.
+  auto PAC = PA.getChecker<MachineBlockFrequencyAnalysis>();
+  return !PAC.preserved() &&
+         !PAC.preservedSet<AllAnalysesOn<MachineFunction>>() &&
+         !PAC.preservedSet<CFGAnalyses>();
+}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.h
index 1bfc61f0ab611..823f86eae9afa 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.h
@@ -16,7 +16,11 @@
 
 #include "WebAssembly.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/IR/Analysis.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Pass.h"
 
 namespace llvm {
 
@@ -120,7 +124,7 @@ class WebAssemblyException {
 
 raw_ostream &operator<<(raw_ostream &OS, const WebAssemblyException &WE);
 
-class WebAssemblyExceptionInfo final : public MachineFunctionPass {
+class WebAssemblyExceptionInfo {
   // Mapping of basic blocks to the innermost exception they occur in
   DenseMap<const MachineBasicBlock *, WebAssemblyException *> BBMap;
   std::vector<std::unique_ptr<WebAssemblyException>> TopLevelExceptions;
@@ -131,18 +135,16 @@ class WebAssemblyExceptionInfo final : public MachineFunctionPass {
   WebAssemblyException *getOutermostException(MachineBasicBlock *MBB) const;
 
 public:
-  static char ID;
-  WebAssemblyExceptionInfo() : MachineFunctionPass(ID) {}
-  ~WebAssemblyExceptionInfo() override { releaseMemory(); }
+  WebAssemblyExceptionInfo() {}
+  ~WebAssemblyExceptionInfo() { releaseMemory(); }
   WebAssemblyExceptionInfo(const WebAssemblyExceptionInfo &) = delete;
+  WebAssemblyExceptionInfo(WebAssemblyExceptionInfo &&) = default;
   WebAssemblyExceptionInfo &
   operator=(const WebAssemblyExceptionInfo &) = delete;
 
-  bool runOnMachineFunction(MachineFunction &) override;
-  void releaseMemory() override;
+  void releaseMemory();
   void recalculate(MachineFunction &MF, MachineDominatorTree &MDT,
                    const MachineDominanceFrontier &MDF);
-  void getAnalysisUsage(AnalysisUsage &AU) const override;
 
   bool empty() const { return TopLevelExceptions.empty(); }
 
@@ -166,7 +168,40 @@ class WebAssemblyExceptionInfo final : public MachineFunctionPass {
     TopLevelExceptions.push_back(std::move(WE));
   }
 
-  void print(raw_ostream &OS, const Module *M = nullptr) const override;
+  void print(raw_ostream &OS, const Module *M) const;
+
+  bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA,
+                  MachineFunctionAnalysisManager::Invalidator &);
+};
+
+class WebAssemblyExceptionInfoWrapperPass : public MachineFunctionPass {
+  WebAssemblyExceptionInfo WasmExceptionInfo;
+
+public:
+  static char ID;
+  WebAssemblyExceptionInfoWrapperPass() : MachineFunctionPass(ID) {}
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  bool runOnMachineFunction(MachineFunction &MF) override;
+  void print(raw_ostream &OS, const Module *M = nullptr) const override {
+    WasmExceptionInfo.print(OS, M);
+  }
+  void releaseMemory() override { WasmExceptionInfo.releaseMemory(); }
+
+  WebAssemblyExceptionInfo &getWEI() { return WasmExceptionInfo; }
+  const WebAssemblyExceptionInfo &getWEI() const { return WasmExceptionInfo; }
+};
+
+class WebAssemblyExceptionAnalysis
+    : public AnalysisInfoMixin<WebAssemblyExceptionAnalysis> {
+  friend AnalysisInfoMixin<WebAssemblyExceptionAnalysis>;
+  static AnalysisKey Key;
+
+public:
+  using Result = WebAssemblyExceptionInfo;
+
+  LLVM_ABI Result run(MachineFunction &MF,
+                      MachineFunctionAnalysisManager &MFAM);
 };
 
 } // end namespace llvm
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
index 56f74dce630df..01f9975225aa2 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
@@ -17,8 +17,11 @@
 #include "WebAssemblyUtilities.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/IR/Analysis.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Target/TargetMachine.h"
@@ -27,12 +30,7 @@ using namespace llvm;
 #define DEBUG_TYPE "wasm-late-eh-prepare"
 
 namespace {
-class WebAssemblyLateEHPrepare final : public MachineFunctionPass {
-  StringRef getPassName() const override {
-    return "WebAssembly Late Prepare Exception";
-  }
-
-  bool runOnMachineFunction(MachineFunction &MF) override;
+class WebAssemblyLateEHPrepareImpl {
   bool removeUnreachableEHPads(MachineFunction &MF);
   void recordCatchRetBBs(MachineFunction &MF);
   bool hoistCatches(MachineFunction &MF);
@@ -45,18 +43,29 @@ class WebAssemblyLateEHPrepare final : public MachineFunctionPass {
   MachineBasicBlock *getMatchingEHPad(MachineInstr *MI);
   SmallPtrSet<MachineBasicBlock *, 8> CatchRetBBs;
 
+public:
+  bool runOnMachineFunction(MachineFunction &MF);
+};
+
+class WebAssemblyLateEHPrepareLegacy final : public MachineFunctionPass {
+  StringRef getPassName() const override {
+    return "WebAssembly Late Prepare Exception";
+  }
+
+  bool runOnMachineFunction(MachineFunction &MF) override;
+
 public:
   static char ID; // Pass identification, replacement for typeid
-  WebAssemblyLateEHPrepare() : MachineFunctionPass(ID) {}
+  WebAssemblyLateEHPrepareLegacy() : MachineFunctionPass(ID) {}
 };
 } // end anonymous namespace
 
-char WebAssemblyLateEHPrepare::ID = 0;
-INITIALIZE_PASS(WebAssemblyLateEHPrepare, DEBUG_TYPE,
+char WebAssemblyLateEHPrepareLegacy::ID = 0;
+INITIALIZE_PASS(WebAssemblyLateEHPrepareLegacy, DEBUG_TYPE,
                 "WebAssembly Late Exception Preparation", false, false)
 
-FunctionPass *llvm::createWebAssemblyLateEHPrepare() {
-  return new WebAssemblyLateEHPrepare();
+FunctionPass *llvm::createWebAssemblyLateEHPrepareLegacyPass() {
+  return new WebAssemblyLateEHPrepareLegacy();
 }
 
 // Returns the nearest EH pad that dominates this instruction. This does not use
@@ -66,7 +75,7 @@ FunctionPass *llvm::createWebAssemblyLateEHPrepare() {
 // Returns nullptr in case it does not find any EH pad in the search, or finds
 // multiple different EH pads.
 MachineBasicBlock *
-WebAssemblyLateEHPrepare::getMatchingEHPad(MachineInstr *MI) {
+WebAssemblyLateEHPrepareImpl::getMatchingEHPad(MachineInstr *MI) {
   MachineFunction *MF = MI->getParent()->getParent();
   SmallVector<MachineBasicBlock *, 2> WL;
   SmallPtrSet<MachineBasicBlock *, 2> Visited;
@@ -112,7 +121,7 @@ static void eraseDeadBBsAndChildren(const Container &MBBs) {
   }
 }
 
-bool WebAssemblyLateEHPrepare::runOnMachineFunction(MachineFunction &MF) {
+bool WebAssemblyLateEHPrepareImpl::runOnMachineFunction(MachineFunction &MF) {
   LLVM_DEBUG(dbgs() << "********** Late EH Prepare **********\n"
                        "********** Function: "
                     << MF.getName() << '\n');
@@ -139,7 +148,8 @@ bool WebAssemblyLateEHPrepare::runOnMachineFunction(MachineFunction &MF) {
 
 // Remove unreachable EH pads and its children. If they remain, CFG
 // stackification can be tricky.
-bool WebAssemblyLateEHPrepare::removeUnreachableEHPads(MachineFunction &MF) {
+bool WebAssemblyLateEHPrepareImpl::removeUnreachableEHPads(
+    MachineFunction &MF) {
   SmallVector<MachineBasicBlock *, 4> ToDelete;
   for (auto &MBB : MF)
     if (MBB.isEHPad() && MBB.pred_empty())
@@ -151,7 +161,7 @@ bool WebAssemblyLateEHPrepare::removeUnreachableEHPads(MachineFunction &MF) {
 // Record which BB ends with catchret instruction, because this will be replaced
 // with 'br's later. This set of catchret BBs is necessary in 'getMatchingEHPad'
 // function.
-void WebAssemblyLateEHPrepare::recordCatchRetBBs(MachineFunction &MF) {
+void WebAssemblyLateEHPrepareImpl::recordCatchRetBBs(MachineFunction &MF) {
   CatchRetBBs.clear();
   for (auto &MBB : MF) {
     auto Pos = MBB.getFirstTerminator();
@@ -175,7 +185,7 @@ void WebAssemblyLateEHPrepare::recordCatchRetBBs(MachineFunction &MF) {
 //   br bb0
 // bb0:
 //   %exn = catch 0
-bool WebAssemblyLateEHPrepare::hoistCatches(MachineFunction &MF) {
+bool WebAssemblyLateEHPrepareImpl::hoistCatches(MachineFunction &MF) {
   bool Changed = false;
   SmallVector<MachineInstr *, 16> Catches;
   for (auto &MBB : MF)
@@ -201,7 +211,7 @@ bool WebAssemblyLateEHPrepare::hoistCatches(MachineFunction &MF) {
 }
 
 // Add catch_all to beginning of cleanup pads.
-bool WebAssemblyLateEHPrepare::addCatchAlls(MachineFunction &MF) {
+bool WebAssemblyLateEHPrepareImpl::addCatchAlls(MachineFunction &MF) {
   bool Changed = false;
   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
 
@@ -230,7 +240,7 @@ bool WebAssemblyLateEHPrepare::addCatchAlls(MachineFunction &MF) {
 
 // Replace pseudo-instructions catchret and cleanupret with br and rethrow
 // respectively.
-bool WebAssemblyLateEHPrepare::replaceFuncletReturns(MachineFunction &MF) {
+bool WebAssemblyLateEHPrepareImpl::replaceFuncletReturns(MachineFunction &MF) {
   bool Changed = false;
   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
 
@@ -295,7 +305,8 @@ bool WebAssemblyLateEHPrepare::replaceFuncletReturns(MachineFunction &MF) {
 
 // Add CATCH_REF and CATCH_ALL_REF pseudo instructions to EH pads, and convert
 // RETHROWs to THROW_REFs.
-bool WebAssemblyLateEHPrepare::addCatchRefsAndThrowRefs(MachineFunction &MF) {
+bool WebAssemblyLateEHPrepareImpl::addCatchRefsAndThrowRefs(
+    MachineFunction &MF) {
   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
   auto &MRI = MF.getRegInfo();
   MapVector<MachineBasicBlock *, SmallVector<MachineInstr *, 2>>
@@ -351,7 +362,7 @@ bool WebAssemblyLateEHPrepare::addCatchRefsAndThrowRefs(MachineFunction &MF) {
 }
 
 // Remove unnecessary unreachables after a throw/rethrow/throw_ref.
-bool WebAssemblyLateEHPrepare::removeUnnecessaryUnreachables(
+bool WebAssemblyLateEHPrepareImpl::removeUnnecessaryUnreachables(
     MachineFunction &MF) {
   bool Changed = false;
   for (auto &MBB : MF) {
@@ -381,7 +392,7 @@ bool WebAssemblyLateEHPrepare::removeUnnecessaryUnreachables(
 // After the stack is unwound due to a thrown exception, the __stack_pointer
 // global/__wasm_get_stack_pointer() can point to an invalid address. This
 // inserts instructions that restore the stack pointer state.
-bool WebAssemblyLateEHPrepare::restoreStackPointer(MachineFunction &MF) {
+bool WebAssemblyLateEHPrepareImpl::restoreStackPointer(MachineFunction &MF) {
   const auto *FrameLowering = static_cast<const WebAssemblyFrameLowering *>(
       MF.getSubtarget().getFrameLowering());
   if (!FrameLowering->needsPrologForEH(MF))
@@ -412,3 +423,17 @@ bool WebAssemblyLateEHPrepare::restoreStackPointer(MachineFunction &MF) {
   }
   return Changed;
 }
+
+bool WebAssemblyLateEHPrepareLegacy::runOnMachineFunction(MachineFunction &MF) {
+  WebAssemblyLateEHPrepareImpl Impl;
+  return Impl.runOnMachineFunction(MF);
+}
+
+PreservedAnalyses
+WebAssemblyLateEHPreparePass::run(MachineFunction &MF,
+                                  MachineFunctionAnalysisManager &MFAM) {
+  WebAssemblyLateEHPrepareImpl Impl;
+  return Impl.runOnMachineFunction(MF)
+             ? getMachineFunctionPassPreservedAnalyses()
+             : PreservedAnalyses::all();
+}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMemIntrinsicResults.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMemIntrinsicResults.cpp
index 74bba7339cab0..8b4285af4bb00 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMemIntrinsicResults.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMemIntrinsicResults.cpp
@@ -31,11 +31,17 @@
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "WebAssemblySubtarget.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/CodeGen/LibcallLoweringInfo.h"
 #include "llvm/CodeGen/LiveIntervals.h"
 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
 #include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachinePassManager.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/IR/Analysis.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
@@ -43,10 +49,31 @@ using namespace llvm;
 #define DEBUG_TYPE "wasm-mem-intrinsic-results"
 
 namespace {
-class WebAssemblyMemIntrinsicResults final : public MachineFunctionPass {
+class WebAssemblyMemIntrinsicResultsImpl {
+public:
+  WebAssemblyMemIntrinsicResultsImpl(MachineDominatorTree *MDT,
+                                     LiveIntervals *LIS,
+                                     const TargetLibraryInfo *LibInfo,
+                                     const LibcallLoweringInfo &LibCalls)
+      : MDT(MDT), LIS(LIS), LibInfo(LibInfo), LibCalls(LibCalls) {}
+  bool runOnMachineFunction(MachineFunction &MF);
+
+private:
+  MachineDominatorTree *MDT;
+  LiveIntervals *LIS;
+  const TargetLibraryInfo *LibInfo;
+  const LibcallLoweringInfo &LibCalls;
+
+  StringRef MemcpyName, MemmoveName, MemsetName;
+
+  bool optimizeCall(MachineBasicBlock &MBB, MachineInstr &MI,
+                    const MachineRegisterInfo &MRI) const;
+};
+
+class WebAssemblyMemIntrinsicResultsLegacy final : public MachineFunctionPass {
 public:
   static char ID; // Pass identification, replacement for typeid
-  WebAssemblyMemIntrinsicResults() : MachineFunctionPass(ID) {}
+  WebAssemblyMemIntrinsicResultsLegacy() : MachineFunctionPass(ID) {}
 
   StringRef getPassName() const override {
     return "WebAssembly Memory Intrinsic Results";
@@ -67,26 +94,16 @@ class WebAssemblyMemIntrinsicResults final : public MachineFunctionPass {
   }
 
   bool runOnMachineFunction(MachineFunction &MF) override;
-
-private:
-  MachineDominatorTree *MDT;
-  LiveIntervals *LIS;
-  const TargetLibraryInfo *LibInfo;
-
-  StringRef MemcpyName, MemmoveName, MemsetName;
-
-  bool optimizeCall(MachineBasicBlock &MBB, MachineInstr &MI,
-                    const MachineRegisterInfo &MRI) const;
 };
 } // end anonymous namespace
 
-char WebAssemblyMemIntrinsicResults::ID = 0;
-INITIALIZE_PASS(WebAssemblyMemIntrinsicResults, DEBUG_TYPE,
+char WebAssemblyMemIntrinsicResultsLegacy::ID = 0;
+INITIALIZE_PASS(WebAssemblyMemIntrinsicResultsLegacy, DEBUG_TYPE,
                 "Optimize memory intrinsic result values for WebAssembly",
                 false, false)
 
-FunctionPass *llvm::createWebAssemblyMemIntrinsicResults() {
-  return new WebAssemblyMemIntrinsicResults();
+FunctionPass *llvm::createWebAssemblyMemIntrinsicResultsLegacyPass() {
+  return new WebAssemblyMemIntrinsicResultsLegacy();
 }
 
 // Replace uses of FromReg with ToReg if they are dominated by MI.
@@ -154,7 +171,7 @@ static bool replaceDominatedUses(MachineBasicBlock &MBB, MachineInstr &MI,
   return Changed;
 }
 
-bool WebAssemblyMemIntrinsicResults::optimizeCall(
+bool WebAssemblyMemIntrinsicResultsImpl::optimizeCall(
     MachineBasicBlock &MBB, MachineInstr &MI,
     const MachineRegisterInfo &MRI) const {
   MachineOperand &Op1 = MI.getOperand(1);
@@ -182,29 +199,21 @@ bool WebAssemblyMemIntrinsicResults::optimizeCall(
   return replaceDominatedUses(MBB, MI, FromReg, ToReg, MRI, *MDT, *LIS);
 }
 
-bool WebAssemblyMemIntrinsicResults::runOnMachineFunction(MachineFunction &MF) {
+bool WebAssemblyMemIntrinsicResultsImpl::runOnMachineFunction(
+    MachineFunction &MF) {
   LLVM_DEBUG({
     dbgs() << "********** Memory Intrinsic Results **********\n"
            << "********** Function: " << MF.getName() << '\n';
   });
 
   MachineRegisterInfo &MRI = MF.getRegInfo();
-  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
-  MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
-  const WebAssemblySubtarget &Subtarget =
-      MF.getSubtarget<WebAssemblySubtarget>();
-  LibInfo =
-      &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(MF.getFunction());
-  const LibcallLoweringInfo &Libcalls =
-      getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
-          *MF.getFunction().getParent(), Subtarget);
 
   MemcpyName = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(
-      Libcalls.getLibcallImpl(RTLIB::MEMCPY));
+      LibCalls.getLibcallImpl(RTLIB::MEMCPY));
   MemmoveName = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(
-      Libcalls.getLibcallImpl(RTLIB::MEMMOVE));
+      LibCalls.getLibcallImpl(RTLIB::MEMMOVE));
   MemsetName = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(
-      Libcalls.getLibcallImpl(RTLIB::MEMSET));
+      LibCalls.getLibcallImpl(RTLIB::MEMSET));
 
   bool Changed = false;
 
@@ -228,3 +237,42 @@ bool WebAssemblyMemIntrinsicResults::runOnMachineFunction(MachineFunction &MF) {
 
   return Changed;
 }
+
+bool WebAssemblyMemIntrinsicResultsLegacy::runOnMachineFunction(
+    MachineFunction &MF) {
+  MachineDominatorTree *MDT =
+      &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
+  LiveIntervals *LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
+  const TargetLibraryInfo *LibInfo =
+      &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(MF.getFunction());
+  const WebAssemblySubtarget &Subtarget =
+      MF.getSubtarget<WebAssemblySubtarget>();
+  const LibcallLoweringInfo &LibCalls =
+      getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
+          *MF.getFunction().getParent(), Subtarget);
+  WebAssemblyMemIntrinsicResultsImpl Impl(MDT, LIS, LibInfo, LibCalls);
+  return Impl.runOnMachineFunction(MF);
+}
+
+PreservedAnalyses
+WebAssemblyMemIntrinsicResultsPass::run(MachineFunction &MF,
+                                        MachineFunctionAnalysisManager &MFAM) {
+  MachineDominatorTree *MDT = &MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
+  LiveIntervals *LIS = &MFAM.getResult<LiveIntervalsAnalysis>(MF);
+  const TargetLibraryInfo *LibInfo = &MFAM.getResult<TargetLibraryAnalysis>(MF);
+  const WebAssemblySubtarget &Subtarget =
+      MF.getSubtarget<WebAssemblySubtarget>();
+  const LibcallLoweringInfo &LibCalls =
+      MFAM.getResult<ModuleAnalysisManagerMachineFunctionProxy>(MF)
+          .getCachedResult<LibcallLoweringModuleAnalysis>(
+              *MF.getFunction().getParent())
+          ->getLibcallLowering(Subtarget);
+  WebAssemblyMemIntrinsicResultsImpl Impl(MDT, LIS, LibInfo, LibCalls);
+  bool Changed = Impl.runOnMachineFunction(MF);
+  if (!Changed)
+    return PreservedAnalyses::all();
+  return getMachineFunctionPassPreservedAnalyses()
+      .preserveSet<CFGAnalyses>()
+      .preserve<LiveIntervalsAnalysis>()
+      .preserve<SlotIndexesAnalysis>();
+}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyOptimizeLiveIntervals.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyOptimizeLiveIntervals.cpp
index 0c561622e634e..324a42b2e3e53 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyOptimizeLiveIntervals.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyOptimizeLiveIntervals.cpp
@@ -24,8 +24,12 @@
 #include "WebAssemblySubtarget.h"
 #include "llvm/CodeGen/LiveIntervals.h"
 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
+#include "llvm/CodeGen/MachinePassManager.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/IR/Analysis.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
@@ -33,7 +37,8 @@ using namespace llvm;
 #define DEBUG_TYPE "wasm-optimize-live-intervals"
 
 namespace {
-class WebAssemblyOptimizeLiveIntervals final : public MachineFunctionPass {
+class WebAssemblyOptimizeLiveIntervalsLegacy final
+    : public MachineFunctionPass {
   StringRef getPassName() const override {
     return "WebAssembly Optimize Live Intervals";
   }
@@ -57,26 +62,24 @@ class WebAssemblyOptimizeLiveIntervals final : public MachineFunctionPass {
 
 public:
   static char ID; // Pass identification, replacement for typeid
-  WebAssemblyOptimizeLiveIntervals() : MachineFunctionPass(ID) {}
+  WebAssemblyOptimizeLiveIntervalsLegacy() : MachineFunctionPass(ID) {}
 };
 } // end anonymous namespace
 
-char WebAssemblyOptimizeLiveIntervals::ID = 0;
-INITIALIZE_PASS(WebAssemblyOptimizeLiveIntervals, DEBUG_TYPE,
+char WebAssemblyOptimizeLiveIntervalsLegacy::ID = 0;
+INITIALIZE_PASS(WebAssemblyOptimizeLiveIntervalsLegacy, DEBUG_TYPE,
                 "Optimize LiveIntervals for WebAssembly", false, false)
 
-FunctionPass *llvm::createWebAssemblyOptimizeLiveIntervals() {
-  return new WebAssemblyOptimizeLiveIntervals();
+FunctionPass *llvm::createWebAssemblyOptimizeLiveIntervalsLegacyPass() {
+  return new WebAssemblyOptimizeLiveIntervalsLegacy();
 }
 
-bool WebAssemblyOptimizeLiveIntervals::runOnMachineFunction(
-    MachineFunction &MF) {
+static bool optimizeLiveIntervals(MachineFunction &MF, LiveIntervals &LIS) {
   LLVM_DEBUG(dbgs() << "********** Optimize LiveIntervals **********\n"
                        "********** Function: "
                     << MF.getName() << '\n');
 
   MachineRegisterInfo &MRI = MF.getRegInfo();
-  auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
 
   // We don't preserve SSA form.
   MRI.leaveSSA();
@@ -121,3 +124,21 @@ bool WebAssemblyOptimizeLiveIntervals::runOnMachineFunction(
 
   return true;
 }
+
+bool WebAssemblyOptimizeLiveIntervalsLegacy::runOnMachineFunction(
+    MachineFunction &MF) {
+  return optimizeLiveIntervals(
+      MF, getAnalysis<LiveIntervalsWrapperPass>().getLIS());
+}
+
+PreservedAnalyses WebAssemblyOptimizeLiveIntervalsPass::run(
+    MachineFunction &MF, MachineFunctionAnalysisManager &MFAM) {
+  bool Changed =
+      optimizeLiveIntervals(MF, MFAM.getResult<LiveIntervalsAnalysis>(MF));
+  if (!Changed)
+    return PreservedAnalyses::all();
+  return getMachineFunctionPassPreservedAnalyses()
+      .preserveSet<CFGAnalyses>()
+      .preserve<LiveIntervalsAnalysis>()
+      .preserve<SlotIndexesAnalysis>();
+}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def b/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
index caf32fae60470..93e9d5180386c 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
@@ -29,10 +29,17 @@ FUNCTION_PASS("wasm-reduce-to-any-all-true", WebAssemblyReduceToAnyAllTruePass(*
 FUNCTION_PASS("wasm-ref-type-mem2local", WebAssemblyRefTypeMem2LocalPass())
 #undef FUNCTION_PASS
 
+#ifndef MACHINE_FUNCTION_ANALYSIS
+#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS)
+#endif
+MACHINE_FUNCTION_ANALYSIS("wasm-exception-info", WebAssemblyExceptionAnalysis())
+#undef MACHINE_FUNCTION_ANALYSIS
+
 #ifndef MACHINE_FUNCTION_PASS
 #define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS)
 #endif
 MACHINE_FUNCTION_PASS("wasm-argument-move", WebAssemblyArgumentMovePass())
+MACHINE_FUNCTION_PASS("wasm-cfg-sort", WebAssemblyCFGSortPass())
 MACHINE_FUNCTION_PASS("wasm-clean-code-after-trap",
                       WebAssemblyCleanCodeAfterTrapPass())
 MACHINE_FUNCTION_PASS("wasm-isel", WebAssemblyISelDAGToDAGPass(*this, getOptLevel()))
@@ -40,8 +47,15 @@ MACHINE_FUNCTION_PASS("wasm-fix-br-table-defaults",
                       WebAssemblyFixBrTableDefaultsPass())
 MACHINE_FUNCTION_PASS("wasm-fix-irreducible-control-flow",
                       WebAssemblyFixIrreducibleControlFlowPass())
+MACHINE_FUNCTION_PASS("wasm-late-eh-prepare", WebAssemblyLateEHPreparePass())
+MACHINE_FUNCTION_PASS("wasm-mem-intrinsic-results", WebAssemblyMemIntrinsicResultsPass())
 MACHINE_FUNCTION_PASS("wasm-nullify-dbg-value-lists",
                       WebAssemblyNullifyDebugValueListsPass())
+MACHINE_FUNCTION_PASS("wasm-optimize-live-intervals",
+                      WebAssemblyOptimizeLiveIntervalsPass())
+MACHINE_FUNCTION_PASS("wasm-reg-coloring", WebAssemblyRegColoringPass())
+MACHINE_FUNCTION_PASS("wasm-reg-stackify", WebAssemblyRegStackifyPass(getOptLevel()))
+MACHINE_FUNCTION_PASS("wasm-replace-phys-regs", WebAssemblyReplacePhysRegsPass())
 MACHINE_FUNCTION_PASS("wasm-set-p2align-operands",
                       WebAssemblySetP2AlignOperandsPass())
 #undef MACHINE_FUNCTION_PASS
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegColoring.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegColoring.cpp
index 6efe09d775c4b..a1c4b02fb290d 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyRegColoring.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegColoring.cpp
@@ -20,8 +20,12 @@
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "llvm/CodeGen/LiveIntervals.h"
 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
+#include "llvm/CodeGen/MachinePassManager.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/IR/Analysis.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
@@ -29,10 +33,10 @@ using namespace llvm;
 #define DEBUG_TYPE "wasm-reg-coloring"
 
 namespace {
-class WebAssemblyRegColoring final : public MachineFunctionPass {
+class WebAssemblyRegColoringLegacy final : public MachineFunctionPass {
 public:
   static char ID; // Pass identification, replacement for typeid
-  WebAssemblyRegColoring() : MachineFunctionPass(ID) {}
+  WebAssemblyRegColoringLegacy() : MachineFunctionPass(ID) {}
 
   StringRef getPassName() const override {
     return "WebAssembly Register Coloring";
@@ -48,17 +52,15 @@ class WebAssemblyRegColoring final : public MachineFunctionPass {
   }
 
   bool runOnMachineFunction(MachineFunction &MF) override;
-
-private:
 };
 } // end anonymous namespace
 
-char WebAssemblyRegColoring::ID = 0;
-INITIALIZE_PASS(WebAssemblyRegColoring, DEBUG_TYPE,
+char WebAssemblyRegColoringLegacy::ID = 0;
+INITIALIZE_PASS(WebAssemblyRegColoringLegacy, DEBUG_TYPE,
                 "Minimize number of registers used", false, false)
 
-FunctionPass *llvm::createWebAssemblyRegColoring() {
-  return new WebAssemblyRegColoring();
+FunctionPass *llvm::createWebAssemblyRegColoringLegacyPass() {
+  return new WebAssemblyRegColoringLegacy();
 }
 
 // Compute the total spill weight for VReg.
@@ -217,7 +219,8 @@ static void undefInvalidDbgValues(
   }
 }
 
-bool WebAssemblyRegColoring::runOnMachineFunction(MachineFunction &MF) {
+static bool regColoring(MachineFunction &MF, LiveIntervals *Liveness,
+                        const MachineBlockFrequencyInfo *MBFI) {
   LLVM_DEBUG({
     dbgs() << "********** Register Coloring **********\n"
            << "********** Function: " << MF.getName() << '\n';
@@ -231,9 +234,6 @@ bool WebAssemblyRegColoring::runOnMachineFunction(MachineFunction &MF) {
     return false;
 
   MachineRegisterInfo *MRI = &MF.getRegInfo();
-  LiveIntervals *Liveness = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
-  const MachineBlockFrequencyInfo *MBFI =
-      &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
   WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
 
   // We don't preserve SSA form.
@@ -329,3 +329,27 @@ bool WebAssemblyRegColoring::runOnMachineFunction(MachineFunction &MF) {
   }
   return true;
 }
+
+bool WebAssemblyRegColoringLegacy::runOnMachineFunction(MachineFunction &MF) {
+  LiveIntervals *Liveness = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
+  const MachineBlockFrequencyInfo *MBFI =
+      &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
+  return regColoring(MF, Liveness, MBFI);
+}
+
+PreservedAnalyses
+WebAssemblyRegColoringPass::run(MachineFunction &MF,
+                                MachineFunctionAnalysisManager &MFAM) {
+  // TODO(boomanaiden154): We duplicate this check from above to avoid computing
+  // analyses if we do not need to. We should remove it when remove support for
+  // the LegacyPM and are able to simplify things.
+  if (MF.exposesReturnsTwice())
+    return PreservedAnalyses::all();
+  LiveIntervals *Liveness = &MFAM.getResult<LiveIntervalsAnalysis>(MF);
+  const MachineBlockFrequencyInfo *MBFI =
+      &MFAM.getResult<MachineBlockFrequencyAnalysis>(MF);
+  return regColoring(MF, Liveness, MBFI)
+             ? getMachineFunctionPassPreservedAnalyses()
+                   .preserveSet<CFGAnalyses>()
+             : PreservedAnalyses::all();
+}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
index 2b34e2cf5ca6b..0b10f68ccbca0 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
@@ -28,9 +28,13 @@
 #include "llvm/CodeGen/LiveIntervals.h"
 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
 #include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachinePassManager.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/IR/Analysis.h"
 #include "llvm/IR/GlobalAlias.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
@@ -40,7 +44,7 @@ using namespace llvm;
 #define DEBUG_TYPE "wasm-reg-stackify"
 
 namespace {
-class WebAssemblyRegStackify final : public MachineFunctionPass {
+class WebAssemblyRegStackifyLegacy final : public MachineFunctionPass {
   bool Optimize;
 
   StringRef getPassName() const override {
@@ -65,19 +69,21 @@ class WebAssemblyRegStackify final : public MachineFunctionPass {
 
 public:
   static char ID; // Pass identification, replacement for typeid
-  WebAssemblyRegStackify(CodeGenOptLevel OptLevel)
+  WebAssemblyRegStackifyLegacy(CodeGenOptLevel OptLevel)
       : MachineFunctionPass(ID), Optimize(OptLevel != CodeGenOptLevel::None) {}
-  WebAssemblyRegStackify() : WebAssemblyRegStackify(CodeGenOptLevel::Default) {}
+  WebAssemblyRegStackifyLegacy()
+      : WebAssemblyRegStackifyLegacy(CodeGenOptLevel::Default) {}
 };
 } // end anonymous namespace
 
-char WebAssemblyRegStackify::ID = 0;
-INITIALIZE_PASS(WebAssemblyRegStackify, DEBUG_TYPE,
+char WebAssemblyRegStackifyLegacy::ID = 0;
+INITIALIZE_PASS(WebAssemblyRegStackifyLegacy, DEBUG_TYPE,
                 "Reorder instructions to use the WebAssembly value stack",
                 false, false)
 
-FunctionPass *llvm::createWebAssemblyRegStackify(CodeGenOptLevel OptLevel) {
-  return new WebAssemblyRegStackify(OptLevel);
+FunctionPass *
+llvm::createWebAssemblyRegStackifyLegacyPass(CodeGenOptLevel OptLevel) {
+  return new WebAssemblyRegStackifyLegacy(OptLevel);
 }
 
 // Decorate the given instruction with implicit operands that enforce the
@@ -826,7 +832,8 @@ class CommutingState {
 };
 } // end anonymous namespace
 
-bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
+static bool regStackify(MachineFunction &MF, bool Optimize,
+                        MachineDominatorTree *MDT, LiveIntervals *LIS) {
   LLVM_DEBUG(dbgs() << "********** Register Stackifying **********\n"
                        "********** Function: "
                     << MF.getName() << '\n');
@@ -835,11 +842,9 @@ bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
   MachineRegisterInfo &MRI = MF.getRegInfo();
   WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
   const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
-  MachineDominatorTree *MDT = nullptr;
-  LiveIntervals *LIS = nullptr;
   if (Optimize) {
-    MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
-    LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
+    assert(MDT && "expected MDT to be available");
+    assert(LIS && "expected LIS to be available");
   }
 
   // Walk the instructions from the bottom up. Currently we don't look past
@@ -1021,3 +1026,31 @@ bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
 
   return Changed;
 }
+
+bool WebAssemblyRegStackifyLegacy::runOnMachineFunction(MachineFunction &MF) {
+  MachineDominatorTree *MDT = nullptr;
+  LiveIntervals *LIS = nullptr;
+  if (Optimize) {
+    MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
+    LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
+  }
+  return regStackify(MF, Optimize, MDT, LIS);
+}
+
+PreservedAnalyses
+WebAssemblyRegStackifyPass::run(MachineFunction &MF,
+                                MachineFunctionAnalysisManager &MFAM) {
+  MachineDominatorTree *MDT = nullptr;
+  LiveIntervals *LIS = nullptr;
+  if (Optimize) {
+    MDT = &MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
+    LIS = &MFAM.getResult<LiveIntervalsAnalysis>(MF);
+  }
+  bool Changed = regStackify(MF, Optimize, MDT, LIS);
+  if (!Changed)
+    return PreservedAnalyses::all();
+  return getMachineFunctionPassPreservedAnalyses()
+      .preserveSet<CFGAnalyses>()
+      .preserve<LiveIntervalsAnalysis>()
+      .preserve<SlotIndexesAnalysis>();
+}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp
index cb152f500436a..f2d3fc12b6af9 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp
@@ -22,9 +22,12 @@
 #include "WebAssembly.h"
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "WebAssemblySubtarget.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachinePassManager.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Analysis.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
@@ -32,10 +35,10 @@ using namespace llvm;
 #define DEBUG_TYPE "wasm-replace-phys-regs"
 
 namespace {
-class WebAssemblyReplacePhysRegs final : public MachineFunctionPass {
+class WebAssemblyReplacePhysRegsLegacy final : public MachineFunctionPass {
 public:
   static char ID; // Pass identification, replacement for typeid
-  WebAssemblyReplacePhysRegs() : MachineFunctionPass(ID) {}
+  WebAssemblyReplacePhysRegsLegacy() : MachineFunctionPass(ID) {}
 
 private:
   StringRef getPassName() const override {
@@ -51,16 +54,16 @@ class WebAssemblyReplacePhysRegs final : public MachineFunctionPass {
 };
 } // end anonymous namespace
 
-char WebAssemblyReplacePhysRegs::ID = 0;
-INITIALIZE_PASS(WebAssemblyReplacePhysRegs, DEBUG_TYPE,
+char WebAssemblyReplacePhysRegsLegacy::ID = 0;
+INITIALIZE_PASS(WebAssemblyReplacePhysRegsLegacy, DEBUG_TYPE,
                 "Replace physical registers with virtual registers", false,
                 false)
 
-FunctionPass *llvm::createWebAssemblyReplacePhysRegs() {
-  return new WebAssemblyReplacePhysRegs();
+FunctionPass *llvm::createWebAssemblyReplacePhysRegsLegacyPass() {
+  return new WebAssemblyReplacePhysRegsLegacy();
 }
 
-bool WebAssemblyReplacePhysRegs::runOnMachineFunction(MachineFunction &MF) {
+static bool replacePhysRegs(MachineFunction &MF) {
   LLVM_DEBUG({
     dbgs() << "********** Replace Physical Registers **********\n"
            << "********** Function: " << MF.getName() << '\n';
@@ -70,9 +73,6 @@ bool WebAssemblyReplacePhysRegs::runOnMachineFunction(MachineFunction &MF) {
   auto &TRI = *MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo();
   bool Changed = false;
 
-  assert(!mustPreserveAnalysisID(LiveIntervalsID) &&
-         "LiveIntervals shouldn't be active yet!");
-
   for (unsigned PReg = WebAssembly::NoRegister + 1;
        PReg < WebAssembly::NUM_TARGET_REGS; ++PReg) {
     // Skip fake registers that are never used explicitly.
@@ -105,3 +105,19 @@ bool WebAssemblyReplacePhysRegs::runOnMachineFunction(MachineFunction &MF) {
 
   return Changed;
 }
+
+bool WebAssemblyReplacePhysRegsLegacy::runOnMachineFunction(
+    MachineFunction &MF) {
+  assert(!mustPreserveAnalysisID(LiveIntervalsID) &&
+         "LiveIntervals shouldn't be active yet!");
+
+  return replacePhysRegs(MF);
+}
+
+PreservedAnalyses
+WebAssemblyReplacePhysRegsPass::run(MachineFunction &MF,
+                                    MachineFunctionAnalysisManager &MFAM) {
+  return replacePhysRegs(MF) ? getMachineFunctionPassPreservedAnalyses()
+                                   .preserveSet<CFGAnalyses>()
+                             : PreservedAnalyses::all();
+}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
index ac44dcc2be674..ef2add03ead16 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -102,16 +102,16 @@ LLVMInitializeWebAssemblyTarget() {
   initializeWebAssemblyArgumentMoveLegacyPass(PR);
   initializeWebAssemblyAsmPrinterPass(PR);
   initializeWebAssemblySetP2AlignOperandsLegacyPass(PR);
-  initializeWebAssemblyReplacePhysRegsPass(PR);
-  initializeWebAssemblyOptimizeLiveIntervalsPass(PR);
-  initializeWebAssemblyMemIntrinsicResultsPass(PR);
-  initializeWebAssemblyRegStackifyPass(PR);
-  initializeWebAssemblyRegColoringPass(PR);
+  initializeWebAssemblyReplacePhysRegsLegacyPass(PR);
+  initializeWebAssemblyOptimizeLiveIntervalsLegacyPass(PR);
+  initializeWebAssemblyMemIntrinsicResultsLegacyPass(PR);
+  initializeWebAssemblyRegStackifyLegacyPass(PR);
+  initializeWebAssemblyRegColoringLegacyPass(PR);
   initializeWebAssemblyNullifyDebugValueListsLegacyPass(PR);
   initializeWebAssemblyFixIrreducibleControlFlowLegacyPass(PR);
-  initializeWebAssemblyLateEHPreparePass(PR);
-  initializeWebAssemblyExceptionInfoPass(PR);
-  initializeWebAssemblyCFGSortPass(PR);
+  initializeWebAssemblyLateEHPrepareLegacyPass(PR);
+  initializeWebAssemblyExceptionInfoWrapperPassPass(PR);
+  initializeWebAssemblyCFGSortLegacyPass(PR);
   initializeWebAssemblyCFGStackifyPass(PR);
   initializeWebAssemblyExplicitLocalsPass(PR);
   initializeWebAssemblyLowerBrUnlessPass(PR);
@@ -451,20 +451,20 @@ void WebAssemblyPassConfig::addPreEmitPass() {
   // Do various transformations for exception handling.
   // Every CFG-changing optimizations should come before this.
   if (TM->Options.ExceptionModel == ExceptionHandling::Wasm)
-    addPass(createWebAssemblyLateEHPrepare());
+    addPass(createWebAssemblyLateEHPrepareLegacyPass());
 
   // Now that we have a prologue and epilogue and all frame indices are
   // rewritten, eliminate SP and FP. This allows them to be stackified,
   // colored, and numbered with the rest of the registers.
-  addPass(createWebAssemblyReplacePhysRegs());
+  addPass(createWebAssemblyReplacePhysRegsLegacyPass());
 
   // Preparations and optimizations related to register stackification.
   if (getOptLevel() != CodeGenOptLevel::None) {
     // Depend on LiveIntervals and perform some optimizations on it.
-    addPass(createWebAssemblyOptimizeLiveIntervals());
+    addPass(createWebAssemblyOptimizeLiveIntervalsLegacyPass());
 
     // Prepare memory intrinsic calls for register stackifying.
-    addPass(createWebAssemblyMemIntrinsicResults());
+    addPass(createWebAssemblyMemIntrinsicResultsLegacyPass());
   }
 
   // Mark registers as representing wasm's value stack. This is a key
@@ -472,18 +472,18 @@ void WebAssemblyPassConfig::addPreEmitPass() {
   // MemIntrinsicResults above) very late, so that it sees as much code as
   // possible, including code emitted by PEI and expanded by late tail
   // duplication.
-  addPass(createWebAssemblyRegStackify(getOptLevel()));
+  addPass(createWebAssemblyRegStackifyLegacyPass(getOptLevel()));
 
   if (getOptLevel() != CodeGenOptLevel::None) {
     // Run the register coloring pass to reduce the total number of registers.
     // This runs after stackification so that it doesn't consider registers
     // that become stackified.
-    addPass(createWebAssemblyRegColoring());
+    addPass(createWebAssemblyRegColoringLegacyPass());
   }
 
   // Sort the blocks of the CFG into topological order, a prerequisite for
   // BLOCK and LOOP markers.
-  addPass(createWebAssemblyCFGSort());
+  addPass(createWebAssemblyCFGSortLegacyPass());
 
   // Insert BLOCK and LOOP markers.
   addPass(createWebAssemblyCFGStackify());

>From a216733da407ffac6e0cd07da5a82dd83835d749 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Fri, 17 Jul 2026 22:18:44 +0000
Subject: [PATCH 2/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?=
 =?UTF-8?q?anges=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.7

[skip ci]
---
 llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp
index 0596fdad12821..92b1dc9502d4b 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp
@@ -14,6 +14,7 @@
 #include "WebAssemblyExceptionInfo.h"
 #include "WebAssemblyUtilities.h"
 #include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
 #include "llvm/CodeGen/MachineDominanceFrontier.h"
 #include "llvm/CodeGen/MachineDominators.h"
 #include "llvm/CodeGen/MachineFunctionAnalysisManager.h"



More information about the llvm-branch-commits mailing list