Hello Everyone, This patch is for the Cilk Plus branch mainly affecting the C++ compiler. This patch will handle exceptions thrown by the spawning function (a function called with _Cilk_spawn).
Thanks, Balaji V. Iyer.
diff --git gcc/ChangeLog.cilkplus gcc/ChangeLog.cilkplus old mode 100644 new mode 100755 index 97975d8..0cae431 --- gcc/ChangeLog.cilkplus +++ gcc/ChangeLog.cilkplus @@ -1,3 +1,22 @@ +2013-02-04 Balaji V. Iyer <balaji.v.i...@intel.com> + + * cilk.c (cilk_init_builtins): Defined __cilkrts_rethrow builtin + function. + (build_cilk_sync): Added code to set exception flag and exception data + in the stack frame. Also added code to call __cilkrts_rethrow function. + Finally, inserted this code in the appropriate location of if-stmt. + (set_cilk_except_flag): New function. + (clear_cilk_except_flag): Likewise. + (set_cilk_except_data): Likewise. + (build_cilk_catch_sync): Likewise. + * cilk-builtins.def (BUILT_IN_CILK_RETHROW): New builtin function. + * c/c-objc-common.h (LANG_HOOKS_FRAME_CLEANUP): Set this hook to + c_install_body_with_frame_cleanup. + * langhooks-def.h (LANG_HOOKS_FRAME_CLEANUP): New #define. + (lhd_install_body_with_frame_cleanup): New function. + * langhooks.h (lang_hooks_for_cilkplus): New struct field called + "install_body_with_frame_cleanup." + 2013-01-24 Balaji V. Iyer <balaji.v.i...@intel.com> * cgraphunit.c (cgraph_finalize_function): If cilkplus is enabled and diff --git gcc/builtins.def gcc/builtins.def old mode 100644 new mode 100755 diff --git gcc/c-family/ChangeLog.cilkplus gcc/c-family/ChangeLog.cilkplus old mode 100644 new mode 100755 index 9a720b8..8bc0a17 --- gcc/c-family/ChangeLog.cilkplus +++ gcc/c-family/ChangeLog.cilkplus @@ -1,3 +1,11 @@ +2013-02-04 Balaji V. Iyer <balaji.v.i...@intel.com> + + * c-cilk.c (build_cilk_wrapper_body): Replaced the function call for + install_body_with_frame_cleanup with the one from langhooks. + (build_cilk_for_body): Likewise. + (install_body_with_frame_cleanup): Renamed this function to + c_install_body_with_frame_cleanup. + 2013-01-24 Balaji V. Iyer <balaji.v.i...@intel.com> * c-cpp-elem-function.c (elem_fn_create_fn): Set the assembler name and diff --git gcc/c-family/c-cilk.c gcc/c-family/c-cilk.c old mode 100644 new mode 100755 index f1bace5..dee4579 --- gcc/c-family/c-cilk.c +++ gcc/c-family/c-cilk.c @@ -99,7 +99,6 @@ static void cilk_outline (tree inner_fn, tree *, struct wrapper_data *); static tree copy_decl_for_cilk (tree decl, copy_body_data *id); static tree check_outlined_calls (tree *, int *, void *); static tree build_cilk_wrapper (tree, tree *); -static void install_body_with_frame_cleanup (tree, tree); static bool var_mentioned_p (tree exp, tree var); extern tree build_unary_op (location_t location, enum tree_code code, @@ -135,7 +134,6 @@ call_graph_add_fn (tree fndecl, struct wrapper_data *wd) tree_cons (NULL_TREE, fndecl, cilk_trees[CILK_TI_PENDING_FUNCTIONS]); f->curr_properties = cfun->curr_properties; - gcc_assert (cfun == DECL_STRUCT_FUNCTION (outer)); gcc_assert (cfun->decl == outer); @@ -1407,7 +1405,7 @@ build_cilk_wrapper_body (tree stmt, cilk_outline (fndecl, &stmt, wd); stmt = fold_build_cleanup_point_expr (void_type_node, stmt); gcc_assert (!DECL_SAVED_TREE (fndecl)); - install_body_with_frame_cleanup (fndecl, stmt); + lang_hooks.cilkplus.install_body_with_frame_cleanup (fndecl, stmt); gcc_assert (DECL_SAVED_TREE (fndecl)); pop_cfun_to (outer); @@ -1553,8 +1551,8 @@ check_outlined_calls (tree *tp, /* This function installs the internal functions of spawn helper and parent. */ -static void -install_body_with_frame_cleanup (tree fndecl, tree body) +void +c_install_body_with_frame_cleanup (tree fndecl, tree body) { tree list; tree frame = make_cilk_frame (fndecl); @@ -2455,7 +2453,7 @@ build_cilk_for_body (struct cilk_for_desc *cfd) body = build3 (BIND_EXPR, void_type_node, loop_var, body, block); TREE_CHAIN (loop_var) = cfd->var2; if (contains_spawn (body)) - install_body_with_frame_cleanup (fndecl, body); + lang_hooks.cilkplus.install_body_with_frame_cleanup (fndecl, body); else DECL_SAVED_TREE (fndecl) = body; diff --git gcc/c/c-objc-common.h gcc/c/c-objc-common.h index 8053c53..08ad087 100644 --- gcc/c/c-objc-common.h +++ gcc/c/c-objc-common.h @@ -122,4 +122,8 @@ along with GCC; see the file COPYING3. If not see #undef LANG_HOOKS_CILK_CHECK_CTRL_FLOW #define LANG_HOOKS_CILK_CHECK_CTRL_FLOW cilk_check_ctrl_flow + +#undef LANG_HOOKS_FRAME_CLEANUP +#define LANG_HOOKS_FRAME_CLEANUP c_install_body_with_frame_cleanup + #endif /* GCC_C_OBJC_COMMON */ diff --git gcc/cilk-builtins.def gcc/cilk-builtins.def old mode 100644 new mode 100755 index 5de740a..e483dd8 --- gcc/cilk-builtins.def +++ gcc/cilk-builtins.def @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_WORKER_ID, "__cilkrts_current_worker_id") DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_WORKER_PTR, "__cilkrts_current_worker") DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_DETACH, "__cilkrts_detach") +DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_RETHROW, "__cilkrts_rethrow") DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_SYNCHED, "__cilkrts_synched") DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_STOLEN, "__cilkrts_was_stolen") DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_ENTER_FRAME, "__cilkrts_enter_frame") diff --git gcc/cilk.c gcc/cilk.c old mode 100644 new mode 100755 index 7387c4c..c444025 --- gcc/cilk.c +++ gcc/cilk.c @@ -282,7 +282,10 @@ cilk_init_builtins (void) cilk_pop_fndecl = install_builtin ("__cilkrts_pop_frame", fptr_fun, BUILT_IN_CILK_POP_FRAME, false); - + + cilk_rethrow_fndecl = install_builtin ("__cilkrts_rethrow", fptr_fun, + BUILT_IN_CILK_RETHROW, false); + cilk_leave_fndecl = build_fn_decl ("__cilkrts_leave_frame", fptr_fun); mark_cold (cilk_leave_fndecl); cilk_leave_fndecl = lang_hooks.decls.pushdecl (cilk_leave_fndecl); @@ -701,7 +704,7 @@ make_cilk_frame (tree fn) return decl; } -/*This function will expand a cilk_sync call. */ +/* This function will expand a cilk_sync call. */ tree build_cilk_sync (void) @@ -714,15 +717,17 @@ build_cilk_sync (void) tree setjmp_expr; tree sync_list, frame_addr; tree sync_begin, sync_end; + tree except_flag, except_cond; /* Cilk_sync becomes the following code: if (frame.flags & CILK_FRAME_UNSYNCHED) if (!builtin_setjmp (frame.ctx) - // cilk_enter_begin(); + // cilk_sync_begin(); __cilkrts_sync(&frame); - // cilk_enter_end(); + // cilk_sync_end(); else - <NOTHING> ; + if (sf.flags & CILK_FRAME_EXCEPTING) + __cilkrts_rethrow (&sf); else <NOTHING> ; */ @@ -736,14 +741,27 @@ build_cilk_sync (void) build_int_cst (TREE_TYPE (unsynched), 0)); frame_addr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, frame); + + /* Check if exception (0x10) bit is set in the sf->flags. */ + except_flag = fold_build2 (BIT_AND_EXPR, TREE_TYPE (flags), flags, + build_int_cst (TREE_TYPE (flags), + CILK_FRAME_EXCEPTING)); + except_flag = fold_build2 (NE_EXPR, TREE_TYPE (except_flag), except_flag, + build_int_cst (TREE_TYPE (except_flag), 0)); + + /* If the exception flag is set then call the __cilkrts_rethrow (&sf). */ + except_cond = fold_build3 (COND_EXPR, void_type_node, except_flag, + build_call_expr (cilk_rethrow_fndecl, 1, + frame_addr), + build_empty_stmt (EXPR_LOCATION (unsynched))); + sync_expr = build_call_expr (cilk_sync_fndecl, 1, frame_addr); setjmp_expr = cilk_call_setjmp (frame); setjmp_expr = fold_build2 (EQ_EXPR, TREE_TYPE (setjmp_expr), setjmp_expr, build_int_cst (TREE_TYPE (setjmp_expr), 0)); setjmp_expr = fold_build3 (COND_EXPR, void_type_node, setjmp_expr, - sync_expr, - build_empty_stmt (EXPR_LOCATION (unsynched))); + sync_expr, except_cond); sync = fold_build3 (COND_EXPR, void_type_node, unsynched, setjmp_expr, build_empty_stmt (EXPR_LOCATION (unsynched))); @@ -1563,3 +1581,132 @@ cilk_check_ctrl_flow (tree *fnbody) walk_tree (fnbody, check_gotos_outside_cilk_for, (void *) &label_list, NULL); return; } + +/* Sets the EXCEPTION bit (0x10) in the FRAME.flags field. */ + +tree +set_cilk_except_flag (tree frame) +{ + tree flags = dot (frame, CILK_TI_FRAME_FLAGS, 0); + + flags = build2 (MODIFY_EXPR, void_type_node, flags, + build2 (BIT_IOR_EXPR, TREE_TYPE (flags), flags, + build_int_cst (TREE_TYPE (flags), + CILK_FRAME_EXCEPTING))); + return flags; +} + +/* Clears the EXCEPTION bit (0x10) in the FRAME.flags field. */ + +tree +clear_cilk_except_flag (tree frame) +{ + tree flags = dot (frame, CILK_TI_FRAME_FLAGS, 0); + + flags = build2 (MODIFY_EXPR, void_type_node, flags, + build2 (BIT_AND_EXPR, TREE_TYPE (flags), flags, + build_int_cst (TREE_TYPE (flags), + ~CILK_FRAME_EXCEPTING))); + return flags; +} + +/* Sets the frame.EXCEPT_DATA field to the head of the exception pointer. */ + +tree +set_cilk_except_data (tree frame) +{ + tree except_data = dot (frame, CILK_TI_FRAME_EXCEPTION, 0); + tree uresume_fn = builtin_decl_implicit (BUILT_IN_EH_POINTER); + tree ret_expr; + uresume_fn = build_call_expr (uresume_fn, 1, + build_int_cst (integer_type_node, 0)); + ret_expr = build2 (MODIFY_EXPR, void_type_node, except_data, uresume_fn); + return ret_expr; +} + +/* This function will insert the code for a _Cilk_sync with the exception + related flags and fields set. This is created seperate because C does not + have exceptions and setting and checking these fields could trigger + seg-faults. */ + +tree +build_cilk_catch_sync (void) +{ + tree frame = cfun->cilk_frame_decl; + tree flags; + tree unsynched; + tree sync; + tree sync_expr; + tree setjmp_expr; + tree sync_list, frame_addr; + tree sync_begin, sync_end; + tree set_except_flag, except_data, sync_expr_list; + tree clear_except_flag, clear_except_cond_list; + + /* We insert the following code: + + if (frame.flags & CILK_FRAME_UNSYNCHED) + { + if (!builtin_setjmp (frame.ctx) + { + frame.except_data = __builtin_eh_pointer(0); + frame.flags |= CILK_FRAME_EXCEPTING; + // cilk_sync_begin(); + __cilkrts_sync(&frame); + // cilk_sync_end(); + } + else + frame.flags &= ~CILK_FRAME_EXCEPTING. + } + */ + flags = dot (frame, CILK_TI_FRAME_FLAGS, false); + + unsynched = fold_build2 (BIT_AND_EXPR, TREE_TYPE (flags), flags, + build_int_cst (TREE_TYPE (flags), + CILK_FRAME_UNSYNCHED)); + + unsynched = fold_build2 (NE_EXPR, TREE_TYPE (unsynched), unsynched, + build_int_cst (TREE_TYPE (unsynched), 0)); + + frame_addr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, frame); + + sync_expr_list = alloc_stmt_list (); + sync_expr = build_call_expr (cilk_sync_fndecl, 1, frame_addr); + + /* Sets the sf->except_data = __builtin_eh_pointer (0); */ + except_data = set_cilk_except_data (frame); + + /* Sets sf->flags to sf->flags | CILK_FRAME_EXCEPTING. */ + set_except_flag = set_cilk_except_flag (frame); + append_to_statement_list (sync_expr, &sync_expr_list); + append_to_statement_list (except_data, &sync_expr_list); + append_to_statement_list (set_except_flag, &sync_expr_list); + + clear_except_cond_list = alloc_stmt_list (); + + /* Sets sf->flags to sf->flags & ~CILK_FRAME_EXCEPTING. */ + clear_except_flag = clear_cilk_except_flag (frame); + append_to_statement_list (clear_except_flag, &clear_except_cond_list); + + setjmp_expr = cilk_call_setjmp (frame); + + setjmp_expr = fold_build2 (EQ_EXPR, TREE_TYPE (setjmp_expr), setjmp_expr, + build_int_cst (TREE_TYPE (setjmp_expr), 0)); + + /* Checks of __builtin_setjmp (frame.ctx) == 0. IF so, then we jump to + sync_list otherwise, we just jump to the clear_except_cond_list. */ + setjmp_expr = fold_build3 (COND_EXPR, void_type_node, setjmp_expr, + sync_expr_list, clear_except_cond_list); + + sync = fold_build3 (COND_EXPR, void_type_node, unsynched, setjmp_expr, + build_empty_stmt (EXPR_LOCATION (unsynched))); + + sync_begin = build_call_expr (cilk_sync_begin_fndecl, 1, frame_addr); + sync_end = build_call_expr (cilk_sync_end_fndecl, 1, frame_addr); + sync_list = alloc_stmt_list (); + append_to_statement_list_force (sync_begin, &sync_list); + append_to_statement_list_force (sync, &sync_list); + append_to_statement_list_force (sync_end, &sync_list); + + return sync_list; +} diff --git gcc/cilk.h gcc/cilk.h old mode 100644 new mode 100755 index 275b8b8..41ec273 --- gcc/cilk.h +++ gcc/cilk.h @@ -323,5 +323,10 @@ extern bool is_cilk_must_expand_fn (enum built_in_function); extern bool is_elem_fn_attribute_p (tree); extern bool is_cilk_function_decl (tree, tree); extern void clear_pragma_simd_list (void); +extern tree set_cilk_except_flag (tree); +extern tree clear_cilk_except_flag (tree); +extern tree set_cilk_except_data (tree); +extern void c_install_body_with_frame_cleanup (tree, tree); +tree build_cilk_catch_sync (void); #endif /* GCC_CILK_H */ diff --git gcc/cp/ChangeLog.cilkplus gcc/cp/ChangeLog.cilkplus old mode 100644 new mode 100755 index 9de4d57..b86af85 --- gcc/cp/ChangeLog.cilkplus +++ gcc/cp/ChangeLog.cilkplus @@ -1,3 +1,13 @@ +2013-02-04 Balaji V. Iyer <balaji.v.i...@intel.com> + + * cp-cilk.c (insert_sync_stmt_after_catch): New function. + (cp_install_body_with_frame_cleanup): Likewise. + (cp_make_cilk_frame): called walk_tree with insert_sync_stmt_after_catch + as a function call parameter. + * cp-objcp-common.h (LANG_HOOKS_FRAME_CLEANUP): New define. + * except.c (do_begin_catch): Made this routine non-static. + (do_end_catch): Likewise. + 2013-01-09 Balaji V. Iyer <balaji.v.i...@intel.com> * semantics.c (finish_call_expr): Added a check for lambda expression diff --git gcc/cp/cp-cilk.c gcc/cp/cp-cilk.c old mode 100644 new mode 100755 index 9df24ce..9a18180 --- gcc/cp/cp-cilk.c +++ gcc/cp/cp-cilk.c @@ -131,6 +131,7 @@ struct cilk_for_desc struct pointer_map_t *decl_map; }; +void cp_install_body_with_frame_cleanup (tree fndecl, tree body); void gimplify_cilk_for_stmt (tree *for_p, gimple_seq *pre_p); static tree compute_loop_var (struct cilk_for_desc *, tree, tree); static bool cp_extract_for_fields (struct cilk_for_desc *cfd, tree for_stmt); @@ -815,6 +816,32 @@ in_cilk_block (void) /* This function will insert a _Cilk_sync right before a try block. */ static tree +insert_sync_before_catch (tree *tp, int *walk_subtrees, + void *data ATTRIBUTE_UNUSED) +{ + tree new_sync_stmt = NULL_TREE, synced_stmt_list = NULL_TREE; + + synced_stmt_list = alloc_stmt_list (); + if (TREE_CODE (*tp) == HANDLER) + { + new_sync_stmt = build_cilk_catch_sync (); + gcc_assert (new_sync_stmt && new_sync_stmt != error_mark_node); + append_to_statement_list_force (new_sync_stmt, &synced_stmt_list); + append_to_statement_list_force (HANDLER_BODY (*tp), &synced_stmt_list); + HANDLER_BODY (*tp) = synced_stmt_list; + + /* We don't need to go any deeper. */ + *walk_subtrees = 0; + + /* We are finished here. We only need to find the first catch block. */ + return *tp; + } + return NULL; +} + +/* This function will insert a _Cilk_sync right before a try block. */ + +static tree insert_sync_stmt (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) { tree new_sync_stmt = NULL_TREE, synced_stmt_list = NULL_TREE; @@ -895,6 +922,7 @@ cp_make_cilk_frame (tree compstmt) /* Here we talk through all the subtrees of compstmt and as soon as we find a try block, we insert a _Cilk_sync right before it. */ cp_walk_tree (&compstmt, insert_sync_stmt, NULL, NULL); + cp_walk_tree (&compstmt, insert_sync_before_catch, NULL, NULL); } return decl; @@ -2898,3 +2926,41 @@ cilk_lambda_fn_temp (tree lambda_fn) add_local_decl (cfun, return_var); return return_var; } + +/* This function installs the internal functions of spawn helper and parent. */ + +void +cp_install_body_with_frame_cleanup (tree fndecl, tree body) +{ + tree list, catch_tf_expr; + tree try_catch_expr, catch_list, try_finally_expr, except_flag, except_data; + tree frame = make_cilk_frame (fndecl); + tree dtor = build_cilk_function_exit (frame, false, false); + extern tree do_begin_catch (void); + extern tree do_end_catch (tree); + add_local_decl (cfun, frame); + + DECL_SAVED_TREE (fndecl) = (list = alloc_stmt_list ()); + + catch_list = alloc_stmt_list (); + except_flag = set_cilk_except_flag (frame); + except_data = set_cilk_except_data (frame); + append_to_statement_list (except_flag, &catch_list); + append_to_statement_list (except_data, &catch_list); + append_to_statement_list (do_begin_catch (), &catch_list); + append_to_statement_list (build_throw (NULL_TREE), &catch_list); + #if 1 + append_to_statement_list (build_cilk_function_exit (frame, false, false), + &catch_list); + #endif + catch_tf_expr = build_stmt (EXPR_LOCATION (body), TRY_FINALLY_EXPR, + catch_list, do_end_catch (NULL_TREE)); + catch_list = build2 (CATCH_EXPR, void_type_node, NULL_TREE, catch_tf_expr); + + try_catch_expr = build_stmt (EXPR_LOCATION (body), TRY_CATCH_EXPR, body, + catch_list); + try_finally_expr = build_stmt (EXPR_LOCATION (body), TRY_FINALLY_EXPR, + try_catch_expr, dtor); + append_to_statement_list_force (try_finally_expr, &list); +} + diff --git gcc/cp/cp-objcp-common.h gcc/cp/cp-objcp-common.h index bcd42d9..4b96b43 100644 --- gcc/cp/cp-objcp-common.h +++ gcc/cp/cp-objcp-common.h @@ -166,4 +166,8 @@ extern void cp_common_init_ts (void); #undef LANG_HOOKS_ELEM_FN_CREATE_FN #define LANG_HOOKS_ELEM_FN_CREATE_FN elem_fn_create_fn + +#undef LANG_HOOKS_FRAME_CLEANUP +#define LANG_HOOKS_FRAME_CLEANUP cp_install_body_with_frame_cleanup + #endif /* GCC_CP_OBJCP_COMMON */ diff --git gcc/cp/cp-tree.h gcc/cp/cp-tree.h old mode 100644 new mode 100755 index 26e8c0f..031bb43 --- gcc/cp/cp-tree.h +++ gcc/cp/cp-tree.h @@ -6107,6 +6107,7 @@ extern void warn_unimplemented_cilk (bool fatal); extern void build_cilk_types (void); extern void cilk_gimplify_for_stmt (tree *, tree *); extern void gimplify_cilk_for_stmt (tree *, gimple_seq *); +extern void cp_install_body_with_frame_cleanup (tree, tree); extern tree build_cilk_run (tree); extern bool cilk_valid_spawn (tree); extern void cilk_init_frame_descriptor (struct function *, bool); diff --git gcc/cp/except.c gcc/cp/except.c index 16a7c45..9a5b64a 100644 --- gcc/cp/except.c +++ gcc/cp/except.c @@ -35,9 +35,9 @@ along with GCC; see the file COPYING3. If not see static void push_eh_cleanup (tree); static tree prepare_eh_type (tree); -static tree do_begin_catch (void); +tree do_begin_catch (void); static int dtor_nothrow (tree); -static tree do_end_catch (tree); +tree do_end_catch (tree); static bool decl_is_java_type (tree decl, int err); static void initialize_handler_parm (tree, tree); static tree do_allocate_exception (tree); @@ -182,7 +182,7 @@ do_get_exception_ptr (void) /* Build up a call to __cxa_begin_catch, to tell the runtime that the exception has been handled. */ -static tree +tree do_begin_catch (void) { tree fn; @@ -230,7 +230,7 @@ dtor_nothrow (tree type) /* Build up a call to __cxa_end_catch, to destroy the exception object for the current catch block if no others are currently using it. */ -static tree +tree do_end_catch (tree type) { tree fn, cleanup; diff --git gcc/langhooks-def.h gcc/langhooks-def.h old mode 100644 new mode 100755 index 8c0af7f..3085a02 --- gcc/langhooks-def.h +++ gcc/langhooks-def.h @@ -217,9 +217,11 @@ void lhd_gimplify_cilk_for (tree *, gimple_seq *, gimple_seq *); void lhd_gimplify_cilk_sync (tree *, gimple_seq *); void lhd_elem_fn_create_fn (tree); void lhd_cilk_check_ctrl_flow (tree *); +void lhd_install_body_with_frame_cleanup (tree, tree); #define LANG_HOOKS_CILK_RECOGNIZE_SPAWN hook_bool_tree_false #define LANG_HOOKS_CILK_VALID_CTOR hook_bool_tree_false #define LANG_HOOKS_CILK_VALID_SPAWN lhd_cilk_valid_spawn +#define LANG_HOOKS_FRAME_CLEANUP lhd_install_body_with_frame_cleanup #define LANG_HOOKS_GIMPLIFY_CILK_SPAWN lhd_gimplify_cilk_spawn #define LANG_HOOKS_GIMPLIFY_CILK_FOR lhd_gimplify_cilk_for #define LANG_HOOKS_GIMPLIFY_CILK_SYNC lhd_gimplify_cilk_sync @@ -229,7 +231,8 @@ void lhd_cilk_check_ctrl_flow (tree *); LANG_HOOKS_CILK_RECOGNIZE_SPAWN, \ LANG_HOOKS_CILK_VALID_CTOR, \ LANG_HOOKS_CILK_VALID_SPAWN, \ - LANG_HOOKS_GIMPLIFY_CILK_SPAWN, \ + LANG_HOOKS_FRAME_CLEANUP, \ + LANG_HOOKS_GIMPLIFY_CILK_SPAWN, \ LANG_HOOKS_GIMPLIFY_CILK_FOR, \ LANG_HOOKS_GIMPLIFY_CILK_SYNC, \ LANG_HOOKS_CILK_CHECK_CTRL_FLOW, \ diff --git gcc/langhooks.c gcc/langhooks.c old mode 100644 new mode 100755 index bcd4284..1e53465 --- gcc/langhooks.c +++ gcc/langhooks.c @@ -730,7 +730,17 @@ lhd_elem_fn_create_fn (tree x ATTRIBUTE_UNUSED) return; } -void lhd_cilk_check_ctrl_flow (tree *x ATTRIBUTE_UNUSED) +void +lhd_cilk_check_ctrl_flow (tree *x ATTRIBUTE_UNUSED) +{ + return; +} + +/* Empty function for install that will cleanup the frame in spawn helper. */ + +void +lhd_install_body_with_frame_cleanup (tree x ATTRIBUTE_UNUSED, + tree y ATTRIBUTE_UNUSED) { return; } diff --git gcc/langhooks.h gcc/langhooks.h old mode 100644 new mode 100755 index 76c0975..c375596 --- gcc/langhooks.h +++ gcc/langhooks.h @@ -231,6 +231,7 @@ struct lang_hooks_for_cilkplus bool (*recognize_spawn) (tree); bool (*spawnable_constructor) (tree); bool (*cilk_valid_spawn) (tree); + void (*install_body_with_frame_cleanup) (tree, tree); void (*gimplify_cilk_spawn) (tree *, gimple_seq *, gimple_seq *); void (*gimplify_cilk_for) (tree *, gimple_seq *, gimple_seq *); void (*gimplify_cilk_sync) (tree *, gimple_seq *); diff --git gcc/testsuite/ChangeLog.cilkplus gcc/testsuite/ChangeLog.cilkplus old mode 100644 new mode 100755 index 47b85ba..ac965b9 --- gcc/testsuite/ChangeLog.cilkplus +++ gcc/testsuite/ChangeLog.cilkplus @@ -1,3 +1,7 @@ +2013-02-04 Balaji V. Iyer <balaji.v.i...@intel.com> + + * g++.dg/cilk-plus/cilk_keywords_test/execute/catch_exc.cc: New test. + 2013-01-22 Balaji V. Iyer <balaji.v.i...@intel.com> * gcc.dg/cilk-plus/cilk_keywords_test/errors/grainsize_error1.c: New diff --git gcc/testsuite/g++.dg/cilk-plus/cilk_keywords_test/execute/catch_exc.cc gcc/testsuite/g++.dg/cilk-plus/cilk_keywords_test/execute/catch_exc.cc new file mode 100755 index 0000000..c48d89b --- /dev/null +++ gcc/testsuite/g++.dg/cilk-plus/cilk_keywords_test/execute/catch_exc.cc @@ -0,0 +1,63 @@ +#include <assert.h> +#include <unistd.h> +#if HAVE_IO +#include <cstdio> +#include <cilk/cilk_api.h> +#endif +#include <cstdlib> + + +void func(int volatile* steal_me) +{ + while (! (*steal_me)) + { + usleep(2000); + } +#if HAVE_IO + printf("Foo executing on %d\n", __cilkrts_get_worker_number()); +#endif + throw 5; +} + +void my_test() +{ + volatile int steal_me = 0; + + try + { + _Cilk_spawn func(&steal_me); +#if HAVE_IO + printf("Continuation executing on %d\n", + __cilkrts_get_worker_number()); +#endif + steal_me = 1; + _Cilk_sync; + goto bad; + } + + catch (int x) + { +#if HAVE_IO + printf("We caught x = %d\n", x); +#endif + assert(x == 5); + } + if (0) + { + bad: +#if HAVE_IO + printf("We should not be here!\n"); +#endif + assert(0); + } +} + + +int main() +{ + my_test(); +#if HAVE_IO + printf("PASSED\n"); +#endif + return 0; +}