[WebAssembly] Port WebAssemblyCFGStackifyPass

Standard NewPM pass porting.

Reviewers: dschuff, sbc100, aheejin

Pull Request: https://github.com/llvm/llvm-project/pull/210255
diff --git a/llvm/lib/Target/WebAssembly/WebAssembly.h b/llvm/lib/Target/WebAssembly/WebAssembly.h
index 57a1cc0..91c8828 100644
--- a/llvm/lib/Target/WebAssembly/WebAssembly.h
+++ b/llvm/lib/Target/WebAssembly/WebAssembly.h
@@ -246,7 +246,15 @@
 };
 
 FunctionPass *createWebAssemblyCFGSortLegacyPass();
-FunctionPass *createWebAssemblyCFGStackify();
+
+class WebAssemblyCFGStackifyPass
+    : public RequiredPassInfoMixin<WebAssemblyCFGStackifyPass> {
+public:
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createWebAssemblyCFGStackifyLegacyPass();
 FunctionPass *createWebAssemblyExplicitLocals();
 FunctionPass *createWebAssemblyLowerBrUnless();
 FunctionPass *createWebAssemblyRegNumbering();
@@ -263,7 +271,7 @@
 void initializeWebAssemblyAsmPrinterPass(PassRegistry &);
 void initializeWebAssemblyCleanCodeAfterTrapLegacyPass(PassRegistry &);
 void initializeWebAssemblyCFGSortLegacyPass(PassRegistry &);
-void initializeWebAssemblyCFGStackifyPass(PassRegistry &);
+void initializeWebAssemblyCFGStackifyLegacyPass(PassRegistry &);
 void initializeWebAssemblyDAGToDAGISelLegacyPass(PassRegistry &);
 void initializeWebAssemblyDebugFixupPass(PassRegistry &);
 void initializeWebAssemblyExceptionInfoWrapperPassPass(PassRegistry &);
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
index be781af..b609f3e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
@@ -33,8 +33,12 @@
 #include "llvm/ADT/Statistic.h"
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/IR/Analysis.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/Target/TargetMachine.h"
 using namespace llvm;
@@ -46,19 +50,10 @@
 STATISTIC(NumCatchUnwindMismatches, "Number of catch unwind mismatches found");
 
 namespace {
-class WebAssemblyCFGStackify final : public MachineFunctionPass {
-  MachineDominatorTree *MDT;
-
-  StringRef getPassName() const override { return "WebAssembly CFG Stackify"; }
-
-  void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AU.addRequired<MachineDominatorTreeWrapperPass>();
-    AU.addRequired<MachineLoopInfoWrapperPass>();
-    AU.addRequired<WebAssemblyExceptionInfoWrapperPass>();
-    MachineFunctionPass::getAnalysisUsage(AU);
-  }
-
-  bool runOnMachineFunction(MachineFunction &MF) override;
+class WebAssemblyCFGStackifyImpl {
+  MachineDominatorTree &MDT;
+  MachineLoopInfo &MLI;
+  WebAssemblyExceptionInfo &WEI;
 
   // For each block whose label represents the end of a scope, record the block
   // which holds the beginning of the scope. This will allow us to quickly skip
@@ -169,21 +164,38 @@
   void unregisterScope(MachineInstr *Begin);
 
 public:
+  WebAssemblyCFGStackifyImpl(MachineDominatorTree &MDT, MachineLoopInfo &MLI,
+                             WebAssemblyExceptionInfo &WEI)
+      : MDT(MDT), MLI(MLI), WEI(WEI) {}
+
+  bool runOnMachineFunction(MachineFunction &MF);
+};
+
+class WebAssemblyCFGStackifyLegacy : public MachineFunctionPass {
+  StringRef getPassName() const override { return "WebAssembly CFG Stackify"; }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.addRequired<MachineDominatorTreeWrapperPass>();
+    AU.addRequired<MachineLoopInfoWrapperPass>();
+    AU.addRequired<WebAssemblyExceptionInfoWrapperPass>();
+    MachineFunctionPass::getAnalysisUsage(AU);
+  }
+
+public:
+  bool runOnMachineFunction(MachineFunction &MF) override;
   static char ID; // Pass identification, replacement for typeid
-  WebAssemblyCFGStackify() : MachineFunctionPass(ID) {}
-  ~WebAssemblyCFGStackify() override { releaseMemory(); }
-  void releaseMemory() override;
+  WebAssemblyCFGStackifyLegacy() : MachineFunctionPass(ID) {}
 };
 } // end anonymous namespace
 
