From e0ca27c53103d532b51a61679b5d4c13d35a09d0 Mon Sep 17 00:00:00 2001 From: Tom de Vries Date: Mon, 30 Nov 2015 16:34:26 +0000 Subject: Handle BUILT_IN_GOMP_PARALLEL in ipa-pta 2015-11-30 Tom de Vries PR tree-optimization/46032 * tree-ssa-structalias.c (find_func_aliases_for_call_arg): New function, factored out of ... (find_func_aliases_for_call): ... here. (find_func_aliases_for_builtin_call, find_func_clobbers): Handle BUILT_IN_GOMP_PARALLEL. (ipa_pta_execute): Same. Handle node->parallelized_function as a local function. * gcc.dg/pr46032.c: New test. * testsuite/libgomp.c/pr46032.c: New test. From-SVN: r231076 --- gcc/tree-ssa-structalias.c | 71 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 13 deletions(-) (limited to 'gcc/tree-ssa-structalias.c') diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index f24ebeba815..7f4a8ad60e4 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -4139,6 +4139,24 @@ get_fi_for_callee (gcall *call) return get_vi_for_tree (fn); } +/* Create constraints for assigning call argument ARG to the incoming parameter + INDEX of function FI. */ + +static void +find_func_aliases_for_call_arg (varinfo_t fi, unsigned index, tree arg) +{ + struct constraint_expr lhs; + lhs = get_function_part_constraint (fi, fi_parm_base + index); + + auto_vec rhsc; + get_constraint_for_rhs (arg, &rhsc); + + unsigned j; + struct constraint_expr *rhsp; + FOR_EACH_VEC_ELT (rhsc, j, rhsp) + process_constraint (new_constraint (lhs, *rhsp)); +} + /* Create constraints for the builtin call T. Return true if the call was handled, otherwise false. */ @@ -4488,6 +4506,25 @@ find_func_aliases_for_builtin_call (struct function *fn, gcall *t) } return true; } + case BUILT_IN_GOMP_PARALLEL: + { + /* Handle __builtin_GOMP_parallel (fn, data, num_threads, flags) as + fn (data). */ + if (in_ipa_mode) + { + tree fnarg = gimple_call_arg (t, 0); + gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR); + tree fndecl = TREE_OPERAND (fnarg, 0); + tree arg = gimple_call_arg (t, 1); + gcc_assert (TREE_CODE (arg) == ADDR_EXPR); + + varinfo_t fi = get_vi_for_tree (fndecl); + find_func_aliases_for_call_arg (fi, 0, arg); + return true; + } + /* Else fallthru to generic call handling. */ + break; + } /* printf-style functions may have hooks to set pointers to point to somewhere into the generated string. Leave them for a later exercise... */ @@ -4546,18 +4583,8 @@ find_func_aliases_for_call (struct function *fn, gcall *t) parameters of the function. */ for (j = 0; j < gimple_call_num_args (t); j++) { - struct constraint_expr lhs ; - struct constraint_expr *rhsp; tree arg = gimple_call_arg (t, j); - - get_constraint_for_rhs (arg, &rhsc); - lhs = get_function_part_constraint (fi, fi_parm_base + j); - while (rhsc.length () != 0) - { - rhsp = &rhsc.last (); - process_constraint (new_constraint (lhs, *rhsp)); - rhsc.pop (); - } + find_func_aliases_for_call_arg (fi, j, arg); } /* If we are returning a value, assign it to the result. */ @@ -5036,6 +5063,8 @@ find_func_clobbers (struct function *fn, gimple *origt) case BUILT_IN_VA_START: case BUILT_IN_VA_END: return; + case BUILT_IN_GOMP_PARALLEL: + return; /* printf-style functions may have hooks to set pointers to point to somewhere into the generated string. Leave them for a later exercise... */ @@ -7345,6 +7374,18 @@ ipa_pta_execute (void) gcc_assert (!node->clone_of); + /* When parallelizing a code region, we split the region off into a + separate function, to be run by several threads in parallel. So for a + function foo, we split off a region into a function + foo._0 (void *foodata), and replace the region with some variant of a + function call run_on_threads (&foo._0, data). The '&foo._0' sets the + address_taken bit for function foo._0, which would make it non-local. + But for the purpose of ipa-pta, we can regard the run_on_threads call + as a local call foo._0 (data), so we ignore address_taken on nodes + with parallelized_function set. */ + bool node_address_taken = (node->address_taken + && !node->parallelized_function); + /* For externally visible or attribute used annotated functions use local constraints for their arguments. For local functions we see all callers and thus do not need initial @@ -7352,7 +7393,7 @@ ipa_pta_execute (void) bool nonlocal_p = (node->used_from_other_partition || node->externally_visible || node->force_output - || node->address_taken); + || node_address_taken); vi = create_function_info_for (node->decl, alias_get_name (node->decl), false, @@ -7504,7 +7545,11 @@ ipa_pta_execute (void) continue; /* Handle direct calls to functions with body. */ - decl = gimple_call_fndecl (stmt); + if (gimple_call_builtin_p (stmt, BUILT_IN_GOMP_PARALLEL)) + decl = TREE_OPERAND (gimple_call_arg (stmt, 0), 0); + else + decl = gimple_call_fndecl (stmt); + if (decl && (fi = lookup_vi_for_tree (decl)) && fi->is_fn_info) -- cgit v1.2.3