re PR ipa/70760 (wrong generated code for std::make_unique with -fipa-pta)
2016-04-27 Richard Biener <rguenther@suse.de> PR ipa/70760 * tree-ssa-structalias.c (find_func_aliases_for_call): Use aggregate_value_p to determine if a function result is returned by reference. (ipa_pta_execute): Functions having their address taken are not automatically nonlocal. * g++.dg/ipa/ipa-pta-2.C: New testcase. * gcc.dg/ipa/ipa-pta-1.c: Adjust. From-SVN: r235511
This commit is contained in:
parent
b3b2bae4e2
commit
72ed2b9c76
@ -1,3 +1,12 @@
|
||||
2016-04-27 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR ipa/70760
|
||||
* tree-ssa-structalias.c (find_func_aliases_for_call): Use
|
||||
aggregate_value_p to determine if a function result is
|
||||
returned by reference.
|
||||
(ipa_pta_execute): Functions having their address taken are
|
||||
not automatically nonlocal.
|
||||
|
||||
2016-04-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR sanitizer/70683
|
||||
|
@ -1,3 +1,9 @@
|
||||
2016-04-27 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR ipa/70760
|
||||
* g++.dg/ipa/ipa-pta-2.C: New testcase.
|
||||
* gcc.dg/ipa/ipa-pta-1.c: Adjust.
|
||||
|
||||
2016-04-27 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* g++.dg/cpp0x/constexpr-recursion3.C: New.
|
||||
|
37
gcc/testsuite/g++.dg/ipa/ipa-pta-2.C
Normal file
37
gcc/testsuite/g++.dg/ipa/ipa-pta-2.C
Normal file
@ -0,0 +1,37 @@
|
||||
// { dg-do run }
|
||||
// { dg-options "-O2 -fipa-pta" }
|
||||
|
||||
extern "C" void abort (void);
|
||||
|
||||
struct Y { ~Y(); int i; };
|
||||
|
||||
Y::~Y () {}
|
||||
|
||||
static Y __attribute__((noinline)) foo ()
|
||||
{
|
||||
Y res;
|
||||
res.i = 3;
|
||||
return res;
|
||||
}
|
||||
|
||||
static Y __attribute__((noinline)) bar ()
|
||||
{
|
||||
Y res;
|
||||
res.i = 42;
|
||||
return res;
|
||||
}
|
||||
|
||||
static Y (*fn) ();
|
||||
|
||||
int a;
|
||||
int main()
|
||||
{
|
||||
if (a)
|
||||
fn = foo;
|
||||
else
|
||||
fn = bar;
|
||||
Y res = fn ();
|
||||
if (res.i != 42)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
@ -40,13 +40,10 @@ int main()
|
||||
}
|
||||
|
||||
/* IPA PTA needs to handle indirect calls properly. Verify that
|
||||
both bar and foo get a (and only a) in their arguments points-to sets.
|
||||
??? As bar and foo have their address taken there might be callers
|
||||
not seen by IPA PTA (if the address escapes the unit which we only compute
|
||||
during IPA PTA...). Thus the solution also includes NONLOCAL. */
|
||||
both bar and foo get a (and only a) in their arguments points-to sets. */
|
||||
|
||||
/* { dg-final { scan-ipa-dump "fn_1 = { bar foo }" "pta2" } } */
|
||||
/* { dg-final { scan-ipa-dump "bar.arg0 = { NONLOCAL a }" "pta2" } } */
|
||||
/* { dg-final { scan-ipa-dump "bar.arg1 = { NONLOCAL a }" "pta2" } } */
|
||||
/* { dg-final { scan-ipa-dump "foo.arg0 = { NONLOCAL a }" "pta2" } } */
|
||||
/* { dg-final { scan-ipa-dump "foo.arg1 = { NONLOCAL a }" "pta2" } } */
|
||||
/* { dg-final { scan-ipa-dump "bar.arg0 = { a }" "pta2" } } */
|
||||
/* { dg-final { scan-ipa-dump "bar.arg1 = { a }" "pta2" } } */
|
||||
/* { dg-final { scan-ipa-dump "foo.arg0 = { a }" "pta2" } } */
|
||||
/* { dg-final { scan-ipa-dump "foo.arg1 = { a }" "pta2" } } */
|
||||
|
@ -4641,12 +4641,11 @@ find_func_aliases_for_call (struct function *fn, gcall *t)
|
||||
auto_vec<ce_s, 2> lhsc;
|
||||
struct constraint_expr rhs;
|
||||
struct constraint_expr *lhsp;
|
||||
bool aggr_p = aggregate_value_p (lhsop, gimple_call_fntype (t));
|
||||
|
||||
get_constraint_for (lhsop, &lhsc);
|
||||
rhs = get_function_part_constraint (fi, fi_result);
|
||||
if (fndecl
|
||||
&& DECL_RESULT (fndecl)
|
||||
&& DECL_BY_REFERENCE (DECL_RESULT (fndecl)))
|
||||
if (aggr_p)
|
||||
{
|
||||
auto_vec<ce_s, 2> tem;
|
||||
tem.quick_push (rhs);
|
||||
@ -4656,22 +4655,19 @@ find_func_aliases_for_call (struct function *fn, gcall *t)
|
||||
}
|
||||
FOR_EACH_VEC_ELT (lhsc, j, lhsp)
|
||||
process_constraint (new_constraint (*lhsp, rhs));
|
||||
}
|
||||
|
||||
/* If we pass the result decl by reference, honor that. */
|
||||
if (lhsop
|
||||
&& fndecl
|
||||
&& DECL_RESULT (fndecl)
|
||||
&& DECL_BY_REFERENCE (DECL_RESULT (fndecl)))
|
||||
{
|
||||
struct constraint_expr lhs;
|
||||
struct constraint_expr *rhsp;
|
||||
/* If we pass the result decl by reference, honor that. */
|
||||
if (aggr_p)
|
||||
{
|
||||
struct constraint_expr lhs;
|
||||
struct constraint_expr *rhsp;
|
||||
|
||||
get_constraint_for_address_of (lhsop, &rhsc);
|
||||
lhs = get_function_part_constraint (fi, fi_result);
|
||||
FOR_EACH_VEC_ELT (rhsc, j, rhsp)
|
||||
process_constraint (new_constraint (lhs, *rhsp));
|
||||
rhsc.truncate (0);
|
||||
get_constraint_for_address_of (lhsop, &rhsc);
|
||||
lhs = get_function_part_constraint (fi, fi_result);
|
||||
FOR_EACH_VEC_ELT (rhsc, j, rhsp)
|
||||
process_constraint (new_constraint (lhs, *rhsp));
|
||||
rhsc.truncate (0);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we use a static chain, pass it along. */
|
||||
@ -7686,30 +7682,13 @@ 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.
|
||||
Note: this is only safe, if foo and foo._0 are in the same lto
|
||||
partition. */
|
||||
bool node_address_taken = ((node->parallelized_function
|
||||
&& !node->used_from_other_partition)
|
||||
? false
|
||||
: node->address_taken);
|
||||
|
||||
/* 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
|
||||
constraints for parameters. */
|
||||
bool nonlocal_p = (node->used_from_other_partition
|
||||
|| node->externally_visible
|
||||
|| node->force_output
|
||||
|| node_address_taken);
|
||||
|| node->force_output);
|
||||
node->call_for_symbol_thunks_and_aliases (refered_from_nonlocal_fn,
|
||||
&nonlocal_p, true);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user