summaryrefslogtreecommitdiff
path: root/gcc/ipa-prop.c
diff options
context:
space:
mode:
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2010-05-19 11:49:36 +0000
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2010-05-19 11:49:36 +0000
commit7115ea0573bd294c444ed99fe7685b4646fa2dd6 (patch)
tree0bf93b58c18ebebe3ec5631fc8ca7271c6f036c0 /gcc/ipa-prop.c
parentb53b53b4d02d73419519acd48cfbd1123950f062 (diff)
downloadgcc-7115ea0573bd294c444ed99fe7685b4646fa2dd6.tar.gz
2010-05-19 Martin Jambor <mjambor@suse.cz>
* ipa-prop.c (ipa_print_node_jump_functions): Print jump functions also for indirect edges. Actual printing moved... (ipa_print_node_jump_functions_for_edge): ...here. (ipa_compute_jump_functions): Renamed to ipa_compute_jump_functions_for_edge and made static. (ipa_compute_jump_functions): New function. (make_edge_direct_to_target): Check if the number of arguments on the newly direct edge is the same as the number of parametrs of the callee. * ipa-cp.c (ipcp_init_stage): Most functionality moved to new ipa_compute_jump_functions. Call ipa_analyze_params_uses. * ipa-inline.c (inline_indirect_intraprocedural_analysis): Call analysis functions unconditionally, call the new ipa_analyze_params_uses on the node instead of every edge. * testsuite/g++.dg/ipa/ivinline-8.C: New test. * testsuite/gcc.dg/ipa/iinline-2.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159559 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-prop.c')
-rw-r--r--gcc/ipa-prop.c191
1 files changed, 126 insertions, 65 deletions
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 6437389876e..d977242b5f0 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -304,16 +304,87 @@ ipa_count_arguments (struct cgraph_edge *cs)
ipa_set_cs_argument_count (IPA_EDGE_REF (cs), arg_num);
}
+/* Print the jump functions associated with call graph edge CS to file F. */
+
+static void
+ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
+{
+ int i, count;
+
+ count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
+ for (i = 0; i < count; i++)
+ {
+ struct ipa_jump_func *jump_func;
+ enum jump_func_type type;
+
+ jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
+ type = jump_func->type;
+
+ fprintf (f, " param %d: ", i);
+ if (type == IPA_JF_UNKNOWN)
+ fprintf (f, "UNKNOWN\n");
+ else if (type == IPA_JF_KNOWN_TYPE)
+ {
+ tree binfo_type = TREE_TYPE (jump_func->value.base_binfo);
+ fprintf (f, "KNOWN TYPE, type in binfo is: ");
+ print_generic_expr (f, binfo_type, 0);
+ fprintf (f, " (%u)\n", TYPE_UID (binfo_type));
+ }
+ else if (type == IPA_JF_CONST)
+ {
+ tree val = jump_func->value.constant;
+ fprintf (f, "CONST: ");
+ print_generic_expr (f, val, 0);
+ if (TREE_CODE (val) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL)
+ {
+ fprintf (f, " -> ");
+ print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)),
+ 0);
+ }
+ fprintf (f, "\n");
+ }
+ else if (type == IPA_JF_CONST_MEMBER_PTR)
+ {
+ fprintf (f, "CONST MEMBER PTR: ");
+ print_generic_expr (f, jump_func->value.member_cst.pfn, 0);
+ fprintf (f, ", ");
+ print_generic_expr (f, jump_func->value.member_cst.delta, 0);
+ fprintf (f, "\n");
+ }
+ else if (type == IPA_JF_PASS_THROUGH)
+ {
+ fprintf (f, "PASS THROUGH: ");
+ fprintf (f, "%d, op %s ",
+ jump_func->value.pass_through.formal_id,
+ tree_code_name[(int)
+ jump_func->value.pass_through.operation]);
+ if (jump_func->value.pass_through.operation != NOP_EXPR)
+ print_generic_expr (dump_file,
+ jump_func->value.pass_through.operand, 0);
+ fprintf (dump_file, "\n");
+ }
+ else if (type == IPA_JF_ANCESTOR)
+ {
+ fprintf (f, "ANCESTOR: ");
+ fprintf (f, "%d, offset "HOST_WIDE_INT_PRINT_DEC", ",
+ jump_func->value.ancestor.formal_id,
+ jump_func->value.ancestor.offset);
+ print_generic_expr (f, jump_func->value.ancestor.type, 0);
+ fprintf (dump_file, "\n");
+ }
+ }
+}
+
+
/* Print the jump functions of all arguments on all call graph edges going from
NODE to file F. */
void
ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
{
- int i, count;
struct cgraph_edge *cs;
- struct ipa_jump_func *jump_func;
- enum jump_func_type type;
+ int i;
fprintf (f, " Jump functions of caller %s:\n", cgraph_node_name (node));
for (cs = node->callees; cs; cs = cs->next_callee)
@@ -321,69 +392,26 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
if (!ipa_edge_args_info_available_for_edge_p (cs))
continue;
- fprintf (f, " callsite %s ", cgraph_node_name (node));
- fprintf (f, "-> %s :: \n", cgraph_node_name (cs->callee));
+ fprintf (f, " callsite %s/%i -> %s/%i : \n",
+ cgraph_node_name (node), node->uid,
+ cgraph_node_name (cs->callee), cs->callee->uid);
+ ipa_print_node_jump_functions_for_edge (f, cs);
+ }
- count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
- for (i = 0; i < count; i++)
- {
- jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
- type = jump_func->type;
+ for (cs = node->indirect_calls, i = 0; cs; cs = cs->next_callee, i++)
+ {
+ if (!ipa_edge_args_info_available_for_edge_p (cs))
+ continue;
- fprintf (f, " param %d: ", i);
- if (type == IPA_JF_UNKNOWN)
- fprintf (f, "UNKNOWN\n");
- else if (type == IPA_JF_KNOWN_TYPE)
- {
- tree binfo_type = TREE_TYPE (jump_func->value.base_binfo);
- fprintf (f, "KNOWN TYPE, type in binfo is: ");
- print_generic_expr (f, binfo_type, 0);
- fprintf (f, " (%u)\n", TYPE_UID (binfo_type));
- }
- else if (type == IPA_JF_CONST)
- {
- tree val = jump_func->value.constant;
- fprintf (f, "CONST: ");
- print_generic_expr (f, val, 0);
- if (TREE_CODE (val) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL)
- {
- fprintf (f, " -> ");
- print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)),
- 0);
- }
- fprintf (f, "\n");
- }
- else if (type == IPA_JF_CONST_MEMBER_PTR)
- {
- fprintf (f, "CONST MEMBER PTR: ");
- print_generic_expr (f, jump_func->value.member_cst.pfn, 0);
- fprintf (f, ", ");
- print_generic_expr (f, jump_func->value.member_cst.delta, 0);
- fprintf (f, "\n");
- }
- else if (type == IPA_JF_PASS_THROUGH)
- {
- fprintf (f, "PASS THROUGH: ");
- fprintf (f, "%d, op %s ",
- jump_func->value.pass_through.formal_id,
- tree_code_name[(int)
- jump_func->value.pass_through.operation]);
- if (jump_func->value.pass_through.operation != NOP_EXPR)
- print_generic_expr (dump_file,
- jump_func->value.pass_through.operand, 0);
- fprintf (dump_file, "\n");
- }
- else if (type == IPA_JF_ANCESTOR)
- {
- fprintf (f, "ANCESTOR: ");
- fprintf (f, "%d, offset "HOST_WIDE_INT_PRINT_DEC", ",
- jump_func->value.ancestor.formal_id,
- jump_func->value.ancestor.offset);
- print_generic_expr (f, jump_func->value.ancestor.type, 0);
- fprintf (dump_file, "\n");
- }
+ if (cs->call_stmt)
+ {
+ fprintf (f, " indirect callsite %d for stmt ", i);
+ print_gimple_stmt (f, cs->call_stmt, 0, TDF_SLIM);
}
+ else
+ fprintf (f, " indirect callsite %d :\n", i);
+ ipa_print_node_jump_functions_for_edge (f, cs);
+
}
}
@@ -852,8 +880,8 @@ compute_cst_member_ptr_arguments (struct ipa_jump_func *functions,
information in the jump_functions array in the ipa_edge_args corresponding
to this callsite. */
-void
-ipa_compute_jump_functions (struct cgraph_edge *cs)
+static void
+ipa_compute_jump_functions_for_edge (struct cgraph_edge *cs)
{
struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
struct ipa_edge_args *arguments = IPA_EDGE_REF (cs);
@@ -880,6 +908,34 @@ ipa_compute_jump_functions (struct cgraph_edge *cs)
compute_cst_member_ptr_arguments (arguments->jump_functions, call);
}
+/* Compute jump functions for all edges - both direct and indirect - outgoing
+ from NODE. Also count the actual arguments in the process. */
+
+void
+ipa_compute_jump_functions (struct cgraph_node *node)
+{
+ struct cgraph_edge *cs;
+
+ for (cs = node->callees; cs; cs = cs->next_callee)
+ {
+ /* We do not need to bother analyzing calls to unknown
+ functions unless they may become known during lto/whopr. */
+ if (!cs->callee->analyzed && !flag_lto && !flag_whopr)
+ continue;
+ ipa_count_arguments (cs);
+ if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
+ != ipa_get_param_count (IPA_NODE_REF (cs->callee)))
+ ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee));
+ ipa_compute_jump_functions_for_edge (cs);
+ }
+
+ for (cs = node->indirect_calls; cs; cs = cs->next_callee)
+ {
+ ipa_count_arguments (cs);
+ ipa_compute_jump_functions_for_edge (cs);
+ }
+}
+
/* If RHS looks like a rhs of a statement loading pfn from a member
pointer formal parameter, return the parameter, otherwise return
NULL. If USE_DELTA, then we look for a use of the delta field
@@ -1345,6 +1401,11 @@ make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
else
fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
}
+
+ if (ipa_get_cs_argument_count (IPA_EDGE_REF (ie))
+ != ipa_get_param_count (IPA_NODE_REF (callee)))
+ ipa_set_called_with_variable_arg (IPA_NODE_REF (callee));
+
return ie;
}