From 99d60e0dabcf20f4db683da83cde905b7a1373de Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Thu, 31 May 2018 22:02:34 +0000 Subject: [WebAssembly] Add Wasm exception handling prepare pass Summary: This adds a pass that transforms a program to be prepared for Wasm exception handling. This is using Windows EH instructions and based on the previous Wasm EH proposal. (https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md) Reviewers: dschuff, majnemer Subscribers: jfb, mgorny, sbc100, jgravelle-google, JDevlieghere, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D43746 llvm-svn: 333696 --- llvm/lib/CodeGen/WinEHPrepare.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'llvm/lib/CodeGen/WinEHPrepare.cpp') diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp index 74ddf09974b..a4ff70daf9a 100644 --- a/llvm/lib/CodeGen/WinEHPrepare.cpp +++ b/llvm/lib/CodeGen/WinEHPrepare.cpp @@ -49,12 +49,17 @@ static cl::opt DisableCleanups( cl::desc("Do not remove implausible terminators or other similar cleanups"), cl::init(false)); +static cl::opt DemoteCatchSwitchPHIOnlyOpt( + "demote-catchswitch-only", cl::Hidden, + cl::desc("Demote catchswitch BBs only (for wasm EH)"), cl::init(false)); + namespace { class WinEHPrepare : public FunctionPass { public: static char ID; // Pass identification, replacement for typeid. - WinEHPrepare() : FunctionPass(ID) {} + WinEHPrepare(bool DemoteCatchSwitchPHIOnly = false) + : FunctionPass(ID), DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {} bool runOnFunction(Function &Fn) override; @@ -77,12 +82,14 @@ private: bool prepareExplicitEH(Function &F); void colorFunclets(Function &F); - void demotePHIsOnFunclets(Function &F); + void demotePHIsOnFunclets(Function &F, bool DemoteCatchSwitchPHIOnly); void cloneCommonBlocks(Function &F); void removeImplausibleInstructions(Function &F); void cleanupPreparedFunclets(Function &F); void verifyPreparedFunclets(Function &F); + bool DemoteCatchSwitchPHIOnly; + // All fields are reset by runOnFunction. EHPersonality Personality = EHPersonality::Unknown; @@ -97,7 +104,9 @@ char WinEHPrepare::ID = 0; INITIALIZE_PASS(WinEHPrepare, DEBUG_TYPE, "Prepare Windows exceptions", false, false) -FunctionPass *llvm::createWinEHPass() { return new WinEHPrepare(); } +FunctionPass *llvm::createWinEHPass(bool DemoteCatchSwitchPHIOnly) { + return new WinEHPrepare(DemoteCatchSwitchPHIOnly); +} bool WinEHPrepare::runOnFunction(Function &Fn) { if (!Fn.hasPersonalityFn()) @@ -678,13 +687,17 @@ void WinEHPrepare::colorFunclets(Function &F) { } } -void WinEHPrepare::demotePHIsOnFunclets(Function &F) { +void WinEHPrepare::demotePHIsOnFunclets(Function &F, + bool DemoteCatchSwitchPHIOnly) { // Strip PHI nodes off of EH pads. SmallVector PHINodes; for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) { BasicBlock *BB = &*FI++; if (!BB->isEHPad()) continue; + if (DemoteCatchSwitchPHIOnly && !isa(BB->getFirstNonPHI())) + continue; + for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { Instruction *I = &*BI++; auto *PN = dyn_cast(I); @@ -1032,7 +1045,8 @@ bool WinEHPrepare::prepareExplicitEH(Function &F) { cloneCommonBlocks(F); if (!DisableDemotion) - demotePHIsOnFunclets(F); + demotePHIsOnFunclets(F, DemoteCatchSwitchPHIOnly || + DemoteCatchSwitchPHIOnlyOpt); if (!DisableCleanups) { LLVM_DEBUG(verifyFunction(F)); -- cgit v1.2.3