aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-cp.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2010-08-05 15:30:14 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2010-08-05 15:30:14 +0200
commit3e66255c25bd1d3071b93491c3063b8c6cdb109e (patch)
treeb694bc6d8a03291fbab5555550a69012ef1c2498 /gcc/ipa-cp.c
parent3949c4a710360edb924d4c88a8974ed0bbfa9f20 (diff)
downloadgcc-3e66255c25bd1d3071b93491c3063b8c6cdb109e.zip
gcc-3e66255c25bd1d3071b93491c3063b8c6cdb109e.tar.gz
gcc-3e66255c25bd1d3071b93491c3063b8c6cdb109e.tar.bz2
ipa-cp.c (ipcp_discover_new_direct_edges): New function.
2010-08-05 Martin Jambor <mjambor@suse.cz> * ipa-cp.c (ipcp_discover_new_direct_edges): New function. (ipcp_insert_stage): Redirect only edges not flagged with indirect_inlining_edge. Call ipcp_discover_new_direct_edges for all discovered constants. * testsuite/gcc.dg/ipa/ipcp-ii-1.c: New test. * testsuite/g++.dg/ipa/ipcp-ivi-1.C: Likewise. From-SVN: r162912
Diffstat (limited to 'gcc/ipa-cp.c')
-rw-r--r--gcc/ipa-cp.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 354a404..e6c67d6 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -1269,6 +1269,49 @@ ipcp_const_param_count (struct cgraph_node *node)
return const_param;
}
+/* Given that a formal parameter of NODE given by INDEX is known to be constant
+ CST, try to find any indirect edges that can be made direct and make them
+ so. Note that INDEX is the number the parameter at the time of analyzing
+ parameter uses and parameter removals should not be considered for it. (In
+ fact, the parameter itself has just been removed.) */
+
+static void
+ipcp_discover_new_direct_edges (struct cgraph_node *node, int index, tree cst)
+{
+ struct cgraph_edge *ie, *next_ie;
+
+ for (ie = node->indirect_calls; ie; ie = next_ie)
+ {
+ struct cgraph_indirect_call_info *ici = ie->indirect_info;
+
+ next_ie = ie->next_callee;
+ if (ici->param_index != index)
+ continue;
+
+ if (ici->polymorphic)
+ {
+ tree binfo;
+ HOST_WIDE_INT token;
+
+ if (TREE_CODE (cst) != ADDR_EXPR)
+ continue;
+
+ binfo = gimple_get_relevant_ref_binfo (TREE_OPERAND (cst, 0),
+ NULL_TREE);
+ if (!binfo)
+ continue;
+ gcc_assert (ie->indirect_info->anc_offset == 0);
+ token = ie->indirect_info->otr_token;
+ cst = gimple_fold_obj_type_ref_known_binfo (token, binfo);
+ if (!cst)
+ continue;
+ }
+
+ ipa_make_edge_direct_to_target (ie, cst);
+ }
+}
+
+
/* Propagate the constant parameters found by ipcp_iterate_stage()
to the function's code. */
static void
@@ -1390,7 +1433,8 @@ ipcp_insert_stage (void)
node_callers++;
redirect_callers = VEC_alloc (cgraph_edge_p, heap, node_callers);
for (cs = node->callers; cs != NULL; cs = cs->next_caller)
- VEC_quick_push (cgraph_edge_p, redirect_callers, cs);
+ if (!cs->indirect_inlining_edge)
+ VEC_quick_push (cgraph_edge_p, redirect_callers, cs);
/* Redirecting all the callers of the node to the
new versioned node. */
@@ -1410,7 +1454,13 @@ ipcp_insert_stage (void)
cgraph_node_name (node), (int)growth, (int)new_size);
ipcp_init_cloned_node (node, node1);
- /* TODO: We can use indirect inlning info to produce new calls. */
+ info = IPA_NODE_REF (node);
+ for (i = 0; i < count; i++)
+ {
+ struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
+ if (lat->type == IPA_CONST_VALUE)
+ ipcp_discover_new_direct_edges (node1, i, lat->constant);
+ }
if (dump_file)
dump_function_to_file (node1->decl, dump_file, dump_flags);