From: Martin Jambor Date: Mon, 11 Jan 2016 09:59:48 +0000 (+0100) Subject: [PR 66616] Check for thunks when adding extra constants to clones X-Git-Tag: releases/gcc-4.9.4~406 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9a1efe82e4729d7513cd458232a005a5a91212ad;p=thirdparty%2Fgcc.git [PR 66616] Check for thunks when adding extra constants to clones 2016-01-11 Martin Jambor PR ipa/66616 * ipa-cp.c (propagate_constants_accross_call): Move thuk check... (call_passes_through_thunk_p): ...here. (find_more_scalar_values_for_callers_subset): Perform thunk checks like propagate_constants_accross_call does. * cgraphclones.c (duplicate_thunk_for_node): Copy can_change_signature flag from the node to the new flag. testsuite/ * g++.dg/ipa/pr66616.C: New test. From-SVN: r232213 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ef95ce489ced..319015c23bb6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-01-11 Martin Jambor + + PR ipa/66616 + * ipa-cp.c (propagate_constants_accross_call): Move thuk check... + (call_passes_through_thunk_p): ...here. + (find_more_scalar_values_for_callers_subset): Perform thunk checks + like propagate_constants_accross_call does. + * cgraphclones.c (duplicate_thunk_for_node): Copy can_change_signature + flag from the node to the new flag. + 2016-01-08 Martin Jambor Backport from mainline diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index e310b1ce801d..11bcc380501c 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -367,6 +367,7 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node) new_thunk = cgraph_create_node (new_decl); set_new_clone_decl_and_node_flags (new_thunk); new_thunk->definition = true; + new_thunk->local.can_change_signature = node->local.can_change_signature; new_thunk->thunk = thunk->thunk; new_thunk->unique_name = in_lto_p; new_thunk->former_clone_of = thunk->decl; diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index a6818ba8da19..5ea4f9b9b517 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1411,6 +1411,18 @@ propagate_aggs_accross_jump_function (struct cgraph_edge *cs, return ret; } +/* Return true if on the way cfrom CS->caller to the final (non-alias and + non-thunk) destination, the call passes through a thunk. */ + +static bool +call_passes_through_thunk_p (struct cgraph_edge *cs) +{ + struct cgraph_node *alias_or_thunk = cs->callee; + while (alias_or_thunk->alias) + alias_or_thunk = cgraph_alias_target (alias_or_thunk); + return alias_or_thunk->thunk.thunk_p; +} + /* Propagate constants from the caller to the callee of CS. INFO describes the caller. */ @@ -1419,7 +1431,7 @@ propagate_constants_accross_call (struct cgraph_edge *cs) { struct ipa_node_params *callee_info; enum availability availability; - struct cgraph_node *callee, *alias_or_thunk; + struct cgraph_node *callee; struct ipa_edge_args *args; bool ret = false; int i, args_count, parms_count; @@ -1439,10 +1451,7 @@ propagate_constants_accross_call (struct cgraph_edge *cs) /* If this call goes through a thunk we must not propagate to the first (0th) parameter. However, we might need to uncover a thunk from below a series of aliases first. */ - alias_or_thunk = cs->callee; - while (alias_or_thunk->alias) - alias_or_thunk = cgraph_alias_target (alias_or_thunk); - if (alias_or_thunk->thunk.thunk_p) + if (call_passes_through_thunk_p (cs)) { ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, 0)); @@ -2837,7 +2846,9 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node, struct ipa_jump_func *jump_func; tree t; - if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs))) + if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) + || (i == 0 + && call_passes_through_thunk_p (cs))) { newval = NULL_TREE; break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d1637d7ea7e6..cce93ed356c8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-11 Martin Jambor + + PR ipa/66616 + * g++.dg/ipa/pr66616.C: New test. + 2016-01-08 Martin Jambor Backport from mainline diff --git a/gcc/testsuite/g++.dg/ipa/pr66616.C b/gcc/testsuite/g++.dg/ipa/pr66616.C new file mode 100644 index 000000000000..440ea6c6bfc1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr66616.C @@ -0,0 +1,54 @@ +// { dg-do run } +// { dg-options "-O2 -fipa-cp-clone" } + +struct Distraction +{ + char fc[8]; + virtual Distraction * return_self () + { return this; } +}; + +static int go; + +struct A; + +struct A +{ + int fi; + + A () : fi(0) {} + A (int pi) : fi (pi) {} + virtual void foo (int p) = 0; +}; + +struct B; + +struct B : public Distraction, A +{ + B () : Distraction(), A() { } + B (int pi) : Distraction (), A (pi) {} + virtual void foo (int p) + { + int o = fi; + for (int i = 0; i < p; i++) + o += i + i * i; + go = o; + } +}; + +struct B gb2 (2); + +extern "C" void abort (void); + +int +main (void) +{ + for (int i = 0; i < 2; i++) + { + struct A *p = &gb2; + p->foo (0); + if (go != 2) + abort (); + } + return 0; +}