aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2013-03-25 17:42:41 +0100
committerMartin Jambor <jamborm@gcc.gnu.org>2013-03-25 17:42:41 +0100
commit162712de00d6e234083e63c00b7a0570aa13a5e3 (patch)
tree45836f6d246d4f771b90aac808750e183ca4063b /gcc
parentcadddfdda2c4a16e7fdd5f0d8d02b465caad2ad5 (diff)
downloadgcc-162712de00d6e234083e63c00b7a0570aa13a5e3.zip
gcc-162712de00d6e234083e63c00b7a0570aa13a5e3.tar.gz
gcc-162712de00d6e234083e63c00b7a0570aa13a5e3.tar.bz2
ipa-cp.c (ipa_get_indirect_edge_target): Renamed to ipa_get_indirect_edge_target_1...
2013-03-25 Martin Jambor <mjambor@suse.cz> * ipa-cp.c (ipa_get_indirect_edge_target): Renamed to ipa_get_indirect_edge_target_1, added parameter agg_reps and ability to process it. (ipa_get_indirect_edge_target): New function. (devirtualization_time_bonus): New parameter known_aggs, pass it to ipa_get_indirect_edge_target. Update all callers. (ipcp_discover_new_direct_edges): New parameter aggvals. Pass it to ipa_get_indirect_edge_target_1 instead of calling ipa_get_indirect_edge_target. (create_specialized_node): Pass aggvlas to ipcp_discover_new_direct_edges. testsuite/ * gcc.dg/ipa/ipcp-agg-9.c: New test. From-SVN: r197054
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/ipa-cp.c70
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-agg-9.c45
4 files changed, 116 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fe32837..6a9293c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2013-03-25 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-cp.c (ipa_get_indirect_edge_target): Renamed to
+ ipa_get_indirect_edge_target_1, added parameter agg_reps and ability to
+ process it.
+ (ipa_get_indirect_edge_target): New function.
+ (devirtualization_time_bonus): New parameter known_aggs, pass it to
+ ipa_get_indirect_edge_target. Update all callers.
+ (ipcp_discover_new_direct_edges): New parameter aggvals. Pass it to
+ ipa_get_indirect_edge_target_1 instead of calling
+ ipa_get_indirect_edge_target.
+ (create_specialized_node): Pass aggvlas to
+ ipcp_discover_new_direct_edges.
+
2013-03-25 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/arm.md (f_sels, f_seld): New types.
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 69d7d23..3545ed1 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -1493,14 +1493,16 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
}
/* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
- (which can contain both constants and binfos) or KNOWN_BINFOS (which can be
- NULL) return the destination. */
+ (which can contain both constants and binfos), KNOWN_BINFOS, KNOWN_AGGS or
+ AGG_REPS return the destination. The latter three can be NULL. If AGG_REPS
+ is not NULL, KNOWN_AGGS is ignored. */
-tree
-ipa_get_indirect_edge_target (struct cgraph_edge *ie,
- vec<tree> known_vals,
- vec<tree> known_binfos,
- vec<ipa_agg_jump_function_p> known_aggs)
+static tree
+ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
+ vec<tree> known_vals,
+ vec<tree> known_binfos,
+ vec<ipa_agg_jump_function_p> known_aggs,
+ struct ipa_agg_replacement_value *agg_reps)
{
int param_index = ie->indirect_info->param_index;
HOST_WIDE_INT token, anc_offset;
@@ -1516,8 +1518,21 @@ ipa_get_indirect_edge_target (struct cgraph_edge *ie,
if (ie->indirect_info->agg_contents)
{
- if (known_aggs.length ()
- > (unsigned int) param_index)
+ if (agg_reps)
+ {
+ t = NULL;
+ while (agg_reps)
+ {
+ if (agg_reps->index == param_index
+ && agg_reps->offset == ie->indirect_info->offset)
+ {
+ t = agg_reps->value;
+ break;
+ }
+ agg_reps = agg_reps->next;
+ }
+ }
+ else if (known_aggs.length () > (unsigned int) param_index)
{
struct ipa_agg_jump_function *agg;
agg = known_aggs[param_index];
@@ -1572,13 +1587,29 @@ ipa_get_indirect_edge_target (struct cgraph_edge *ie,
}
}
+
+/* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
+ (which can contain both constants and binfos), KNOWN_BINFOS (which can be
+ NULL) or KNOWN_AGGS (which also can be NULL) return the destination. */
+
+tree
+ipa_get_indirect_edge_target (struct cgraph_edge *ie,
+ vec<tree> known_vals,
+ vec<tree> known_binfos,
+ vec<ipa_agg_jump_function_p> known_aggs)
+{
+ return ipa_get_indirect_edge_target_1 (ie, known_vals, known_binfos,
+ known_aggs, NULL);
+}
+
/* Calculate devirtualization time bonus for NODE, assuming we know KNOWN_CSTS
and KNOWN_BINFOS. */
static int
devirtualization_time_bonus (struct cgraph_node *node,
vec<tree> known_csts,
- vec<tree> known_binfos)
+ vec<tree> known_binfos,
+ vec<ipa_agg_jump_function_p> known_aggs)
{
struct cgraph_edge *ie;
int res = 0;
@@ -1590,7 +1621,7 @@ devirtualization_time_bonus (struct cgraph_node *node,
tree target;
target = ipa_get_indirect_edge_target (ie, known_csts, known_binfos,
- vNULL);
+ known_aggs);
if (!target)
continue;
@@ -1834,7 +1865,8 @@ estimate_local_effects (struct cgraph_node *node)
cgraph_for_node_and_aliases (node, gather_caller_stats, &stats, false);
estimate_ipcp_clone_size_and_time (node, known_csts, known_binfos,
known_aggs_ptrs, &size, &time, &hints);
- time -= devirtualization_time_bonus (node, known_csts, known_binfos);
+ time -= devirtualization_time_bonus (node, known_csts, known_binfos,
+ known_aggs_ptrs);
time -= hint_time_bonus (hints);
time -= removable_params_cost;
size -= stats.n_calls * removable_params_cost;
@@ -1911,7 +1943,8 @@ estimate_local_effects (struct cgraph_node *node)
known_aggs_ptrs, &size, &time,
&hints);
time_benefit = base_time - time
- + devirtualization_time_bonus (node, known_csts, known_binfos)
+ + devirtualization_time_bonus (node, known_csts, known_binfos,
+ known_aggs_ptrs)
+ hint_time_bonus (hints)
+ removable_params_cost + emc;
@@ -1973,7 +2006,8 @@ estimate_local_effects (struct cgraph_node *node)
known_aggs_ptrs, &size, &time,
&hints);
time_benefit = base_time - time
- + devirtualization_time_bonus (node, known_csts, known_binfos)
+ + devirtualization_time_bonus (node, known_csts, known_binfos,
+ known_aggs_ptrs)
+ hint_time_bonus (hints);
gcc_checking_assert (size >=0);
if (size == 0)
@@ -2256,7 +2290,8 @@ ipcp_propagate_stage (struct topo_info *topo)
static void
ipcp_discover_new_direct_edges (struct cgraph_node *node,
- vec<tree> known_vals)
+ vec<tree> known_vals,
+ struct ipa_agg_replacement_value *aggvals)
{
struct cgraph_edge *ie, *next_ie;
bool found = false;
@@ -2266,7 +2301,8 @@ ipcp_discover_new_direct_edges (struct cgraph_node *node,
tree target;
next_ie = ie->next_callee;
- target = ipa_get_indirect_edge_target (ie, known_vals, vNULL, vNULL);
+ target = ipa_get_indirect_edge_target_1 (ie, known_vals, vNULL, vNULL,
+ aggvals);
if (target)
{
ipa_make_edge_direct_to_target (ie, target);
@@ -2676,7 +2712,7 @@ create_specialized_node (struct cgraph_node *node,
new_info->ipcp_orig_node = node;
new_info->known_vals = known_vals;
- ipcp_discover_new_direct_edges (new_node, known_vals);
+ ipcp_discover_new_direct_edges (new_node, known_vals, aggvals);
callers.release ();
return new_node;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7fef606..36552cc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2013-03-25 Martin Jambor <mjambor@suse.cz>
+
+ * gcc.dg/ipa/ipcp-agg-9.c: New test.
+
2013-03-25 Tobias Burnus <burnus@net-b.de>
PR fortran/38536
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-agg-9.c b/gcc/testsuite/gcc.dg/ipa/ipcp-agg-9.c
new file mode 100644
index 0000000..e6b4b96
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-agg-9.c
@@ -0,0 +1,45 @@
+/* Verify that IPA-CP can make edges direct based on aggregate contents. */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fno-early-inlining -fdump-ipa-cp -fdump-ipa-inline" } */
+
+struct S
+{
+ int i;
+ void (*f)(struct S *);
+ unsigned u;
+};
+
+struct U
+{
+ struct U *next;
+ struct S s;
+ short a[8];
+};
+
+extern void non_existent(struct S *p, int);
+
+static void hooray1 (struct S *p)
+{
+ non_existent (p, 1);
+}
+
+static __attribute__ ((noinline))
+void hiphip1 (struct S *p)
+{
+ p->f (p);
+}
+
+int test1 (void)
+{
+ struct S s;
+ s.i = 1234;
+ s.f = hooray1;
+ s.u = 1001;
+ hiphip1 (&s);
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump "ipa-prop: Discovered an indirect call to a known target" "cp" } } */
+/* { dg-final { scan-ipa-dump "hooray1\[^\\n\]*inline copy in hiphip1" "inline" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
+/* { dg-final { cleanup-ipa-dump "inline" } } */