Handle BUILT_IN_GOMP_PARALLEL in ipa-pta

2015-11-30  Tom de Vries  <tom@codesourcery.com>

	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
This commit is contained in:
Tom de Vries 2015-11-30 16:34:26 +00:00 committed by Tom de Vries
parent 7b90c63a28
commit e0ca27c531
6 changed files with 170 additions and 13 deletions

View File

@ -1,3 +1,14 @@
2015-11-30 Tom de Vries <tom@codesourcery.com>
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.
2015-11-30 Jakub Jelinek <jakub@redhat.com> 2015-11-30 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/68501 PR tree-optimization/68501

View File

@ -1,3 +1,8 @@
2015-11-30 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/46032
* gcc.dg/pr46032.c: New test.
2015-11-30 Richard Biener <rguenther@suse.de> 2015-11-30 Richard Biener <rguenther@suse.de>
PR tree-optimization/68592 PR tree-optimization/68592

View File

@ -0,0 +1,47 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fopenmp -ftree-vectorize -std=c99 -fipa-pta -fdump-tree-vect-all" } */
extern void abort (void);
#define nEvents 1000
static void __attribute__((noinline, noclone, optimize("-fno-tree-vectorize")))
init (unsigned *results, unsigned *pData)
{
unsigned int i;
for (i = 0; i < nEvents; ++i)
pData[i] = i % 3;
}
static void __attribute__((noinline, noclone, optimize("-fno-tree-vectorize")))
check (unsigned *results)
{
unsigned sum = 0;
for (int idx = 0; idx < (int)nEvents; idx++)
sum += results[idx];
if (sum != 1998)
abort ();
}
int
main (void)
{
unsigned results[nEvents];
unsigned pData[nEvents];
unsigned coeff = 2;
init (&results[0], &pData[0]);
#pragma omp parallel for
for (int idx = 0; idx < (int)nEvents; idx++)
results[idx] = coeff * pData[idx];
check (&results[0]);
return 0;
}
/* { dg-final { scan-tree-dump-times "note: vectorized 1 loop" 1 "vect" } } */
/* { dg-final { scan-tree-dump-not "versioning for alias required" "vect" } } */

View File

@ -4139,6 +4139,24 @@ get_fi_for_callee (gcall *call)
return get_vi_for_tree (fn); 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<ce_s, 2> 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 /* Create constraints for the builtin call T. Return true if the call
was handled, otherwise false. */ was handled, otherwise false. */
@ -4488,6 +4506,25 @@ find_func_aliases_for_builtin_call (struct function *fn, gcall *t)
} }
return true; 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 /* printf-style functions may have hooks to set pointers to
point to somewhere into the generated string. Leave them point to somewhere into the generated string. Leave them
for a later exercise... */ for a later exercise... */
@ -4546,18 +4583,8 @@ find_func_aliases_for_call (struct function *fn, gcall *t)
parameters of the function. */ parameters of the function. */
for (j = 0; j < gimple_call_num_args (t); j++) 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); tree arg = gimple_call_arg (t, j);
find_func_aliases_for_call_arg (fi, j, arg);
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 ();
}
} }
/* If we are returning a value, assign it to the result. */ /* 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_START:
case BUILT_IN_VA_END: case BUILT_IN_VA_END:
return; return;
case BUILT_IN_GOMP_PARALLEL:
return;
/* printf-style functions may have hooks to set pointers to /* printf-style functions may have hooks to set pointers to
point to somewhere into the generated string. Leave them point to somewhere into the generated string. Leave them
for a later exercise... */ for a later exercise... */
@ -7345,6 +7374,18 @@ ipa_pta_execute (void)
gcc_assert (!node->clone_of); 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 /* For externally visible or attribute used annotated functions use
local constraints for their arguments. local constraints for their arguments.
For local functions we see all callers and thus do not need initial 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 bool nonlocal_p = (node->used_from_other_partition
|| node->externally_visible || node->externally_visible
|| node->force_output || node->force_output
|| node->address_taken); || node_address_taken);
vi = create_function_info_for (node->decl, vi = create_function_info_for (node->decl,
alias_get_name (node->decl), false, alias_get_name (node->decl), false,
@ -7504,7 +7545,11 @@ ipa_pta_execute (void)
continue; continue;
/* Handle direct calls to functions with body. */ /* 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 if (decl
&& (fi = lookup_vi_for_tree (decl)) && (fi = lookup_vi_for_tree (decl))
&& fi->is_fn_info) && fi->is_fn_info)

View File

@ -1,3 +1,8 @@
2015-11-30 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/46032
* testsuite/libgomp.c/pr46032.c: New test.
2015-11-27 Jakub Jelinek <jakub@redhat.com> 2015-11-27 Jakub Jelinek <jakub@redhat.com>
PR libgomp/68579 PR libgomp/68579

View File

@ -0,0 +1,44 @@
/* { dg-do run } */
/* { dg-options "-O2 -ftree-vectorize -std=c99 -fipa-pta" } */
extern void abort (void);
#define nEvents 1000
static void __attribute__((noinline, noclone, optimize("-fno-tree-vectorize")))
init (unsigned *results, unsigned *pData)
{
unsigned int i;
for (i = 0; i < nEvents; ++i)
pData[i] = i % 3;
}
static void __attribute__((noinline, noclone, optimize("-fno-tree-vectorize")))
check (unsigned *results)
{
unsigned sum = 0;
for (int idx = 0; idx < (int)nEvents; idx++)
sum += results[idx];
if (sum != 1998)
abort ();
}
int
main (void)
{
unsigned results[nEvents];
unsigned pData[nEvents];
unsigned coeff = 2;
init (&results[0], &pData[0]);
#pragma omp parallel for
for (int idx = 0; idx < (int)nEvents; idx++)
results[idx] = coeff * pData[idx];
check (&results[0]);
return 0;
}