diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d9f6157cb48..74a81618ce2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2008-06-19 Jakub Jelinek + + PR c++/36523 + * cgraphunit.c (cgraph_process_new_functions): Don't clear + node->needed and node->reachable. + * cgraphbuild.c (record_reference): Handle OMP_PARALLEL and OMP_TASK. + * omp-low.c (delete_omp_context): Call finalize_task_copyfn. + (expand_task_call): Don't call expand_task_copyfn. + (expand_task_copyfn): Renamed to... + (finalize_task_copyfn): ... this. + 2008-06-19 Jan Hubicka * builtins.c (expand_builtin_nonlocal_goto): Stabilize r_sp before diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c index e37ca86f51d..19e198344b6 100644 --- a/gcc/cgraphbuild.c +++ b/gcc/cgraphbuild.c @@ -62,6 +62,24 @@ record_reference (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) } break; + case OMP_PARALLEL: + if (flag_unit_at_a_time) + { + if (OMP_PARALLEL_FN (*tp)) + cgraph_mark_needed_node (cgraph_node (OMP_PARALLEL_FN (*tp))); + } + break; + + case OMP_TASK: + if (flag_unit_at_a_time) + { + if (OMP_TASK_FN (*tp)) + cgraph_mark_needed_node (cgraph_node (OMP_TASK_FN (*tp))); + if (OMP_TASK_COPYFN (*tp)) + cgraph_mark_needed_node (cgraph_node (OMP_TASK_COPYFN (*tp))); + } + break; + default: /* Save some cycles by not walking types and declaration as we won't find anything useful there anyway. */ diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 6b00bd59c41..2dcccc1bd93 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -443,7 +443,6 @@ cgraph_process_new_functions (void) it into reachable functions list. */ node->next_needed = NULL; - node->needed = node->reachable = false; cgraph_finalize_function (fndecl, false); cgraph_mark_reachable_node (node); output = true; diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 09b7260a66e..db5f8584405 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -1188,6 +1188,37 @@ new_omp_context (tree stmt, omp_context *outer_ctx) return ctx; } +static void maybe_catch_exception (tree *stmt_p); + +/* Finalize task copyfn. */ + +static void +finalize_task_copyfn (tree task_stmt) +{ + struct function *child_cfun; + tree child_fn, old_fn; + + child_fn = OMP_TASK_COPYFN (task_stmt); + if (child_fn == NULL_TREE) + return; + + child_cfun = DECL_STRUCT_FUNCTION (child_fn); + + /* Inform the callgraph about the new function. */ + DECL_STRUCT_FUNCTION (child_fn)->curr_properties + = cfun->curr_properties; + + old_fn = current_function_decl; + push_cfun (child_cfun); + current_function_decl = child_fn; + gimplify_body (&DECL_SAVED_TREE (child_fn), child_fn, false); + maybe_catch_exception (&BIND_EXPR_BODY (DECL_SAVED_TREE (child_fn))); + pop_cfun (); + current_function_decl = old_fn; + + cgraph_add_new_function (child_fn, false); +} + /* Destroy a omp_context data structures. Called through the splay tree value delete callback. */ @@ -1218,6 +1249,9 @@ delete_omp_context (splay_tree_value value) DECL_ABSTRACT_ORIGIN (t) = NULL; } + if (is_task_ctx (ctx)) + finalize_task_copyfn (ctx->stmt); + XDELETE (ctx); } @@ -2882,35 +2916,6 @@ expand_parallel_call (struct omp_region *region, basic_block bb, } -static void maybe_catch_exception (tree *stmt_p); - - -/* Finalize task copyfn. */ - -static void -expand_task_copyfn (tree task_stmt) -{ - struct function *child_cfun; - tree child_fn, old_fn; - - child_fn = OMP_TASK_COPYFN (task_stmt); - child_cfun = DECL_STRUCT_FUNCTION (child_fn); - - /* Inform the callgraph about the new function. */ - DECL_STRUCT_FUNCTION (child_fn)->curr_properties - = cfun->curr_properties; - - old_fn = current_function_decl; - push_cfun (child_cfun); - current_function_decl = child_fn; - gimplify_body (&DECL_SAVED_TREE (child_fn), child_fn, false); - maybe_catch_exception (&BIND_EXPR_BODY (DECL_SAVED_TREE (child_fn))); - pop_cfun (); - current_function_decl = old_fn; - - cgraph_add_new_function (child_fn, false); -} - /* Build the function call to GOMP_task to actually generate the task operation. BB is the block where to insert the code. */ @@ -2922,9 +2927,6 @@ expand_task_call (basic_block bb, tree entry_stmt) clauses = OMP_TASK_CLAUSES (entry_stmt); - if (OMP_TASK_COPYFN (entry_stmt)) - expand_task_copyfn (entry_stmt); - c = find_omp_clause (clauses, OMP_CLAUSE_IF); if (c) cond = gimple_boolify (OMP_CLAUSE_IF_EXPR (c)); diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 784d59f933d..ed27454354e 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -2,6 +2,9 @@ * testsuite/libgomp.c/nqueens-1.c: New test. + PR c++/36523 + * testsuite/libgomp.c++/task-7.C: New function. + 2008-06-17 Ralf Wildenhues * configure: Regenerate. diff --git a/libgomp/testsuite/libgomp.c++/task-7.C b/libgomp/testsuite/libgomp.c++/task-7.C new file mode 100644 index 00000000000..e9828cd2c4d --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/task-7.C @@ -0,0 +1,18 @@ +// PR c++/36523 +// { dg-do run } + +template +struct A +{ + A() { } + A(const A&) { } + void foo() { } +}; + +int main() +{ + A a; + #pragma omp task firstprivate (a) + a.foo(); + return 0; +}