aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2012-11-21 18:13:48 +0100
committerMartin Jambor <jamborm@gcc.gnu.org>2012-11-21 18:13:48 +0100
commiteb20b7788fe0a9f43657668207677833e3881741 (patch)
tree19097a42aba8e5dd844fbeecb52d7e94b245e809
parent7e9f2b6e35b47373730c340471afa1734e197b60 (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--gcc/ipa-cp.c26
-rw-r--r--gcc/ipa-prop.h4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-agg-7.c54
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-agg-8.c52
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" } } */