[llvm] [CodeGen] Port WinEHPrepare to new pass manager (PR #74233)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 3 01:34:45 PST 2023
https://github.com/paperchalice created https://github.com/llvm/llvm-project/pull/74233
None
>From 40007df125112016a79fbeb5a2ec6b291f9312b4 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 | 78 +++++++++++--------
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(+), 35 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..fcc79f9675636 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.
@@ -1214,7 +1228,7 @@ bool WinEHPrepare::prepareExplicitEH(Function &F) {
// 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 +1265,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 +1302,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 +1316,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