From a235d13217ff14621a88f3ea96a8a3b980c56d02 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Sun, 23 Aug 2009 18:13:48 +0000 Subject: [PATCH] SJLJ pass needs to punt if there's no personality function available. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79858 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SjLjEHPrepare.cpp | 50 +++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/lib/CodeGen/SjLjEHPrepare.cpp b/lib/CodeGen/SjLjEHPrepare.cpp index 91a85c07196..61f13abcdaf 100644 --- a/lib/CodeGen/SjLjEHPrepare.cpp +++ b/lib/CodeGen/SjLjEHPrepare.cpp @@ -82,8 +82,8 @@ char SjLjEHPass::ID = 0; FunctionPass *llvm::createSjLjEHPass(const TargetLowering *TLI) { return new SjLjEHPass(TLI); } -// doInitialization - Make sure that there is a prototype for abort in the -// current module. +// doInitialization - Set up decalarations and types needed to process +// exceptions. bool SjLjEHPass::doInitialization(Module &M) { // Build the function context structure. // builtin_setjmp uses a five word jbuf @@ -119,6 +119,7 @@ bool SjLjEHPass::doInitialization(Module &M) { Selector32Fn = Intrinsic::getDeclaration(&M, Intrinsic::eh_selector_i32); Selector64Fn = Intrinsic::getDeclaration(&M, Intrinsic::eh_selector_i64); ExceptionFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_exception); + PersonalityFn = 0; return true; } @@ -280,10 +281,33 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) { // If we don't have any invokes or unwinds, there's nothing to do. if (Unwinds.empty() && Invokes.empty()) return false; + // Find the eh.selector.* and eh.exception calls. We'll use the first + // eh.selector to determine the right personality function to use. For + // SJLJ, we always use the same personality for the whole function, + // not on a per-selector basis. + // FIXME: That's a bit ugly. Better way? + SmallVector EH_Selectors; + SmallVector EH_Exceptions; + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { + if (CallInst *CI = dyn_cast(I)) { + if (CI->getCalledFunction() == Selector32Fn || + CI->getCalledFunction() == Selector64Fn) { + if (!PersonalityFn) PersonalityFn = CI->getOperand(2); + EH_Selectors.push_back(CI); + } else if (CI->getCalledFunction() == ExceptionFn) { + EH_Exceptions.push_back(CI); + } + } + } + } + // If we don't have any eh.selector calls, we can't determine the personality + // function. Without a personality function, we can't process exceptions. + if (!PersonalityFn) return false; + NumInvokes += Invokes.size(); NumUnwinds += Unwinds.size(); - if (!Invokes.empty()) { // We have invokes, so we need to add register/unregister calls to get // this function onto the global unwind stack. @@ -322,26 +346,6 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) { "exception_gep", EntryBB->getTerminator()); - // Find the eh.selector.* and eh.exception calls. We'll use the first - // ex.selector to determine the right personality function to use. For - // SJLJ, we always use the same personality for the whole function, - // not on a per-selector basis. - // FIXME: That's a bit ugly. Better way? - SmallVector EH_Selectors; - SmallVector EH_Exceptions; - for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { - if (CallInst *CI = dyn_cast(I)) { - if (CI->getCalledFunction() == Selector32Fn || - CI->getCalledFunction() == Selector64Fn) { - if (!PersonalityFn) PersonalityFn = CI->getOperand(2); - EH_Selectors.push_back(CI); - } else if (CI->getCalledFunction() == ExceptionFn) { - EH_Exceptions.push_back(CI); - } - } - } - } // The result of the eh.selector call will be replaced with a // a reference to the selector value returned in the function // context. We leave the selector itself so the EH analysis later