summaryrefslogtreecommitdiff
path: root/lib/CodeGen/SjLjEHPrepare.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2010-10-19 23:27:08 +0000
committerJim Grosbach <grosbach@apple.com>2010-10-19 23:27:08 +0000
commite4ad387a5a88dae20f0f7578e55170bbc8eee2a9 (patch)
treef9c3cee8133510908555374961d222159566e233 /lib/CodeGen/SjLjEHPrepare.cpp
parentdb4708cf86cece22539ff022cc0601612dd02ead (diff)
downloadllvm-e4ad387a5a88dae20f0f7578e55170bbc8eee2a9.tar.gz
llvm-e4ad387a5a88dae20f0f7578e55170bbc8eee2a9.tar.bz2
llvm-e4ad387a5a88dae20f0f7578e55170bbc8eee2a9.tar.xz
Add a pre-dispatch SjLj EH hook on the unwind edge for targets to do any
setup they require. Use this for ARM/Darwin to rematerialize the base pointer from the frame pointer when required. rdar://8564268 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116879 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SjLjEHPrepare.cpp')
-rw-r--r--lib/CodeGen/SjLjEHPrepare.cpp17
1 files changed, 14 insertions, 3 deletions
diff --git a/lib/CodeGen/SjLjEHPrepare.cpp b/lib/CodeGen/SjLjEHPrepare.cpp
index b637980f88..1f6a5c4ea0 100644
--- a/lib/CodeGen/SjLjEHPrepare.cpp
+++ b/lib/CodeGen/SjLjEHPrepare.cpp
@@ -53,6 +53,7 @@ namespace {
Constant *SelectorFn;
Constant *ExceptionFn;
Constant *CallSiteFn;
+ Constant *DispatchSetupFn;
Value *CallSite;
public:
@@ -116,6 +117,8 @@ bool SjLjEHPass::doInitialization(Module &M) {
SelectorFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_selector);
ExceptionFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_exception);
CallSiteFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_callsite);
+ DispatchSetupFn
+ = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_dispatch_setup);
PersonalityFn = 0;
return true;
@@ -438,9 +441,17 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) {
BasicBlock *DispatchBlock =
BasicBlock::Create(F.getContext(), "eh.sjlj.setjmp.catch", &F);
- // Insert a load in the Catch block, and a switch on its value. By default,
- // we go to a block that just does an unwind (which is the correct action
- // for a standard call).
+ // Add a call to dispatch_setup at the start of the dispatch block. This
+ // is expanded to any target-specific setup that needs to be done.
+ Value *SetupArg =
+ CastInst::Create(Instruction::BitCast, FunctionContext,
+ Type::getInt8PtrTy(F.getContext()), "",
+ DispatchBlock);
+ CallInst::Create(DispatchSetupFn, SetupArg, "", DispatchBlock);
+
+ // Insert a load of the callsite in the dispatch block, and a switch on
+ // its value. By default, we go to a block that just does an unwind
+ // (which is the correct action for a standard call).
BasicBlock *UnwindBlock =
BasicBlock::Create(F.getContext(), "unwindbb", &F);
Unwinds.push_back(new UnwindInst(F.getContext(), UnwindBlock));