-char WebAssemblyCFGStackify::ID = 0;
+char WebAssemblyCFGStackifyLegacy::ID = 0;
 INITIALIZE_PASS(
-    WebAssemblyCFGStackify, DEBUG_TYPE,
+    WebAssemblyCFGStackifyLegacy, DEBUG_TYPE,
     "Insert BLOCK/LOOP/TRY/TRY_TABLE markers for WebAssembly scopes", false,
     false)
 
-FunctionPass *llvm::createWebAssemblyCFGStackify() {
-  return new WebAssemblyCFGStackify();
+FunctionPass *llvm::createWebAssemblyCFGStackifyLegacyPass() {
+  return new WebAssemblyCFGStackifyLegacy();
 }
 
 /// Test whether Pred has any terminators explicitly branching to MBB, as
@@ -248,22 +260,22 @@
   return InsertPos;
 }
 
-void WebAssemblyCFGStackify::registerScope(MachineInstr *Begin,
-                                           MachineInstr *End) {
+void WebAssemblyCFGStackifyImpl::registerScope(MachineInstr *Begin,
+                                               MachineInstr *End) {
   BeginToEnd[Begin] = End;
   EndToBegin[End] = Begin;
 }
 
 // When 'End' is not an 'end_try' but a 'delegate', EHPad is nullptr.
-void WebAssemblyCFGStackify::registerTryScope(MachineInstr *Begin,
-                                              MachineInstr *End,
-                                              MachineBasicBlock *EHPad) {
+void WebAssemblyCFGStackifyImpl::registerTryScope(MachineInstr *Begin,
+                                                  MachineInstr *End,
+                                                  MachineBasicBlock *EHPad) {
   registerScope(Begin, End);
   TryToEHPad[Begin] = EHPad;
   EHPadToTry[EHPad] = Begin;
 }
 
-void WebAssemblyCFGStackify::unregisterScope(MachineInstr *Begin) {
+void WebAssemblyCFGStackifyImpl::unregisterScope(MachineInstr *Begin) {
   assert(BeginToEnd.count(Begin));
   MachineInstr *End = BeginToEnd[Begin];
   assert(EndToBegin.count(End));
@@ -280,7 +292,7 @@
 /// Insert a BLOCK marker for branches to MBB (if needed).
 // TODO Consider a more generalized way of handling block (and also loop and
 // try) signatures when we implement the multi-value proposal later.
-void WebAssemblyCFGStackify::placeBlockMarker(MachineBasicBlock &MBB) {
+void WebAssemblyCFGStackifyImpl::placeBlockMarker(MachineBasicBlock &MBB) {
   assert(!MBB.isEHPad());
   MachineFunction &MF = *MBB.getParent();
   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
@@ -294,7 +306,7 @@
   int MBBNumber = MBB.getNumber();
   for (MachineBasicBlock *Pred : MBB.predecessors()) {
     if (Pred->getNumber() < MBBNumber) {
-      Header = Header ? MDT->findNearestCommonDominator(Header, Pred) : Pred;
+      Header = Header ? MDT.findNearestCommonDominator(Header, Pred) : Pred;
       if (explicitlyBranchesTo(Pred, &MBB))
         IsBranchedTo = true;
     }
@@ -431,10 +443,8 @@
 }
 
 /// Insert a LOOP marker for a loop starting at MBB (if it's a loop header).
-void WebAssemblyCFGStackify::placeLoopMarker(MachineBasicBlock &MBB) {
+void WebAssemblyCFGStackifyImpl::placeLoopMarker(MachineBasicBlock &MBB) {
   MachineFunction &MF = *MBB.getParent();
-  const auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
-  const auto &WEI = getAnalysis<WebAssemblyExceptionInfoWrapperPass>().getWEI();
   SortRegionInfo SRI(MLI, WEI);
   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
 
@@ -498,13 +508,10 @@
   updateScopeTops(&MBB, AfterLoop);
 }
 
-void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) {
+void WebAssemblyCFGStackifyImpl::placeTryMarker(MachineBasicBlock &MBB) {
   assert(MBB.isEHPad());
   MachineFunction &MF = *MBB.getParent();
-  auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
-  const auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
-  const auto &WEI = getAnalysis<WebAssemblyExceptionInfoWrapperPass>().getWEI();
   SortRegionInfo SRI(MLI, WEI);
   const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
 
@@ -692,13 +699,10 @@
     updateScopeTops(Header, End);
 }
 
-void WebAssemblyCFGStackify::placeTryTableMarker(MachineBasicBlock &MBB) {
+void WebAssemblyCFGStackifyImpl::placeTryTableMarker(MachineBasicBlock &MBB) {
   assert(MBB.isEHPad());
   MachineFunction &MF = *MBB.getParent();
-  auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
-  const auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
-  const auto &WEI = getAnalysis<WebAssemblyExceptionInfoWrapperPass>().getWEI();
   SortRegionInfo SRI(MLI, WEI);
   const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
 
@@ -989,7 +993,7 @@
     updateScopeTops(Header, End);
 }
 
-void WebAssemblyCFGStackify::removeUnnecessaryInstrs(MachineFunction &MF) {
+void WebAssemblyCFGStackifyImpl::removeUnnecessaryInstrs(MachineFunction &MF) {
   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
 
   // When there is an unconditional branch right before a catch instruction and
@@ -1171,7 +1175,7 @@
 
 // Wrap the given range of instructions with a try-delegate that targets
 // 'UnwindDest'. RangeBegin and RangeEnd are inclusive.
-void WebAssemblyCFGStackify::addNestedTryDelegate(
+void WebAssemblyCFGStackifyImpl::addNestedTryDelegate(
     MachineInstr *RangeBegin, MachineInstr *RangeEnd,
     MachineBasicBlock *UnwindDest) {
   auto *BeginBB = RangeBegin->getParent();
@@ -1309,7 +1313,7 @@
 //   throw_ref
 // end_try_table
 MachineBasicBlock *
-WebAssemblyCFGStackify::getTrampolineBlock(MachineBasicBlock *UnwindDest) {
+WebAssemblyCFGStackifyImpl::getTrampolineBlock(MachineBasicBlock *UnwindDest) {
   // We need one trampoline BB per unwind destination, even though there are
   // multiple try_tables target the same unwind destination. If we have already
   // created one for the given UnwindDest, return it.
@@ -1380,9 +1384,9 @@
 
 // Wrap the given range of instructions with a try_table-end_try_table that
 // targets 'UnwindDest'. RangeBegin and RangeEnd are inclusive.
-void WebAssemblyCFGStackify::addNestedTryTable(MachineInstr *RangeBegin,
-                                               MachineInstr *RangeEnd,
-                                               MachineBasicBlock *UnwindDest) {
+void WebAssemblyCFGStackifyImpl::addNestedTryTable(
+    MachineInstr *RangeBegin, MachineInstr *RangeEnd,
+    MachineBasicBlock *UnwindDest) {
   auto *BeginBB = RangeBegin->getParent();
   auto *EndBB = RangeEnd->getParent();
 
@@ -1589,7 +1593,7 @@
   return Name;
 }
 
-bool WebAssemblyCFGStackify::fixCallUnwindMismatches(MachineFunction &MF) {
+bool WebAssemblyCFGStackifyImpl::fixCallUnwindMismatches(MachineFunction &MF) {
   // This function is used for both the legacy EH and the standard (exnref) EH,
   // and the reason we have unwind mismatches is the same for the both of them,
   // but the code examples in the comments are going to be different. To make
@@ -2073,7 +2077,7 @@
   return true;
 }
 
-bool WebAssemblyCFGStackify::fixCatchUnwindMismatches(MachineFunction &MF) {
+bool WebAssemblyCFGStackifyImpl::fixCatchUnwindMismatches(MachineFunction &MF) {
   // This function is used for both the legacy EH and the standard (exnref) EH,
   // and the reason we have unwind mismatches is the same for the both of them,
   // but the code examples in the comments are going to be different. To make
@@ -2364,7 +2368,7 @@
   return true;
 }
 
-void WebAssemblyCFGStackify::recalculateScopeTops(MachineFunction &MF) {
+void WebAssemblyCFGStackifyImpl::recalculateScopeTops(MachineFunction &MF) {
   // Renumber BBs and recalculate ScopeTop info because new BBs might have been
   // created and inserted during fixing unwind mismatches.
   MF.RenumberBlocks();
@@ -2398,7 +2402,7 @@
 /// that end at the function end need to have a return type signature that
 /// matches the function signature, even though it's unreachable. This function
 /// checks for such cases and fixes up the signatures.
-void WebAssemblyCFGStackify::fixEndsAtEndOfFunction(MachineFunction &MF) {
+void WebAssemblyCFGStackifyImpl::fixEndsAtEndOfFunction(MachineFunction &MF) {
   const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
 
   if (MFI.getResults().empty())
@@ -2506,7 +2510,7 @@
 }
 
 /// Insert BLOCK/LOOP/TRY/TRY_TABLE markers at appropriate places.
-void WebAssemblyCFGStackify::placeMarkers(MachineFunction &MF) {
+void WebAssemblyCFGStackifyImpl::placeMarkers(MachineFunction &MF) {
   // We allocate one more than the number of blocks in the function to
   // accommodate for the possible fake block we may insert at the end.
   ScopeTops.resize(MF.getNumBlockIDs() + 1);
@@ -2548,7 +2552,7 @@
   }
 }
 
-unsigned WebAssemblyCFGStackify::getBranchDepth(
+unsigned WebAssemblyCFGStackifyImpl::getBranchDepth(
     const SmallVectorImpl<EndMarkerInfo> &Stack, const MachineBasicBlock *MBB) {
   unsigned Depth = 0;
   for (auto X : reverse(Stack)) {
@@ -2560,7 +2564,7 @@
   return Depth;
 }
 
-unsigned WebAssemblyCFGStackify::getDelegateDepth(
+unsigned WebAssemblyCFGStackifyImpl::getDelegateDepth(
     const SmallVectorImpl<EndMarkerInfo> &Stack, const MachineBasicBlock *MBB) {
   if (MBB == FakeCallerBB)
     return Stack.size();
@@ -2595,7 +2599,7 @@
   return Depth;
 }
 
-unsigned WebAssemblyCFGStackify::getRethrowDepth(
+unsigned WebAssemblyCFGStackifyImpl::getRethrowDepth(
     const SmallVectorImpl<EndMarkerInfo> &Stack,
     const MachineBasicBlock *EHPadToRethrow) {
   unsigned Depth = 0;
@@ -2612,7 +2616,7 @@
   return Depth;
 }
 
-void WebAssemblyCFGStackify::rewriteDepthImmediates(MachineFunction &MF) {
+void WebAssemblyCFGStackifyImpl::rewriteDepthImmediates(MachineFunction &MF) {
   // Now rewrite references to basic blocks to be depth immediates.
   SmallVector<EndMarkerInfo, 8> Stack;
 
@@ -2683,29 +2687,17 @@
   assert(Stack.empty() && "Control flow should be balanced");
 }
 
-void WebAssemblyCFGStackify::cleanupFunctionData(MachineFunction &MF) {
+void WebAssemblyCFGStackifyImpl::cleanupFunctionData(MachineFunction &MF) {
   if (FakeCallerBB)
     MF.deleteMachineBasicBlock(FakeCallerBB);
   AppendixBB = FakeCallerBB = CallerTrampolineBB = nullptr;
 }
 
-void WebAssemblyCFGStackify::releaseMemory() {
-  ScopeTops.clear();
-  BeginToEnd.clear();
-  EndToBegin.clear();
-  TryToEHPad.clear();
-  EHPadToTry.clear();
-  UnwindDestToTrampoline.clear();
-}
-
-bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {
+bool WebAssemblyCFGStackifyImpl::runOnMachineFunction(MachineFunction &MF) {
   LLVM_DEBUG(dbgs() << "********** CFG Stackifying **********\n"
                        "********** Function: "
                     << MF.getName() << '\n');
   const MCAsmInfo &MCAI = MF.getTarget().getMCAsmInfo();
-  MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
-
-  releaseMemory();
 
   // Liveness is not tracked for VALUE_STACK physreg.
   MF.getRegInfo().invalidateLiveness();
@@ -2735,3 +2727,26 @@
   MF.getInfo<WebAssemblyFunctionInfo>()->setCFGStackified();
   return true;
 }
+
+bool WebAssemblyCFGStackifyLegacy::runOnMachineFunction(MachineFunction &MF) {
+  MachineDominatorTree &MDT =
+      getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
+  MachineLoopInfo &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
+  WebAssemblyExceptionInfo &WEI =
+      getAnalysis<WebAssemblyExceptionInfoWrapperPass>().getWEI();
+  WebAssemblyCFGStackifyImpl Impl(MDT, MLI, WEI);
+  return Impl.runOnMachineFunction(MF);
+}
+
+PreservedAnalyses
+WebAssemblyCFGStackifyPass::run(MachineFunction &MF,
+                                MachineFunctionAnalysisManager &MFAM) {
+  MachineDominatorTree &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
+  MachineLoopInfo &MLI = MFAM.getResult<MachineLoopAnalysis>(MF);
+  WebAssemblyExceptionInfo &WEI =
+      MFAM.getResult<WebAssemblyExceptionAnalysis>(MF);
+  WebAssemblyCFGStackifyImpl Impl(MDT, MLI, WEI);
+  return Impl.runOnMachineFunction(MF)
+             ? getMachineFunctionPassPreservedAnalyses()
+             : PreservedAnalyses::all();
+}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
index 4cf950f..9cdb42b 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
@@ -220,7 +220,7 @@
   addMachineFunctionPass(WebAssemblyCFGSortPass(), PMW);
 
   // Insert BLOCK and LOOP markers.
-  // TODO(boomanaiden154): WebAssemblyCFGStackify
+  addMachineFunctionPass(WebAssemblyCFGStackifyPass(), PMW);
 
   // Insert explicit local.get and local.set operators.
   if (!WasmDisableExplicitLocals) {
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def b/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
index 93e9d51..467a88e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
@@ -40,6 +40,7 @@
 #endif
 MACHINE_FUNCTION_PASS("wasm-argument-move", WebAssemblyArgumentMovePass())
 MACHINE_FUNCTION_PASS("wasm-cfg-sort", WebAssemblyCFGSortPass())
+MACHINE_FUNCTION_PASS("wasm-cfg-stackify", WebAssemblyCFGStackifyPass())
 MACHINE_FUNCTION_PASS("wasm-clean-code-after-trap",
                       WebAssemblyCleanCodeAfterTrapPass())
 MACHINE_FUNCTION_PASS("wasm-isel", WebAssemblyISelDAGToDAGPass(*this, getOptLevel()))
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
index ef2add0..ac242f3 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -112,7 +112,7 @@
   initializeWebAssemblyLateEHPrepareLegacyPass(PR);
   initializeWebAssemblyExceptionInfoWrapperPassPass(PR);
   initializeWebAssemblyCFGSortLegacyPass(PR);
-  initializeWebAssemblyCFGStackifyPass(PR);
+  initializeWebAssemblyCFGStackifyLegacyPass(PR);
   initializeWebAssemblyExplicitLocalsPass(PR);
   initializeWebAssemblyLowerBrUnlessPass(PR);
   initializeWebAssemblyRegNumberingPass(PR);
@@ -486,7 +486,7 @@
   addPass(createWebAssemblyCFGSortLegacyPass());
 
   // Insert BLOCK and LOOP markers.
-  addPass(createWebAssemblyCFGStackify());
+  addPass(createWebAssemblyCFGStackifyLegacyPass());
 
   // Insert explicit local.get and local.set operators.
   if (!WasmDisableExplicitLocals)