diff --git a/llvm/include/llvm/Transforms/IPO/PruneEH.h b/llvm/include/llvm/Transforms/IPO/PruneEH.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Transforms/IPO/PruneEH.h @@ -0,0 +1,29 @@ +//===- PruneEH.h - Pass which deletes unused exception handlers -----------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file implements a simple interprocedural pass which walks the +// call-graph, turning invoke instructions into calls, iff the callee cannot +// throw an exception, and marking functions 'nounwind' if they cannot throw. +// It implements this as a bottom-up traversal of the call-graph. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_IPO_PRUNEEH_H +#define LLVM_TRANSFORMS_IPO_PRUNEEH_H + +#include "llvm/Analysis/CGSCCPassManager.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { +struct PruneEHPass : PassInfoMixin { + PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, + LazyCallGraph &CG, CGSCCUpdateResult &UR); +}; +} // namespace llvm + +#endif // LLVM_TRANSFORMS_IPO_PRUNEEH_H diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -98,6 +98,7 @@ #include "llvm/Transforms/IPO/MergeFunctions.h" #include "llvm/Transforms/IPO/OpenMPOpt.h" #include "llvm/Transforms/IPO/PartialInlining.h" +#include "llvm/Transforms/IPO/PruneEH.h" #include "llvm/Transforms/IPO/SCCP.h" #include "llvm/Transforms/IPO/SampleProfile.h" #include "llvm/Transforms/IPO/StripDeadPrototypes.h" diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -121,6 +121,7 @@ CGSCC_PASS("openmpopt", OpenMPOptPass()) CGSCC_PASS("coro-split", CoroSplitPass()) CGSCC_PASS("no-op-cgscc", NoOpCGSCCPass()) +CGSCC_PASS("prune-eh", PruneEHPass()) #undef CGSCC_PASS #ifndef FUNCTION_ANALYSIS diff --git a/llvm/lib/Transforms/IPO/PruneEH.cpp b/llvm/lib/Transforms/IPO/PruneEH.cpp --- a/llvm/lib/Transforms/IPO/PruneEH.cpp +++ b/llvm/lib/Transforms/IPO/PruneEH.cpp @@ -13,6 +13,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Transforms/IPO/PruneEH.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" @@ -134,8 +135,8 @@ SCCMightReturn = true; } } - if (SCCMightUnwind && SCCMightReturn) - break; + if (SCCMightUnwind && SCCMightReturn) + break; } } @@ -262,3 +263,15 @@ BB->eraseFromParent(); } } + +PreservedAnalyses PruneEHPass::run(LazyCallGraph::SCC &C, + CGSCCAnalysisManager &AM, LazyCallGraph &CG, + CGSCCUpdateResult &UR) { + SetVector Functions; + for (auto &N : C) + Functions.insert(&N.getFunction()); + CallGraphUpdater CGU; + CGU.initialize(CG, C, AM, UR); + return runImpl(CGU, Functions) ? PreservedAnalyses::none() + : PreservedAnalyses::all(); +} diff --git a/llvm/test/Transforms/PruneEH/looptest.ll b/llvm/test/Transforms/PruneEH/looptest.ll --- a/llvm/test/Transforms/PruneEH/looptest.ll +++ b/llvm/test/Transforms/PruneEH/looptest.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -prune-eh -S | FileCheck %s +; RUN: opt < %s -passes=prune-eh -S | FileCheck %s declare void @nounwind() nounwind