[llvm-commits] [llvm-gcc-4.2] r78626 - in /llvm-gcc-4.2/trunk/gcc: c-decl.c cp/except.c except.c except.h libfuncs.h llvm-backend.cpp llvm-convert.cpp llvm-internal.h objc/objc-act.c
Jim Grosbach
grosbach at apple.com
Mon Aug 10 17:10:16 PDT 2009
Author: grosbach
Date: Mon Aug 10 19:10:16 2009
New Revision: 78626
URL: http://llvm.org/viewvc/llvm-project?rev=78626&view=rev
Log:
SjLj based exception handling unwinding support. This patch is nasty, brutish
and short. Well, it's kinda short. Definitely nasty and brutish.
The front-end generates the register/unregister calls into the SjLj runtime,
call-site indices and landing pad dispatch. The back end fills in the LSDA
with the call-site information provided by the front end. Catch blocks are
not yet implemented.
Built on Darwin and verified no llvm-core "make check" regressions.
Modified:
llvm-gcc-4.2/trunk/gcc/c-decl.c
llvm-gcc-4.2/trunk/gcc/cp/except.c
llvm-gcc-4.2/trunk/gcc/except.c
llvm-gcc-4.2/trunk/gcc/except.h
llvm-gcc-4.2/trunk/gcc/libfuncs.h
llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp
llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
llvm-gcc-4.2/trunk/gcc/llvm-internal.h
llvm-gcc-4.2/trunk/gcc/objc/objc-act.c
Modified: llvm-gcc-4.2/trunk/gcc/c-decl.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-decl.c?rev=78626&r1=78625&r2=78626&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/c-decl.c (original)
+++ llvm-gcc-4.2/trunk/gcc/c-decl.c Mon Aug 10 19:10:16 2009
@@ -3586,6 +3586,10 @@
= llvm_init_one_libfunc (USING_SJLJ_EXCEPTIONS
? "__gcc_personality_sj0"
: "__gcc_personality_v0");
+ llvm_unwind_sjlj_register_libfunc
+ = llvm_init_one_libfunc ("_Unwind_SjLj_Register");
+ llvm_unwind_sjlj_unregister_libfunc
+ = llvm_init_one_libfunc ("_Unwind_SjLj_Unregister");
#else
eh_personality_libfunc
= init_one_libfunc (USING_SJLJ_EXCEPTIONS
Modified: llvm-gcc-4.2/trunk/gcc/cp/except.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cp/except.c?rev=78626&r1=78625&r2=78626&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/cp/except.c (original)
+++ llvm-gcc-4.2/trunk/gcc/cp/except.c Mon Aug 10 19:10:16 2009
@@ -97,6 +97,10 @@
= llvm_init_one_libfunc (USING_SJLJ_EXCEPTIONS
? "__gxx_personality_sj0"
: "__gxx_personality_v0");
+ llvm_unwind_sjlj_register_libfunc
+ = llvm_init_one_libfunc ("_Unwind_SjLj_Register");
+ llvm_unwind_sjlj_unregister_libfunc
+ = llvm_init_one_libfunc ("_Unwind_SjLj_Unregister");
#else
eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
? "__gxx_personality_sj0"
Modified: llvm-gcc-4.2/trunk/gcc/except.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/except.c?rev=78626&r1=78625&r2=78626&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/except.c (original)
+++ llvm-gcc-4.2/trunk/gcc/except.c Mon Aug 10 19:10:16 2009
@@ -115,12 +115,21 @@
htab_t type_to_runtime_map;
/* Describe the SjLj_Function_Context structure. */
+#ifndef ENABLE_LLVM
static GTY(()) tree sjlj_fc_type_node;
static int sjlj_fc_call_site_ofs;
static int sjlj_fc_data_ofs;
static int sjlj_fc_personality_ofs;
static int sjlj_fc_lsda_ofs;
static int sjlj_fc_jbuf_ofs;
+#else
+tree sjlj_fc_type_node;
+int sjlj_fc_call_site_ofs;
+int sjlj_fc_data_ofs;
+int sjlj_fc_personality_ofs;
+int sjlj_fc_lsda_ofs;
+int sjlj_fc_jbuf_ofs;
+#endif
/* Describes one exception region. */
struct eh_region GTY(())
@@ -276,7 +285,7 @@
static hashval_t ehspec_filter_hash (const void *);
static int add_ttypes_entry (htab_t, tree);
static int add_ehspec_entry (htab_t, htab_t, tree);
-static void assign_filter_values (void);
+/*static void assign_filter_values (void); */
static void build_post_landing_pads (void);
static void connect_post_landing_pads (void);
static void dw2_build_landing_pads (void);
@@ -1376,7 +1385,7 @@
we use lots of landing pads, and so every type or list can share
the same filter value, which saves table space. */
-static void
+/*static*/ void
assign_filter_values (void)
{
int i;
Modified: llvm-gcc-4.2/trunk/gcc/except.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/except.h?rev=78626&r1=78625&r2=78626&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/except.h (original)
+++ llvm-gcc-4.2/trunk/gcc/except.h Mon Aug 10 19:10:16 2009
@@ -57,6 +57,7 @@
/* After initial rtl generation, call back to finish generating
exception support code. */
extern void finish_eh_generation (void);
+extern void assign_filter_values (void);
extern void init_eh (void);
extern void init_eh_for_function (void);
@@ -124,6 +125,13 @@
extern struct eh_region *get_eh_region (unsigned);
extern tree get_eh_type_list (struct eh_region *);
extern tree lookup_type_for_runtime (tree);
+
+extern GTY(()) tree sjlj_fc_type_node;
+extern int sjlj_fc_call_site_ofs;
+extern int sjlj_fc_data_ofs;
+extern int sjlj_fc_personality_ofs;
+extern int sjlj_fc_lsda_ofs;
+extern int sjlj_fc_jbuf_ofs;
#endif
/* LLVM local end */
Modified: llvm-gcc-4.2/trunk/gcc/libfuncs.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/libfuncs.h?rev=78626&r1=78625&r2=78626&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/libfuncs.h (original)
+++ llvm-gcc-4.2/trunk/gcc/libfuncs.h Mon Aug 10 19:10:16 2009
@@ -82,9 +82,15 @@
#ifdef ENABLE_LLVM
#define llvm_unwind_resume_libfunc (llvm_libfunc_table[LTI_unwind_resume])
#define llvm_eh_personality_libfunc (llvm_libfunc_table[LTI_eh_personality])
+#define llvm_unwind_sjlj_register_libfunc \
+ (llvm_libfunc_table[LTI_unwind_sjlj_register])
+#define llvm_unwind_sjlj_unregister_libfunc \
+ (llvm_libfunc_table[LTI_unwind_sjlj_unregister])
#else
#define llvm_unwind_resume_libfunc unwind_resume_libfunc
#define llvm_eh_personality_libfunc eh_personality_libfunc
+#define llvm_unwind_sjlj_register_libfunc unwind_sjlj_register_libfunc
+#define llvm_unwind_sjlj_unregister_libfunc unwind_sjlj_unregister_libfunc
#endif
/* LLVM LOCAL end */
Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=78626&r1=78625&r2=78626&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Mon Aug 10 19:10:16 2009
@@ -59,6 +59,7 @@
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "except.h"
#include "flags.h"
#include "tree.h"
#include "diagnostic.h"
@@ -499,7 +500,10 @@
/// known at codegen time.
void performLateBackendInitialization(void) {
// The Ada front-end sets flag_exceptions only after processing the file.
- ExceptionHandling = flag_exceptions;
+ if (USING_SJLJ_EXCEPTIONS)
+ SjLjExceptionHandling = flag_exceptions;
+ else
+ DwarfExceptionHandling = flag_exceptions;
for (Module::iterator I = TheModule->begin(), E = TheModule->end();
I != E; ++I)
if (!I->isDeclaration()) {
Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=78626&r1=78625&r2=78626&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Aug 10 19:10:16 2009
@@ -158,7 +158,7 @@
TD(getTargetData()), Builder(Context, *TheFolder) {
FnDecl = fndecl;
Fn = 0;
- ReturnBB = UnwindBB = 0;
+ ReturnBB = UnwindBB = DispatchBB = 0;
ReturnOffset = 0;
if (TheDebugInfo) {
@@ -632,7 +632,78 @@
if (!DECL_LLVM_SET_P(TREE_VALUE(t)))
EmitAutomaticVariableDecl(TREE_VALUE(t));
}
-
+
+ // Register the frame with the unwind machinery if there are exception
+ // handling regions in the function.
+ if (USING_SJLJ_EXCEPTIONS && current_function_has_exception_handlers()) {
+
+ CreateExceptionValues();
+
+ // Create a function context on the stack
+ FunctionContext =
+ CreateTempLoc (ConvertType(sjlj_fc_type_node));
+ llvm::Value *Idxs[2];
+ Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+
+ // Assign the unwind personality function address
+ Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 3);
+ Value *FieldPtr = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2,
+ "personality_gep");
+ const Type *FieldTy =
+ cast<PointerType>(FieldPtr->getType())->getElementType();
+ Value *Val =
+ Builder.CreateBitCast(DECL_LLVM(llvm_eh_personality_libfunc), FieldTy);
+ Builder.CreateStore(Val, FieldPtr);
+
+ // Load the address for the language specific data area (LSDA)
+ Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 4);
+ FieldPtr
+ = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2, "lsda_gep");
+ FieldTy = cast<PointerType>(FieldPtr->getType())->getElementType();
+ Val =
+ Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
+ Intrinsic::eh_sjlj_lsda),
+ "eh_lsda");
+ Builder.CreateStore(Val, FieldPtr);
+
+ // builtin_setjmp() stuff goes here.
+ // 1. Save the frame pointer.
+ Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 5);
+ FieldPtr
+ = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2, "jbuf_gep");
+ Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+ Value *ElemPtr
+ = Builder.CreateGEP (FieldPtr, Idxs, Idxs+2, "jbuf_fp_gep");
+ FieldTy = cast<PointerType>(ElemPtr->getType())->getElementType();
+ // FIXME: The EmitBuiltinExtractReturnAddr() function comes close to
+ // what we want here. Refactor it so that it does, or make a common
+ // helper function.
+ Val = Builder.CreateCall
+ (Intrinsic::getDeclaration(TheModule, Intrinsic::frameaddress),
+ ConstantInt::get(llvm::Type::Int32Ty, 0));
+ Val = BitCastToType(Val, FieldTy);
+ Builder.CreateStore(Val, ElemPtr);
+
+ FieldPtr = BitCastToType(FieldPtr, llvm::Type::Int8Ty->getPointerTo());
+ Value *DispatchVal = Builder.CreateCall
+ (Intrinsic::getDeclaration(TheModule, Intrinsic::eh_sjlj_setjmp),
+ FieldPtr);
+ // check the return value of the setjmp. non-zero goes to dispatcher
+ Value *Zero = ConstantInt::get(llvm::Type::Int32Ty, 0);
+ Value *Compare = Builder.CreateICmpEQ(DispatchVal, Zero);
+
+ // Branch on the compare.
+ DispatchBB = BasicBlock::Create("dispatch");
+ BasicBlock *PostEntryBB = BasicBlock::Create("post_entry");
+ Builder.CreateCondBr(Compare, PostEntryBB, DispatchBB);
+ EmitBlock(PostEntryBB);
+
+ // Register the context and note that this call cannot throw
+ CallInst *RegisterCall =
+ Builder.CreateCall(DECL_LLVM(llvm_unwind_sjlj_register_libfunc),
+ FunctionContext.Ptr);
+ }
+
// Create a new block for the return node, but don't insert it yet.
ReturnBB = BasicBlock::Create("return");
}
@@ -640,7 +711,16 @@
Function *TreeToLLVM::FinishFunctionBody() {
// Insert the return block at the end of the function.
EmitBlock(ReturnBB);
-
+
+ if (USING_SJLJ_EXCEPTIONS) {
+ // Un-register the frame with the unwind machinery if there are exception
+ // handling regions in the function.
+ if (current_function_has_exception_handlers()) {
+ Builder.CreateCall(DECL_LLVM(llvm_unwind_sjlj_unregister_libfunc),
+ FunctionContext.Ptr);
+ }
+ }
+
SmallVector <Value *, 4> RetVals;
// If the function returns a value, get it into a register and return it now.
@@ -700,9 +780,16 @@
Builder.CreateAggregateRet(RetVals.data(), RetVals.size());
// Emit pending exception handling code.
- EmitLandingPads();
- EmitPostPads();
- EmitUnwindBlock();
+ if (USING_SJLJ_EXCEPTIONS) {
+ EmitSjLjLandingPads();
+ EmitPostPads();
+ EmitSjLjDispatcher();
+ EmitUnwindBlock();
+ } else {
+ EmitLandingPads();
+ EmitPostPads();
+ EmitUnwindBlock();
+ }
// If this function takes the address of a label, emit the indirect goto
// block.
@@ -1925,6 +2012,151 @@
((std::vector<struct eh_region *> *)data)->push_back(region);
}
+/// EmitSjLjDispatcher - Emit SJLJ EH dispatcher
+void TreeToLLVM::EmitSjLjDispatcher () {
+ if (DispatchBB) {
+ EmitBlock(DispatchBB);
+ // Get the call_site value
+ llvm::Value *Idxs[2];
+ Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+ Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 1);
+ Value *FieldPtr = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2,
+ "call_site_gep");
+ Value *CallSite = Builder.CreateLoad(FieldPtr, "call_site");
+
+ // Figure out which landing pad to go to via the call_site
+ // FIXME: would this be better as a switch? Probably.
+ for (unsigned region = 1 ; region < LandingPads.size() ; ++region) {
+ if (LandingPads[region]) {
+ Value *RegionNo = ConstantInt::get(llvm::Type::Int32Ty, region - 1);
+ Value *Compare = Builder.CreateICmpEQ(CallSite, RegionNo);
+ // Branch on the compare.
+ BasicBlock *NextDispatch = BasicBlock::Create("dispatch");
+ Builder.CreateCondBr(Compare, LandingPads[region], NextDispatch);
+ EmitBlock(NextDispatch);
+ }
+ }
+ Builder.CreateBr(LandingPads[1]);
+ }
+}
+
+
+/// EmitSjLjLandingPads - Emit EH landing pads.
+void TreeToLLVM::EmitSjLjLandingPads() {
+ std::vector<Value*> Args;
+ std::vector<struct eh_region *> Handlers;
+
+ for (unsigned i = 1; i < LandingPads.size(); ++i) {
+ BasicBlock *LandingPad = LandingPads[i];
+
+ if (!LandingPad)
+ continue;
+
+ CreateExceptionValues();
+
+ EmitBlock(LandingPad);
+
+ // Fetch and store the exception selector.
+ // Get the exception value from the function context
+ llvm::Value *Idxs[2];
+ Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+ Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 2);
+ Value *FieldPtr
+ = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2, "jbuf_gep");
+ Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+ Value *ElemPtr
+ = Builder.CreateGEP (FieldPtr, Idxs, Idxs+2, "jbuf_exc_gep");
+ Value *Ex = Builder.CreateLoad (ElemPtr);
+ const Type *ExceptionValueTy =
+ cast<PointerType>(ExceptionValue->getType())->getElementType();
+ Ex = CastToAnyType(Ex, false, ExceptionValueTy, false);
+ Builder.CreateStore(Ex, ExceptionValue);
+
+
+ // The exception and the personality function.
+ Args.push_back(Builder.CreateLoad(ExceptionValue, "eh_ptr"));
+ assert(llvm_eh_personality_libfunc
+ && "no exception handling personality function!");
+ Args.push_back(BitCastToType(DECL_LLVM(llvm_eh_personality_libfunc),
+ PointerType::getUnqual(Type::Int8Ty)));
+ // Add selections for each handler.
+ foreach_reachable_handler(i, false, AddHandler, &Handlers);
+
+ for (std::vector<struct eh_region *>::iterator I = Handlers.begin(),
+ E = Handlers.end(); I != E; ++I) {
+ struct eh_region *region = *I;
+
+ // Create a post landing pad for the handler.
+ getPostPad(get_eh_region_number(region));
+ int RegionKind = classify_eh_handler(region);
+ if (RegionKind < 0) {
+ // Filter - note the length.
+ tree TypeList = get_eh_type_list(region);
+ unsigned Length = list_length(TypeList);
+ Args.reserve(Args.size() + Length + 1);
+ Args.push_back(ConstantInt::get(Type::Int32Ty, Length + 1));
+
+ // Add the type infos.
+ for (; TypeList; TypeList = TREE_CHAIN(TypeList)) {
+ tree TType = lookup_type_for_runtime(TREE_VALUE(TypeList));
+ Args.push_back(Emit(TType, 0));
+ }
+ } else if (RegionKind > 0) {
+ // Catch.
+ tree TypeList = get_eh_type_list(region);
+
+ if (!TypeList) {
+ // Catch-all - push a null pointer.
+ Args.push_back(Constant::getNullValue(
+ PointerType::getUnqual(Type::Int8Ty)));
+ } else {
+ // Add the type infos.
+ for (; TypeList; TypeList = TREE_CHAIN(TypeList)) {
+ tree TType = lookup_type_for_runtime(TREE_VALUE(TypeList));
+ Args.push_back(Emit(TType, 0));
+ }
+ }
+ }
+ }
+ if (can_throw_external_1(i, false)) {
+ // Some exceptions from this region may not be caught by any handler.
+ // Since invokes are required to branch to the unwind label no matter
+ // what exception is being unwound, append a catch-all.
+
+ // The representation of a catch-all is language specific.
+ Value *Catch_All;
+ if (!lang_eh_catch_all) {
+ // Use a "cleanup" - this should be good enough for most languages.
+ Catch_All = ConstantInt::get(Type::Int32Ty, 0);
+ } else {
+ tree catch_all_type = lang_eh_catch_all();
+ if (catch_all_type == NULL_TREE)
+ // Use a C++ style null catch-all object.
+ Catch_All =
+ Constant::getNullValue(PointerType::getUnqual(Type::Int8Ty));
+ else
+ // This language has a type that catches all others.
+ Catch_All = Emit(catch_all_type, 0);
+ }
+ Args.push_back(Catch_All);
+ }
+ // Add this in when we do catch() blocks
+#if 0
+ // Emit the selector call.
+ Value *Select = Builder.CreateCall(FuncEHSelector, Args.begin(), Args.end(),
+ "eh_select");
+ Builder.CreateStore(Select, ExceptionSelectorValue);
+#endif
+ // Branch to the post landing pad for the first reachable handler.
+ assert(!Handlers.empty() && "Landing pad but no handler?");
+ Builder.CreateBr(getPostPad(get_eh_region_number(*Handlers.begin())));
+
+ Handlers.clear();
+ Args.clear();
+ }
+}
+
+
/// EmitLandingPads - Emit EH landing pads.
void TreeToLLVM::EmitLandingPads() {
std::vector<Value*> Args;
@@ -2022,7 +2254,6 @@
Value *Select = Builder.CreateCall(FuncEHSelector, Args.begin(), Args.end(),
"eh_select");
Builder.CreateStore(Select, ExceptionSelectorValue);
-
// Branch to the post landing pad for the first reachable handler.
assert(!Handlers.empty() && "Landing pad but no handler?");
Builder.CreateBr(getPostPad(get_eh_region_number(*Handlers.begin())));
@@ -2151,6 +2382,17 @@
if (UnwindBB) {
CreateExceptionValues();
EmitBlock(UnwindBB);
+ if (USING_SJLJ_EXCEPTIONS) {
+ // Mark the call_site as -1 since we're signalling to continue
+ // the unwind now.
+ llvm::Value *Idxs[2];
+ Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+ Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 1);
+ Value *FieldPtr = Builder.CreateGEP (FunctionContext.Ptr, Idxs, Idxs+2,
+ "call_site_gep");
+ const Type *FieldTy = cast<PointerType>(FieldPtr->getType())->getElementType();
+ Builder.CreateStore(ConstantInt::get(FieldTy, (uint64_t)-1, true), FieldPtr);
+ }
// Fetch and store exception handler.
Value *Arg = Builder.CreateLoad(ExceptionValue, "eh_ptr");
assert(llvm_unwind_resume_libfunc && "no unwind resume function!");
@@ -2652,6 +2894,26 @@
ThisPad = BasicBlock::Create("lpad");
LandingPad = ThisPad;
+
+ if (USING_SJLJ_EXCEPTIONS) {
+ // Mark the call site so we'll dispatch to the right landing pad
+ // when we get an exception passed back.
+ llvm::Value *Idxs[2];
+ Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+ Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, 1);
+ Value *FieldPtr = Builder.CreateGEP (FunctionContext.Ptr,
+ Idxs, Idxs+2, "call_site_gep");
+// FieldPtr = BitCastToType(FieldPtr,
+// llvm::Type::Int32Ty->getPointerTo());
+ const Type *FieldTy =
+ cast<PointerType>(FieldPtr->getType())->getElementType();
+ Constant *CallSiteIdx = ConstantInt::get(FieldTy, RegionNo, true);
+ Builder.CreateStore(CallSiteIdx, FieldPtr);
+ // Tell the back end what the call-site value is
+ Builder.CreateCall
+ (Intrinsic::getDeclaration(TheModule, Intrinsic::eh_sjlj_callsite),
+ CallSiteIdx);
+ }
} else {
assert(can_throw_external_1(RegionNo, false) &&
"Must-not-throw region handled by runtime?");
Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=78626&r1=78625&r2=78626&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Mon Aug 10 19:10:16 2009
@@ -297,7 +297,9 @@
Function *Fn;
BasicBlock *ReturnBB;
BasicBlock *UnwindBB;
+ BasicBlock *DispatchBB;
unsigned ReturnOffset;
+ MemRef FunctionContext; // For SJLJ exception handling
// State that changes as the function is emitted.
@@ -451,6 +453,12 @@
Value *EmitMemMove(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
Value *EmitMemSet(Value *DestPtr, Value *SrcVal, Value *Size, unsigned Align);
+ /// EmitSjLjDispatcher - Emit SJLJ EH dispatcher
+ void EmitSjLjDispatcher();
+
+ /// EmitSjLjLandingPads - Emit SJLJ EH landing pads.
+ void EmitSjLjLandingPads();
+
/// EmitLandingPads - Emit EH landing pads.
void EmitLandingPads();
Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/objc/objc-act.c?rev=78626&r1=78625&r2=78626&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/objc/objc-act.c (original)
+++ llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Mon Aug 10 19:10:16 2009
@@ -8291,6 +8291,10 @@
#ifdef ENABLE_LLVM
llvm_eh_personality_libfunc
= llvm_init_one_libfunc ("__objc_personality_v0");
+ llvm_unwind_sjlj_register_libfunc
+ = llvm_init_one_libfunc ("_Unwind_SjLj_Register");
+ llvm_unwind_sjlj_unregister_libfunc
+ = llvm_init_one_libfunc ("_Unwind_SjLj_Unregister");
#else
eh_personality_libfunc
= init_one_libfunc ("__objc_personality_v0");
More information about the llvm-commits
mailing list