diff options
author | Bill Wendling <isanbard@gmail.com> | 2011-07-27 21:44:28 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2011-07-27 21:44:28 +0000 |
commit | 91c56a8d8dfb0bebfcd68b5ae3d504a1dc19aa0b (patch) | |
tree | 78360668a5f544067ab2e2822fd6773c6d9f46eb | |
parent | f36b0a2ee4fe1e67778b60daf6020574e62ca672 (diff) | |
download | external_llvm-91c56a8d8dfb0bebfcd68b5ae3d504a1dc19aa0b.zip external_llvm-91c56a8d8dfb0bebfcd68b5ae3d504a1dc19aa0b.tar.gz external_llvm-91c56a8d8dfb0bebfcd68b5ae3d504a1dc19aa0b.tar.bz2 |
Refuse to inline two functions which use different personality functions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136269 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Utils/InlineFunction.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index 714b12c..b2e6033 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -829,6 +829,40 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) { return false; } + // Find the personality function used by the landing pads of the caller. If it + // exists, then check to see that it matches the personality function used in + // the callee. + for (Function::const_iterator + I = Caller->begin(), E = Caller->end(); I != E; ++I) + if (const InvokeInst *II = dyn_cast<InvokeInst>(I->getTerminator())) { + const BasicBlock *BB = II->getUnwindDest(); + // FIXME: This 'isa' here should become go away once the new EH system is + // in place. + if (!isa<LandingPadInst>(BB->getFirstNonPHI())) + continue; + const LandingPadInst *LP = cast<LandingPadInst>(BB->getFirstNonPHI()); + const Value *CallerPersFn = LP->getPersonalityFn(); + + // If the personality functions match, then we can perform the + // inlining. Otherwise, we can't inline. + // TODO: This isn't 100% true. Some personality functions are proper + // supersets of others and can be used in place of the other. + for (Function::const_iterator + I = CalledFunc->begin(), E = CalledFunc->end(); I != E; ++I) + if (const InvokeInst *II = dyn_cast<InvokeInst>(I->getTerminator())) { + const BasicBlock *BB = II->getUnwindDest(); + // FIXME: This 'if/dyn_cast' here should become a normal 'cast' once + // the new EH system is in place. + if (const LandingPadInst *LP = + dyn_cast<LandingPadInst>(BB->getFirstNonPHI())) + if (CallerPersFn != LP->getPersonalityFn()) + return false; + break; + } + + break; + } + // Get an iterator to the last basic block in the function, which will have // the new function inlined after it. // |