[llvm] [CodeGen] Port WinEHPrepare to new pass manager (PR #74233)

via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 3 02:12:11 PST 2023


https://github.com/paperchalice updated https://github.com/llvm/llvm-project/pull/74233

>From 08608223afd4189e6b45e456779b0fae191ecc84 Mon Sep 17 00:00:00 2001
From: PaperChalice <29250197+paperchalice at users.noreply.github.com>
Date: Sat, 2 Dec 2023 15:26:26 +0800
Subject: [PATCH] [CodeGen] Port WinEHPrepare to new pass manager

---
 .../include/llvm/CodeGen/CodeGenPassBuilder.h |  5 +-
 .../llvm/CodeGen/MachinePassRegistry.def      |  2 +-
 llvm/include/llvm/CodeGen/WinEHPrepare.h      | 27 +++++++
 llvm/lib/CodeGen/WinEHPrepare.cpp             | 81 +++++++++++--------
 llvm/lib/Passes/PassBuilder.cpp               |  6 ++
 llvm/lib/Passes/PassRegistry.def              |  6 ++
 llvm/test/CodeGen/WinEH/wineh-asm.ll          |  1 +
 llvm/test/CodeGen/WinEH/wineh-cloning.ll      |  1 +
 llvm/test/CodeGen/WinEH/wineh-demotion.ll     |  1 +
 llvm/test/CodeGen/WinEH/wineh-no-demotion.ll  |  1 +
 10 files changed, 93 insertions(+), 38 deletions(-)
 create mode 100644 llvm/include/llvm/CodeGen/WinEHPrepare.h

diff --git a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
index 0a12f42109986..a8ab670ad77be 100644
--- a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
@@ -29,6 +29,7 @@
 #include "llvm/CodeGen/ReplaceWithVeclib.h"
 #include "llvm/CodeGen/SafeStack.h"
 #include "llvm/CodeGen/UnreachableBlockElim.h"
+#include "llvm/CodeGen/WinEHPrepare.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/IRPrinter/IRPrintingPasses.h"
@@ -681,7 +682,7 @@ void CodeGenPassBuilder<Derived>::addPassesToHandleExceptions(
     // We support using both GCC-style and MSVC-style exceptions on Windows, so
     // add both preparation passes. Each pass will only actually run if it
     // recognizes the personality function.
-    addPass(WinEHPass());
+    addPass(WinEHPreparePass());
     addPass(DwarfEHPass(getOptLevel()));
     break;
   case ExceptionHandling::Wasm:
@@ -689,7 +690,7 @@ void CodeGenPassBuilder<Derived>::addPassesToHandleExceptions(
     // on catchpads and cleanuppads because it does not outline them into
     // funclets. Catchswitch blocks are not lowered in SelectionDAG, so we
     // should remove PHIs there.
-    addPass(WinEHPass(/*DemoteCatchSwitchPHIOnly=*/false));
+    addPass(WinEHPreparePass(/*DemoteCatchSwitchPHIOnly=*/false));
     addPass(WasmEHPass());
     break;
   case ExceptionHandling::None:
diff --git a/llvm/include/llvm/CodeGen/MachinePassRegistry.def b/llvm/include/llvm/CodeGen/MachinePassRegistry.def
index fc2d07fd6616f..4e98fd6bc9278 100644
--- a/llvm/include/llvm/CodeGen/MachinePassRegistry.def
+++ b/llvm/include/llvm/CodeGen/MachinePassRegistry.def
@@ -54,6 +54,7 @@ FUNCTION_PASS("scalarize-masked-mem-intrin", ScalarizeMaskedMemIntrinPass, ())
 FUNCTION_PASS("tlshoist", TLSVariableHoistPass, ())
 FUNCTION_PASS("unreachableblockelim", UnreachableBlockElimPass, ())
 FUNCTION_PASS("verify", VerifierPass, ())
+FUNCTION_PASS("winehprepare", WinEHPreparePass, ())
 #undef FUNCTION_PASS
 
 #ifndef LOOP_PASS
@@ -131,7 +132,6 @@ DUMMY_FUNCTION_PASS("shadow-stack-gc-lowering", ShadowStackGCLoweringPass, ())
 DUMMY_FUNCTION_PASS("sjljehprepare", SjLjEHPreparePass, ())
 DUMMY_FUNCTION_PASS("stack-protector", StackProtectorPass, ())
 DUMMY_FUNCTION_PASS("wasmehprepare", WasmEHPass, ())
-DUMMY_FUNCTION_PASS("winehprepare", WinEHPass, ())
 #undef DUMMY_FUNCTION_PASS
 
 #ifndef DUMMY_MODULE_PASS
diff --git a/llvm/include/llvm/CodeGen/WinEHPrepare.h b/llvm/include/llvm/CodeGen/WinEHPrepare.h
new file mode 100644
index 0000000000000..0a47934d6126b
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/WinEHPrepare.h
@@ -0,0 +1,27 @@
+//===-- llvm/CodeGen/WinEHPrepare.h ----------------------------*- C++ -*--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_WINEHPREPARE_H
+#define LLVM_CODEGEN_WINEHPREPARE_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class WinEHPreparePass : public PassInfoMixin<WinEHPreparePass> {
+  bool DemoteCatchSwitchPHIOnly;
+
+public:
+  WinEHPreparePass(bool DemoteCatchSwitchPHIOnly_ = false)
+      : DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly_) {}
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+};
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_WINEHPREPARE_H
diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp
index 13791d1a78cff..f4e24d772e76b 100644
--- a/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -15,6 +15,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/CodeGen/WinEHPrepare.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/STLExtras.h"
@@ -51,27 +52,20 @@ static cl::opt<bool> DisableCleanups(
     cl::desc("Do not remove implausible terminators or other similar cleanups"),
     cl::init(false));
 
+// TODO: Remove this option when we fully migrate to new pass manager
 static cl::opt<bool> DemoteCatchSwitchPHIOnlyOpt(
     "demote-catchswitch-only", cl::Hidden,
     cl::desc("Demote catchswitch BBs only (for wasm EH)"), cl::init(false));
 
 namespace {
 
-class WinEHPrepare : public FunctionPass {
+class WinEHPrepareImpl {
 public:
   static char ID; // Pass identification, replacement for typeid.
-  WinEHPrepare(bool DemoteCatchSwitchPHIOnly = false)
-      : FunctionPass(ID), DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
-
-  bool runOnFunction(Function &Fn) override;
+  WinEHPrepareImpl(bool DemoteCatchSwitchPHIOnly)
+      : DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
 
-  bool doFinalization(Module &M) override;
-
-  void getAnalysisUsage(AnalysisUsage &AU) const override;
-
-  StringRef getPassName() const override {
-    return "Windows exception handling preparation";
-  }
+  bool runOnFunction(Function &Fn);
 
 private:
   void insertPHIStores(PHINode *OriginalPHI, AllocaInst *SpillSlot);
@@ -100,8 +94,32 @@ class WinEHPrepare : public FunctionPass {
   MapVector<BasicBlock *, std::vector<BasicBlock *>> FuncletBlocks;
 };
 
+class WinEHPrepare : public FunctionPass {
+  bool DemoteCatchSwitchPHIOnly;
+
+public:
+  static char ID; // Pass identification, replacement for typeid.
+
+  WinEHPrepare(bool DemoteCatchSwitchPHIOnly = false)
+      : FunctionPass(ID), DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
+
+  StringRef getPassName() const override {
+    return "Windows exception handling preparation";
+  }
+
+  bool runOnFunction(Function &Fn) override {
+    return WinEHPrepareImpl(DemoteCatchSwitchPHIOnly).runOnFunction(Fn);
+  }
+};
+
 } // end anonymous namespace
 
+PreservedAnalyses WinEHPreparePass::run(Function &F,
+                                        FunctionAnalysisManager &) {
+  bool Changed = WinEHPrepareImpl(DemoteCatchSwitchPHIOnly).runOnFunction(F);
+  return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
+}
+
 char WinEHPrepare::ID = 0;
 INITIALIZE_PASS(WinEHPrepare, DEBUG_TYPE, "Prepare Windows exceptions",
                 false, false)
@@ -110,7 +128,7 @@ FunctionPass *llvm::createWinEHPass(bool DemoteCatchSwitchPHIOnly) {
   return new WinEHPrepare(DemoteCatchSwitchPHIOnly);
 }
 
-bool WinEHPrepare::runOnFunction(Function &Fn) {
+bool WinEHPrepareImpl::runOnFunction(Function &Fn) {
   if (!Fn.hasPersonalityFn())
     return false;
 
@@ -125,10 +143,6 @@ bool WinEHPrepare::runOnFunction(Function &Fn) {
   return prepareExplicitEH(Fn);
 }
 
-bool WinEHPrepare::doFinalization(Module &M) { return false; }
-
-void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {}
-
 static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState,
                              const BasicBlock *BB) {
   CxxUnwindMapEntry UME;
@@ -831,7 +845,7 @@ void llvm::calculateClrEHStateNumbers(const Function *Fn,
   calculateStateNumbersForInvokes(Fn, FuncInfo);
 }
 
-void WinEHPrepare::colorFunclets(Function &F) {
+void WinEHPrepareImpl::colorFunclets(Function &F) {
   BlockColors = colorEHFunclets(F);
 
   // Invert the map from BB to colors to color to BBs.
@@ -842,8 +856,8 @@ void WinEHPrepare::colorFunclets(Function &F) {
   }
 }
 
-void WinEHPrepare::demotePHIsOnFunclets(Function &F,
-                                        bool DemoteCatchSwitchPHIOnly) {
+void WinEHPrepareImpl::demotePHIsOnFunclets(Function &F,
+                                            bool DemoteCatchSwitchPHIOnly) {
   // Strip PHI nodes off of EH pads.
   SmallVector<PHINode *, 16> PHINodes;
   for (BasicBlock &BB : make_early_inc_range(F)) {
@@ -873,7 +887,7 @@ void WinEHPrepare::demotePHIsOnFunclets(Function &F,
   }
 }
 
-void WinEHPrepare::cloneCommonBlocks(Function &F) {
+void WinEHPrepareImpl::cloneCommonBlocks(Function &F) {
   // We need to clone all blocks which belong to multiple funclets.  Values are
   // remapped throughout the funclet to propagate both the new instructions
   // *and* the new basic blocks themselves.
@@ -1075,7 +1089,7 @@ void WinEHPrepare::cloneCommonBlocks(Function &F) {
   }
 }
 
-void WinEHPrepare::removeImplausibleInstructions(Function &F) {
+void WinEHPrepareImpl::removeImplausibleInstructions(Function &F) {
   // Remove implausible terminators and replace them with UnreachableInst.
   for (auto &Funclet : FuncletBlocks) {
     BasicBlock *FuncletPadBB = Funclet.first;
@@ -1149,7 +1163,7 @@ void WinEHPrepare::removeImplausibleInstructions(Function &F) {
   }
 }
 
-void WinEHPrepare::cleanupPreparedFunclets(Function &F) {
+void WinEHPrepareImpl::cleanupPreparedFunclets(Function &F) {
   // Clean-up some of the mess we made by removing useles PHI nodes, trivial
   // branches, etc.
   for (BasicBlock &BB : llvm::make_early_inc_range(F)) {
@@ -1164,7 +1178,7 @@ void WinEHPrepare::cleanupPreparedFunclets(Function &F) {
 }
 
 #ifndef NDEBUG
-void WinEHPrepare::verifyPreparedFunclets(Function &F) {
+void WinEHPrepareImpl::verifyPreparedFunclets(Function &F) {
   for (BasicBlock &BB : F) {
     size_t NumColors = BlockColors[&BB].size();
     assert(NumColors == 1 && "Expected monochromatic BB!");
@@ -1178,7 +1192,7 @@ void WinEHPrepare::verifyPreparedFunclets(Function &F) {
 }
 #endif
 
-bool WinEHPrepare::prepareExplicitEH(Function &F) {
+bool WinEHPrepareImpl::prepareExplicitEH(Function &F) {
   // Remove unreachable blocks.  It is not valuable to assign them a color and
   // their existence can trick us into thinking values are alive when they are
   // not.
@@ -1206,15 +1220,12 @@ bool WinEHPrepare::prepareExplicitEH(Function &F) {
   LLVM_DEBUG(colorFunclets(F));
   LLVM_DEBUG(verifyPreparedFunclets(F));
 
-  BlockColors.clear();
-  FuncletBlocks.clear();
-
   return true;
 }
 
 // TODO: Share loads when one use dominates another, or when a catchpad exit
 // dominates uses (needs dominators).
-AllocaInst *WinEHPrepare::insertPHILoads(PHINode *PN, Function &F) {
+AllocaInst *WinEHPrepareImpl::insertPHILoads(PHINode *PN, Function &F) {
   BasicBlock *PHIBlock = PN->getParent();
   AllocaInst *SpillSlot = nullptr;
   Instruction *EHPad = PHIBlock->getFirstNonPHI();
@@ -1251,8 +1262,8 @@ AllocaInst *WinEHPrepare::insertPHILoads(PHINode *PN, Function &F) {
 // to be careful not to introduce interfering stores (needs liveness analysis).
 // TODO: identify related phi nodes that can share spill slots, and share them
 // (also needs liveness).
-void WinEHPrepare::insertPHIStores(PHINode *OriginalPHI,
-                                   AllocaInst *SpillSlot) {
+void WinEHPrepareImpl::insertPHIStores(PHINode *OriginalPHI,
+                                       AllocaInst *SpillSlot) {
   // Use a worklist of (Block, Value) pairs -- the given Value needs to be
   // stored to the spill slot by the end of the given Block.
   SmallVector<std::pair<BasicBlock *, Value *>, 4> Worklist;
@@ -1288,7 +1299,7 @@ void WinEHPrepare::insertPHIStores(PHINode *OriginalPHI,
   }
 }
 
-void WinEHPrepare::insertPHIStore(
+void WinEHPrepareImpl::insertPHIStore(
     BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
     SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist) {
 
@@ -1302,9 +1313,9 @@ void WinEHPrepare::insertPHIStore(
   new StoreInst(PredVal, SpillSlot, PredBlock->getTerminator());
 }
 
-void WinEHPrepare::replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
-                                      DenseMap<BasicBlock *, Value *> &Loads,
-                                      Function &F) {
+void WinEHPrepareImpl::replaceUseWithLoad(
+    Value *V, Use &U, AllocaInst *&SpillSlot,
+    DenseMap<BasicBlock *, Value *> &Loads, Function &F) {
   // Lazilly create the spill slot.
   if (!SpillSlot)
     SpillSlot = new AllocaInst(V->getType(), DL->getAllocaAddrSpace(), nullptr,
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index dad7a74693cbc..54094b58bf042 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -79,6 +79,7 @@
 #include "llvm/CodeGen/HardwareLoops.h"
 #include "llvm/CodeGen/SafeStack.h"
 #include "llvm/CodeGen/TypePromotion.h"
+#include "llvm/CodeGen/WinEHPrepare.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/PassManager.h"
@@ -1092,6 +1093,11 @@ Expected<bool> parseStructuralHashPrinterPassOptions(StringRef Params) {
                                "StructuralHashPrinterPass");
 }
 
+Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
+  return parseSinglePassOption(Params, "demote-catchswitch-only",
+                               "WinEHPreparePass");
+}
+
 } // namespace
 
 /// Tests whether a pass name starts with a valid prefix for a default pipeline
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index e23863a235a16..733065b25841c 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -521,6 +521,12 @@ FUNCTION_PASS_WITH_PARAMS(
     "sroa", "SROAPass",
     [](SROAOptions PreserveCFG) { return SROAPass(PreserveCFG); },
     parseSROAOptions, "preserve-cfg;modify-cfg")
+FUNCTION_PASS_WITH_PARAMS(
+    "winehprepare", "WinEHPreparePass",
+    [](bool DemoteCatchSwitchPHIOnly) {
+      return WinEHPreparePass(DemoteCatchSwitchPHIOnly);
+    },
+    parseWinEHPrepareOptions, "demote-catchswitch-only")
 #undef FUNCTION_PASS_WITH_PARAMS
 
 #ifndef LOOPNEST_PASS
diff --git a/llvm/test/CodeGen/WinEH/wineh-asm.ll b/llvm/test/CodeGen/WinEH/wineh-asm.ll
index c9e1632ebdbab..27ec1e6ab5333 100644
--- a/llvm/test/CodeGen/WinEH/wineh-asm.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-asm.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -winehprepare < %s
+; RUN: opt -passes=winehprepare < %s
 
 target triple = "x86_64-pc-windows-msvc"
 
diff --git a/llvm/test/CodeGen/WinEH/wineh-cloning.ll b/llvm/test/CodeGen/WinEH/wineh-cloning.ll
index 045aeadb4f7e7..40d70f14882f9 100644
--- a/llvm/test/CodeGen/WinEH/wineh-cloning.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-cloning.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -mtriple=x86_64-pc-windows-msvc -S -winehprepare  < %s | FileCheck %s
+; RUN: opt -mtriple=x86_64-pc-windows-msvc -S -passes=winehprepare  < %s | FileCheck %s
 
 declare i32 @__CxxFrameHandler3(...)
 declare i32 @__C_specific_handler(...)
diff --git a/llvm/test/CodeGen/WinEH/wineh-demotion.ll b/llvm/test/CodeGen/WinEH/wineh-demotion.ll
index 43676d57ad08c..e062609ba20dd 100644
--- a/llvm/test/CodeGen/WinEH/wineh-demotion.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-demotion.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -mtriple=x86_64-pc-windows-msvc -S -winehprepare  < %s | FileCheck %s
+; RUN: opt -mtriple=x86_64-pc-windows-msvc -S -passes=winehprepare  < %s | FileCheck %s
 
 declare i32 @__CxxFrameHandler3(...)
 
diff --git a/llvm/test/CodeGen/WinEH/wineh-no-demotion.ll b/llvm/test/CodeGen/WinEH/wineh-no-demotion.ll
index 421d0bd763cdf..93e08a1032315 100644
--- a/llvm/test/CodeGen/WinEH/wineh-no-demotion.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-no-demotion.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -mtriple=x86_64-pc-windows-msvc -S -winehprepare -disable-demotion -disable-cleanups < %s | FileCheck %s
+; RUN: opt -mtriple=x86_64-pc-windows-msvc -S -passes=winehprepare -disable-demotion -disable-cleanups < %s | FileCheck %s
 
 declare i32 @__CxxFrameHandler3(...)
 



More information about the llvm-commits mailing list