diff options
author | Martin Jambor <mjambor@suse.cz> | 2012-11-21 18:13:48 +0100 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2012-11-21 18:13:48 +0100 |
commit | eb20b7788fe0a9f43657668207677833e3881741 (patch) | |
tree | 19097a42aba8e5dd844fbeecb52d7e94b245e809 | |
parent | 7e9f2b6e35b47373730c340471afa1734e197b60 (diff) | |
download | gcc-eb20b7788fe0a9f43657668207677833e3881741.zip gcc-eb20b7788fe0a9f43657668207677833e3881741.tar.gz gcc-eb20b7788fe0a9f43657668207677833e3881741.tar.bz2 |
ipa-prop.h (struct ipa_node_params): Rename clone_for_all_contexts to do_clone_for_all_contexts.
2012-11-21 Martin Jambor <mjambor@suse.cz>
* ipa-prop.h (struct ipa_node_params): Rename clone_for_all_contexts to
do_clone_for_all_contexts. Update all uses. New flag
is_all_contexts_clone.
* ipa-cp.c (cgraph_edge_brings_value_p): Also consider the case when cs
leads to the clone for all contexts.
(perhaps_add_new_callers): Likewise.
(decide_whether_version_node): Remove bogus !plats->aggs test. Set
is_all_contexts_clone when cloning for all contexts.
* testsuite/gcc.dg/ipa/ipcp-agg-7.c: New test.
* testsuite/gcc.dg/ipa/ipcp-agg-8.c: Likewise.
From-SVN: r193701
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/ipa-cp.c | 26 | ||||
-rw-r--r-- | gcc/ipa-prop.h | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/ipcp-agg-7.c | 54 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/ipcp-agg-8.c | 52 |
6 files changed, 140 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 58f69d1..7853c37 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,16 @@ 2012-11-21 Martin Jambor <mjambor@suse.cz> + * ipa-prop.h (struct ipa_node_params): Rename clone_for_all_contexts to + do_clone_for_all_contexts. Update all uses. New flag + is_all_contexts_clone. + * ipa-cp.c (cgraph_edge_brings_value_p): Also consider the case when cs + leads to the clone for all contexts. + (perhaps_add_new_callers): Likewise. + (decide_whether_version_node): Remove bogus !plats->aggs test. Set + is_all_contexts_clone when cloning for all contexts. + +2012-11-21 Martin Jambor <mjambor@suse.cz> + PR tree-optimization/55260 * ipa-cp.c (intersect_aggregates_with_edge): New function. (find_aggregate_values_for_callers_subset): Part moved to the function diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 16cf990..12e199d 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1828,7 +1828,7 @@ estimate_local_effects (struct cgraph_node *node) if (size <= 0 || cgraph_will_be_removed_from_program_if_no_direct_calls (node)) { - info->clone_for_all_contexts = true; + info->do_clone_for_all_contexts = true; base_time = time; if (dump_file) @@ -1841,7 +1841,7 @@ estimate_local_effects (struct cgraph_node *node) { if (size + overall_size <= max_new_size) { - info->clone_for_all_contexts = true; + info->do_clone_for_all_contexts = true; base_time = time; overall_size += size; @@ -2312,8 +2312,9 @@ cgraph_edge_brings_value_p (struct cgraph_edge *cs, struct ipcp_value_source *src) { struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); + struct ipa_node_params *dst_info = IPA_NODE_REF (cs->callee); - if (IPA_NODE_REF (cs->callee)->ipcp_orig_node + if ((dst_info->ipcp_orig_node && !dst_info->is_all_contexts_clone) || caller_info->node_dead) return false; if (!src->val) @@ -3175,8 +3176,9 @@ perhaps_add_new_callers (struct cgraph_node *node, struct ipcp_value *val) while (cs) { enum availability availability; - - if (cgraph_function_node (cs->callee, &availability) == node + struct cgraph_node *dst = cgraph_function_node (cs->callee, + &availability); + if ((dst == node || IPA_NODE_REF (dst)->is_all_contexts_clone) && availability > AVAIL_OVERWRITABLE && cgraph_edge_brings_value_p (cs, src)) { @@ -3335,8 +3337,8 @@ decide_whether_version_node (struct cgraph_node *node) cgraph_node_name (node), node->uid); gather_context_independent_values (info, &known_csts, &known_binfos, - info->clone_for_all_contexts ? &known_aggs - : NULL, NULL); + info->do_clone_for_all_contexts ? &known_aggs + : NULL, NULL); for (i = 0; i < count ;i++) { @@ -3351,7 +3353,7 @@ decide_whether_version_node (struct cgraph_node *node) ret |= decide_about_value (node, i, -1, val, known_csts, known_binfos); - if (!plats->aggs_bottom || !plats->aggs) + if (!plats->aggs_bottom) { struct ipcp_agg_lattice *aglat; struct ipcp_value *val; @@ -3368,8 +3370,9 @@ decide_whether_version_node (struct cgraph_node *node) info = IPA_NODE_REF (node); } - if (info->clone_for_all_contexts) + if (info->do_clone_for_all_contexts) { + struct cgraph_node *clone; vec<cgraph_edge_p> callers; if (dump_file) @@ -3379,11 +3382,12 @@ decide_whether_version_node (struct cgraph_node *node) callers = collect_callers_of_node (node); move_binfos_to_values (known_csts, known_binfos); - create_specialized_node (node, known_csts, + clone = create_specialized_node (node, known_csts, known_aggs_to_agg_replacement_list (known_aggs), callers); info = IPA_NODE_REF (node); - info->clone_for_all_contexts = false; + info->do_clone_for_all_contexts = false; + IPA_NODE_REF (clone)->is_all_contexts_clone = true; ret = true; } else diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 1d0a992..95442dc 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -328,7 +328,9 @@ struct ipa_node_params unsigned node_enqueued : 1; /* Whether we should create a specialized version based on values that are known to be constant in all contexts. */ - unsigned clone_for_all_contexts : 1; + unsigned do_clone_for_all_contexts : 1; + /* Set if this is an IPA-CP clone for all contexts. */ + unsigned is_all_contexts_clone : 1; /* Node has been completely replaced by clones and will be removed after ipa-cp is finished. */ unsigned node_dead : 1; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5def603..3a12c81 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2012-11-21 Martin Jambor <mjambor@suse.cz> + * gcc.dg/ipa/ipcp-agg-7.c: New test. + * gcc.dg/ipa/ipcp-agg-8.c: Likewise. + +2012-11-21 Martin Jambor <mjambor@suse.cz> + PR tree-optimization/55260 * g++.dg/torture/pr55260-2.C: New test. diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-agg-7.c b/gcc/testsuite/gcc.dg/ipa/ipcp-agg-7.c new file mode 100644 index 0000000..e85ca1a --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipcp-agg-7.c @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-ipa-sra -fdump-ipa-cp-details -fdump-tree-optimized-slim" } */ +/* { dg-add-options bind_pic_locally } */ + +struct S +{ + int a, b, c; +}; + +void *blah(int, void *); + +static void __attribute__ ((noinline)) foo (int x, int z, struct S *p); + +static void __attribute__ ((noinline)) +bar (int x, int z, struct S *p) +{ + foo (z, x, p); +} + +static void __attribute__ ((noinline)) +foo (int x, int z, struct S *p) +{ + int i, c = p->c; + int b = p->b - z; + void *v = (void *) p; + + if (z) + { + z--; + bar (z, x, p); + } + for (i = 0; i< c; i++) + v = blah(b + x + i, v); +} + +void +entry (int c) +{ + struct S s; + int i; + + for (i = 0; i<c; i++) + { + s.a = c; + s.b = 64; + s.c = 32; + foo (4, i, &s); + } +} +/* { dg-final { scan-ipa-dump-times "Clone of bar" 1 "cp" } } */ +/* { dg-final { scan-ipa-dump-times "Clone of foo" 1 "cp" } } */ +/* { dg-final { cleanup-ipa-dump "cp" } } */ +/* { dg-final { scan-tree-dump-not "->c;" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-agg-8.c b/gcc/testsuite/gcc.dg/ipa/ipcp-agg-8.c new file mode 100644 index 0000000..5014ffd --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipcp-agg-8.c @@ -0,0 +1,52 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-ipa-sra -fdump-tree-optimized-slim" } */ +/* { dg-add-options bind_pic_locally } */ + +struct S +{ + int a, b, c; +}; + +void *blah(int, void *); + +static void __attribute__ ((noinline)) foo (int x, int z, struct S *p); + +static void __attribute__ ((noinline)) +bar (int x, int z, struct S *p) +{ + p->b = 0; + foo (z, x, p); +} + +static void __attribute__ ((noinline)) +foo (int x, int z, struct S *p) +{ + int i, c = p->c; + int b = p->b - z; + void *v = (void *) p; + + if (z) + { + z--; + bar (z, x, p); + } + for (i = 0; i< c; i++) + v = blah(b + x + i, v); +} + +void +entry (int c) +{ + struct S s; + int i; + + for (i = 0; i<c; i++) + { + s.a = c; + s.b = 64; + s.c = 32; + foo (4, i, &s); + } +} +/* { dg-final { scan-tree-dump "->b;" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ |