Commit 7b872d9e by Martin Jambor Committed by Martin Jambor

ipa-prop.h (ipa_get_jf_known_type_offset): New function.

2012-06-03  Martin Jambor  <mjambor@suse.cz>

	* ipa-prop.h (ipa_get_jf_known_type_offset): New function.
	(ipa_get_jf_known_type_base_type): Likewise.
	(ipa_get_jf_known_type_component_type): Likewise.
	(ipa_get_jf_constant): Likewise.
	(ipa_get_jf_pass_through_formal_id): Likewise.
	(ipa_get_jf_pass_through_operation): Likewise.
	(ipa_get_jf_ancestor_offset): Likewise.
	(ipa_get_jf_ancestor_type): Likewise.
	(ipa_get_jf_ancestor_formal_id): Likewise.
	(ipa_get_jf_member_ptr_pfn): Likewise.
	* ipa-prop.c (ipa_set_jf_known_type): New function.
	(ipa_set_jf_constant): Likewise.
	(ipa_set_jf_simple_pass_through): Likewise.
	(ipa_set_jf_arith_pass_through): Likewise.
	(ipa_set_ancestor_jf): Likewise.
	(fill_member_ptr_cst_jump_function): Moved up and renamed to
	ipa_set_jf_member_ptr_cst.
	(detect_type_change_1): Use the new jump function creation functions.
	(compute_complex_assign_jump_func): Likewise.
	(compute_complex_ancestor_jump_func): Likewise.
	(compute_known_type_jump_func): Likewise.
	(compute_scalar_jump_functions): Likewise.
	(compute_pass_through_member_ptrs): Likewise.
	(determine_cst_member_ptr): Likewise.
	(combine_known_type_and_ancestor_jfs): Likewise.
	(try_make_edge_direct_simple_call): Likewise.
	(try_make_edge_direct_virtual_call): Likewise.
	(update_indirect_edges_after_inlining): Likewise.
	* ipa-cp.c (ipa_get_jf_pass_through_result): Use jump function
	access functions.  Incorporat NOP_EXPR and BINFO handling from its
	callers.
	(ipa_get_jf_ancestor_result): Likewise.  Incorporate handling BINFOs
	which was in its callers.
	(ipa_value_from_jfunc): Use jump function access functions.  Some
	functionality moved to functions above.
	(propagate_vals_accross_ancestor): Likewise.
	(propagate_vals_accross_pass_through): Use jump function access
	functions.
	(propagate_accross_jump_function): Likewise.
	* ipa-inline-analysis.c (remap_edge_change_prob): Use jump function
	access functions.
	(inline_merge_summary): Likewise.

From-SVN: r188156
parent 7ac6a832
2012-06-03 Martin Jambor <mjambor@suse.cz>
* ipa-prop.h (ipa_get_jf_known_type_offset): New function.
(ipa_get_jf_known_type_base_type): Likewise.
(ipa_get_jf_known_type_component_type): Likewise.
(ipa_get_jf_constant): Likewise.
(ipa_get_jf_pass_through_formal_id): Likewise.
(ipa_get_jf_pass_through_operation): Likewise.
(ipa_get_jf_ancestor_offset): Likewise.
(ipa_get_jf_ancestor_type): Likewise.
(ipa_get_jf_ancestor_formal_id): Likewise.
(ipa_get_jf_member_ptr_pfn): Likewise.
* ipa-prop.c (ipa_set_jf_known_type): New function.
(ipa_set_jf_constant): Likewise.
(ipa_set_jf_simple_pass_through): Likewise.
(ipa_set_jf_arith_pass_through): Likewise.
(ipa_set_ancestor_jf): Likewise.
(fill_member_ptr_cst_jump_function): Moved up and renamed to
ipa_set_jf_member_ptr_cst.
(detect_type_change_1): Use the new jump function creation functions.
(compute_complex_assign_jump_func): Likewise.
(compute_complex_ancestor_jump_func): Likewise.
(compute_known_type_jump_func): Likewise.
(compute_scalar_jump_functions): Likewise.
(compute_pass_through_member_ptrs): Likewise.
(determine_cst_member_ptr): Likewise.
(combine_known_type_and_ancestor_jfs): Likewise.
(try_make_edge_direct_simple_call): Likewise.
(try_make_edge_direct_virtual_call): Likewise.
(update_indirect_edges_after_inlining): Likewise.
* ipa-cp.c (ipa_get_jf_pass_through_result): Use jump function
access functions. Incorporat NOP_EXPR and BINFO handling from its
callers.
(ipa_get_jf_ancestor_result): Likewise. Incorporate handling BINFOs
which was in its callers.
(ipa_value_from_jfunc): Use jump function access functions. Some
functionality moved to functions above.
(propagate_vals_accross_ancestor): Likewise.
(propagate_vals_accross_pass_through): Use jump function access
functions.
(propagate_accross_jump_function): Likewise.
* ipa-inline-analysis.c (remap_edge_change_prob): Use jump function
access functions.
(inline_merge_summary): Likewise.
2012-06-03 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> 2012-06-03 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* config/pa/pa.h (MAX_PCREL17F_OFFSET): Define. * config/pa/pa.h (MAX_PCREL17F_OFFSET): Define.
......
...@@ -638,17 +638,19 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input) ...@@ -638,17 +638,19 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)
{ {
tree restype, res; tree restype, res;
gcc_checking_assert (is_gimple_ip_invariant (input)); if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
if (jfunc->value.pass_through.operation == NOP_EXPR)
return input; return input;
else if (TREE_CODE (input) == TREE_BINFO)
return NULL_TREE;
if (TREE_CODE_CLASS (jfunc->value.pass_through.operation) gcc_checking_assert (is_gimple_ip_invariant (input));
if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
== tcc_comparison) == tcc_comparison)
restype = boolean_type_node; restype = boolean_type_node;
else else
restype = TREE_TYPE (input); restype = TREE_TYPE (input);
res = fold_binary (jfunc->value.pass_through.operation, restype, res = fold_binary (ipa_get_jf_pass_through_operation (jfunc), restype,
input, jfunc->value.pass_through.operand); input, ipa_get_jf_pass_through_operand (jfunc));
if (res && !is_gimple_ip_invariant (res)) if (res && !is_gimple_ip_invariant (res))
return NULL_TREE; return NULL_TREE;
...@@ -662,12 +664,16 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input) ...@@ -662,12 +664,16 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)
static tree static tree
ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input) ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
{ {
if (TREE_CODE (input) == ADDR_EXPR) if (TREE_CODE (input) == TREE_BINFO)
return get_binfo_at_offset (input,
ipa_get_jf_ancestor_offset (jfunc),
ipa_get_jf_ancestor_type (jfunc));
else if (TREE_CODE (input) == ADDR_EXPR)
{ {
tree t = TREE_OPERAND (input, 0); tree t = TREE_OPERAND (input, 0);
t = build_ref_for_offset (EXPR_LOCATION (t), t, t = build_ref_for_offset (EXPR_LOCATION (t), t,
jfunc->value.ancestor.offset, ipa_get_jf_ancestor_offset (jfunc),
jfunc->value.ancestor.type, NULL, false); ipa_get_jf_ancestor_type (jfunc), NULL, false);
return build_fold_addr_expr (t); return build_fold_addr_expr (t);
} }
else else
...@@ -680,12 +686,12 @@ ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input) ...@@ -680,12 +686,12 @@ ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
static tree static tree
ipa_value_from_known_type_jfunc (struct ipa_jump_func *jfunc) ipa_value_from_known_type_jfunc (struct ipa_jump_func *jfunc)
{ {
tree base_binfo = TYPE_BINFO (jfunc->value.known_type.base_type); tree base_binfo = TYPE_BINFO (ipa_get_jf_known_type_base_type (jfunc));
if (!base_binfo) if (!base_binfo)
return NULL_TREE; return NULL_TREE;
return get_binfo_at_offset (base_binfo, return get_binfo_at_offset (base_binfo,
jfunc->value.known_type.offset, ipa_get_jf_known_type_offset (jfunc),
jfunc->value.known_type.component_type); ipa_get_jf_known_type_component_type (jfunc));
} }
/* Determine whether JFUNC evaluates to a known value (that is either a /* Determine whether JFUNC evaluates to a known value (that is either a
...@@ -697,7 +703,7 @@ tree ...@@ -697,7 +703,7 @@ tree
ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc) ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc)
{ {
if (jfunc->type == IPA_JF_CONST) if (jfunc->type == IPA_JF_CONST)
return jfunc->value.constant; return ipa_get_jf_constant (jfunc);
else if (jfunc->type == IPA_JF_KNOWN_TYPE) else if (jfunc->type == IPA_JF_KNOWN_TYPE)
return ipa_value_from_known_type_jfunc (jfunc); return ipa_value_from_known_type_jfunc (jfunc);
else if (jfunc->type == IPA_JF_PASS_THROUGH else if (jfunc->type == IPA_JF_PASS_THROUGH
...@@ -707,9 +713,9 @@ ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc) ...@@ -707,9 +713,9 @@ ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc)
int idx; int idx;
if (jfunc->type == IPA_JF_PASS_THROUGH) if (jfunc->type == IPA_JF_PASS_THROUGH)
idx = jfunc->value.pass_through.formal_id; idx = ipa_get_jf_pass_through_formal_id (jfunc);
else else
idx = jfunc->value.ancestor.formal_id; idx = ipa_get_jf_ancestor_formal_id (jfunc);
if (info->ipcp_orig_node) if (info->ipcp_orig_node)
input = VEC_index (tree, info->known_vals, idx); input = VEC_index (tree, info->known_vals, idx);
...@@ -732,23 +738,10 @@ ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc) ...@@ -732,23 +738,10 @@ ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc)
return NULL_TREE; return NULL_TREE;
if (jfunc->type == IPA_JF_PASS_THROUGH) if (jfunc->type == IPA_JF_PASS_THROUGH)
{
if (jfunc->value.pass_through.operation == NOP_EXPR)
return input;
else if (TREE_CODE (input) == TREE_BINFO)
return NULL_TREE;
else
return ipa_get_jf_pass_through_result (jfunc, input); return ipa_get_jf_pass_through_result (jfunc, input);
}
else
{
if (TREE_CODE (input) == TREE_BINFO)
return get_binfo_at_offset (input, jfunc->value.ancestor.offset,
jfunc->value.ancestor.type);
else else
return ipa_get_jf_ancestor_result (jfunc, input); return ipa_get_jf_ancestor_result (jfunc, input);
} }
}
else else
return NULL_TREE; return NULL_TREE;
} }
...@@ -907,13 +900,13 @@ propagate_vals_accross_pass_through (struct cgraph_edge *cs, ...@@ -907,13 +900,13 @@ propagate_vals_accross_pass_through (struct cgraph_edge *cs,
struct ipcp_value *src_val; struct ipcp_value *src_val;
bool ret = false; bool ret = false;
if (jfunc->value.pass_through.operation == NOP_EXPR) if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
for (src_val = src_lat->values; src_val; src_val = src_val->next) for (src_val = src_lat->values; src_val; src_val = src_val->next)
ret |= add_value_to_lattice (dest_lat, src_val->value, cs, ret |= add_value_to_lattice (dest_lat, src_val->value, cs,
src_val, src_idx); src_val, src_idx);
/* Do not create new values when propagating within an SCC because if there /* Do not create new values when propagating within an SCC because if there
arithmetic functions with circular dependencies, there is infinite number are arithmetic functions with circular dependencies, there is infinite
of them and we would just make lattices bottom. */ number of them and we would just make lattices bottom. */
else if (edge_within_scc (cs)) else if (edge_within_scc (cs))
ret = set_lattice_contains_variable (dest_lat); ret = set_lattice_contains_variable (dest_lat);
else else
...@@ -956,13 +949,7 @@ propagate_vals_accross_ancestor (struct cgraph_edge *cs, ...@@ -956,13 +949,7 @@ propagate_vals_accross_ancestor (struct cgraph_edge *cs,
for (src_val = src_lat->values; src_val; src_val = src_val->next) for (src_val = src_lat->values; src_val; src_val = src_val->next)
{ {
tree t = src_val->value; tree t = ipa_get_jf_ancestor_result (jfunc, src_val->value);
if (TREE_CODE (t) == TREE_BINFO)
t = get_binfo_at_offset (t, jfunc->value.ancestor.offset,
jfunc->value.ancestor.type);
else
t = ipa_get_jf_ancestor_result (jfunc, t);
if (t) if (t)
ret |= add_value_to_lattice (dest_lat, t, cs, src_val, src_idx); ret |= add_value_to_lattice (dest_lat, t, cs, src_val, src_idx);
...@@ -996,7 +983,7 @@ propagate_accross_jump_function (struct cgraph_edge *cs, ...@@ -996,7 +983,7 @@ propagate_accross_jump_function (struct cgraph_edge *cs,
return set_lattice_contains_variable (dest_lat); return set_lattice_contains_variable (dest_lat);
} }
else else
val = jfunc->value.constant; val = ipa_get_jf_constant (jfunc);
return add_value_to_lattice (dest_lat, val, cs, NULL, 0); return add_value_to_lattice (dest_lat, val, cs, NULL, 0);
} }
else if (jfunc->type == IPA_JF_PASS_THROUGH else if (jfunc->type == IPA_JF_PASS_THROUGH
...@@ -1008,9 +995,9 @@ propagate_accross_jump_function (struct cgraph_edge *cs, ...@@ -1008,9 +995,9 @@ propagate_accross_jump_function (struct cgraph_edge *cs,
bool ret; bool ret;
if (jfunc->type == IPA_JF_PASS_THROUGH) if (jfunc->type == IPA_JF_PASS_THROUGH)
src_idx = jfunc->value.pass_through.formal_id; src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
else else
src_idx = jfunc->value.ancestor.formal_id; src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
src_lat = ipa_get_lattice (caller_info, src_idx); src_lat = ipa_get_lattice (caller_info, src_idx);
if (src_lat->bottom) if (src_lat->bottom)
......
...@@ -2514,16 +2514,16 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge, ...@@ -2514,16 +2514,16 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge,
{ {
struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i); struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i);
if (jfunc->type == IPA_JF_PASS_THROUGH if (jfunc->type == IPA_JF_PASS_THROUGH
&& (jfunc->value.pass_through.formal_id && (ipa_get_jf_pass_through_formal_id (jfunc)
< (int) VEC_length (inline_param_summary_t, < (int) VEC_length (inline_param_summary_t,
inlined_es->param))) inlined_es->param)))
{ {
int jf_formal_id = ipa_get_jf_pass_through_formal_id (jfunc);
int prob1 = VEC_index (inline_param_summary_t, int prob1 = VEC_index (inline_param_summary_t,
es->param, i)->change_prob; es->param, i)->change_prob;
int prob2 = VEC_index int prob2 = VEC_index
(inline_param_summary_t, (inline_param_summary_t,
inlined_es->param, inlined_es->param, jf_formal_id)->change_prob;
jfunc->value.pass_through.formal_id)->change_prob;
int prob = ((prob1 * prob2 + REG_BR_PROB_BASE / 2) int prob = ((prob1 * prob2 + REG_BR_PROB_BASE / 2)
/ REG_BR_PROB_BASE); / REG_BR_PROB_BASE);
...@@ -2649,8 +2649,8 @@ inline_merge_summary (struct cgraph_edge *edge) ...@@ -2649,8 +2649,8 @@ inline_merge_summary (struct cgraph_edge *edge)
int map = -1; int map = -1;
/* TODO: handle non-NOPs when merging. */ /* TODO: handle non-NOPs when merging. */
if (jfunc->type == IPA_JF_PASS_THROUGH if (jfunc->type == IPA_JF_PASS_THROUGH
&& jfunc->value.pass_through.operation == NOP_EXPR) && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
map = jfunc->value.pass_through.formal_id; map = ipa_get_jf_pass_through_formal_id (jfunc);
VEC_replace (int, operand_map, i, map); VEC_replace (int, operand_map, i, map);
gcc_assert (map < ipa_get_param_count (IPA_NODE_REF (to))); gcc_assert (map < ipa_get_param_count (IPA_NODE_REF (to)));
} }
......
...@@ -266,6 +266,73 @@ ipa_print_all_jump_functions (FILE *f) ...@@ -266,6 +266,73 @@ ipa_print_all_jump_functions (FILE *f)
} }
} }
/* Set JFUNC to be a known type jump function. */
static void
ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
tree base_type, tree component_type)
{
jfunc->type = IPA_JF_KNOWN_TYPE;
jfunc->value.known_type.offset = offset,
jfunc->value.known_type.base_type = base_type;
jfunc->value.known_type.component_type = component_type;
}
/* Set JFUNC to be a constant jmp function. */
static void
ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant)
{
jfunc->type = IPA_JF_CONST;
jfunc->value.constant = constant;
}
/* Set JFUNC to be a simple pass-through jump function. */
static void
ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id)
{
jfunc->type = IPA_JF_PASS_THROUGH;
jfunc->value.pass_through.operand = NULL_TREE;
jfunc->value.pass_through.formal_id = formal_id;
jfunc->value.pass_through.operation = NOP_EXPR;
}
/* Set JFUNC to be an arithmetic pass through jump function. */
static void
ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
tree operand, enum tree_code operation)
{
jfunc->type = IPA_JF_PASS_THROUGH;
jfunc->value.pass_through.operand = operand;
jfunc->value.pass_through.formal_id = formal_id;
jfunc->value.pass_through.operation = operation;
}
/* Set JFUNC to be an ancestor jump function. */
static void
ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
tree type, int formal_id)
{
jfunc->type = IPA_JF_ANCESTOR;
jfunc->value.ancestor.formal_id = formal_id;
jfunc->value.ancestor.offset = offset;
jfunc->value.ancestor.type = type;
}
/* Simple function filling in a member pointer constant jump function (with PFN
and DELTA as the constant value) into JFUNC. */
static void
ipa_set_jf_member_ptr_cst (struct ipa_jump_func *jfunc,
tree pfn, tree delta)
{
jfunc->type = IPA_JF_CONST_MEMBER_PTR;
jfunc->value.member_cst.pfn = pfn;
jfunc->value.member_cst.delta = delta;
}
/* Structure to be passed in between detect_type_change and /* Structure to be passed in between detect_type_change and
check_stmt_for_type_change. */ check_stmt_for_type_change. */
...@@ -464,11 +531,7 @@ detect_type_change_1 (tree arg, tree base, tree comp_type, gimple call, ...@@ -464,11 +531,7 @@ detect_type_change_1 (tree arg, tree base, tree comp_type, gimple call,
|| offset != 0) || offset != 0)
jfunc->type = IPA_JF_UNKNOWN; jfunc->type = IPA_JF_UNKNOWN;
else else
{ ipa_set_jf_known_type (jfunc, 0, tci.known_current_type, comp_type);
jfunc->type = IPA_JF_KNOWN_TYPE;
jfunc->value.known_type.base_type = tci.known_current_type;
jfunc->value.known_type.component_type = comp_type;
}
return true; return true;
} }
...@@ -666,18 +729,12 @@ compute_complex_assign_jump_func (struct ipa_node_params *info, ...@@ -666,18 +729,12 @@ compute_complex_assign_jump_func (struct ipa_node_params *info,
TREE_TYPE (op1)))) TREE_TYPE (op1))))
return; return;
jfunc->type = IPA_JF_PASS_THROUGH; ipa_set_jf_arith_pass_through (jfunc, index, op2,
jfunc->value.pass_through.formal_id = index; gimple_assign_rhs_code (stmt));
jfunc->value.pass_through.operation = gimple_assign_rhs_code (stmt);
jfunc->value.pass_through.operand = op2;
} }
else if (gimple_assign_single_p (stmt) else if (gimple_assign_single_p (stmt)
&& !detect_type_change_ssa (tc_ssa, call, jfunc)) && !detect_type_change_ssa (tc_ssa, call, jfunc))
{ ipa_set_jf_simple_pass_through (jfunc, index);
jfunc->type = IPA_JF_PASS_THROUGH;
jfunc->value.pass_through.formal_id = index;
jfunc->value.pass_through.operation = NOP_EXPR;
}
return; return;
} }
...@@ -703,12 +760,7 @@ compute_complex_assign_jump_func (struct ipa_node_params *info, ...@@ -703,12 +760,7 @@ compute_complex_assign_jump_func (struct ipa_node_params *info,
index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa)); index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
if (index >= 0 if (index >= 0
&& !detect_type_change (op1, base, call, jfunc, offset)) && !detect_type_change (op1, base, call, jfunc, offset))
{ ipa_set_ancestor_jf (jfunc, offset, TREE_TYPE (op1), index);
jfunc->type = IPA_JF_ANCESTOR;
jfunc->value.ancestor.formal_id = index;
jfunc->value.ancestor.offset = offset;
jfunc->value.ancestor.type = TREE_TYPE (op1);
}
} }
/* Extract the base, offset and MEM_REF expression from a statement ASSIGN if /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
...@@ -832,12 +884,7 @@ compute_complex_ancestor_jump_func (struct ipa_node_params *info, ...@@ -832,12 +884,7 @@ compute_complex_ancestor_jump_func (struct ipa_node_params *info,
} }
if (!detect_type_change (obj, expr, call, jfunc, offset)) if (!detect_type_change (obj, expr, call, jfunc, offset))
{ ipa_set_ancestor_jf (jfunc, offset, TREE_TYPE (obj), index);
jfunc->type = IPA_JF_ANCESTOR;
jfunc->value.ancestor.formal_id = index;
jfunc->value.ancestor.offset = offset;
jfunc->value.ancestor.type = TREE_TYPE (obj);
}
} }
/* Given OP which is passed as an actual argument to a called function, /* Given OP which is passed as an actual argument to a called function,
...@@ -869,10 +916,7 @@ compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc, ...@@ -869,10 +916,7 @@ compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc,
|| !TYPE_BINFO (TREE_TYPE (base))) || !TYPE_BINFO (TREE_TYPE (base)))
return; return;
jfunc->type = IPA_JF_KNOWN_TYPE; ipa_set_jf_known_type (jfunc, offset, TREE_TYPE (base), TREE_TYPE (op));
jfunc->value.known_type.base_type = TREE_TYPE (base);
jfunc->value.known_type.offset = offset;
jfunc->value.known_type.component_type = TREE_TYPE (op);
} }
...@@ -898,10 +942,7 @@ compute_scalar_jump_functions (struct ipa_node_params *info, ...@@ -898,10 +942,7 @@ compute_scalar_jump_functions (struct ipa_node_params *info,
arg = gimple_call_arg (call, num); arg = gimple_call_arg (call, num);
if (is_gimple_ip_invariant (arg)) if (is_gimple_ip_invariant (arg))
{ ipa_set_jf_constant (jfunc, arg);
jfunc->type = IPA_JF_CONST;
jfunc->value.constant = arg;
}
else if (TREE_CODE (arg) == SSA_NAME) else if (TREE_CODE (arg) == SSA_NAME)
{ {
if (SSA_NAME_IS_DEFAULT_DEF (arg)) if (SSA_NAME_IS_DEFAULT_DEF (arg))
...@@ -910,11 +951,7 @@ compute_scalar_jump_functions (struct ipa_node_params *info, ...@@ -910,11 +951,7 @@ compute_scalar_jump_functions (struct ipa_node_params *info,
if (index >= 0 if (index >= 0
&& !detect_type_change_ssa (arg, call, jfunc)) && !detect_type_change_ssa (arg, call, jfunc))
{ ipa_set_jf_simple_pass_through (jfunc, index);
jfunc->type = IPA_JF_PASS_THROUGH;
jfunc->value.pass_through.formal_id = index;
jfunc->value.pass_through.operation = NOP_EXPR;
}
} }
else else
{ {
...@@ -997,9 +1034,7 @@ compute_pass_through_member_ptrs (struct ipa_node_params *info, ...@@ -997,9 +1034,7 @@ compute_pass_through_member_ptrs (struct ipa_node_params *info,
{ {
struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args,
num); num);
jfunc->type = IPA_JF_PASS_THROUGH; ipa_set_jf_simple_pass_through (jfunc, index);
jfunc->value.pass_through.formal_id = index;
jfunc->value.pass_through.operation = NOP_EXPR;
} }
else else
undecided_members = true; undecided_members = true;
...@@ -1012,18 +1047,6 @@ compute_pass_through_member_ptrs (struct ipa_node_params *info, ...@@ -1012,18 +1047,6 @@ compute_pass_through_member_ptrs (struct ipa_node_params *info,
return undecided_members; return undecided_members;
} }
/* Simple function filling in a member pointer constant jump function (with PFN
and DELTA as the constant value) into JFUNC. */
static void
fill_member_ptr_cst_jump_function (struct ipa_jump_func *jfunc,
tree pfn, tree delta)
{
jfunc->type = IPA_JF_CONST_MEMBER_PTR;
jfunc->value.member_cst.pfn = pfn;
jfunc->value.member_cst.delta = delta;
}
/* If RHS is an SSA_NAME and it is defined by a simple copy assign statement, /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
return the rhs of its defining statement. */ return the rhs of its defining statement. */
...@@ -1091,7 +1114,7 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field, ...@@ -1091,7 +1114,7 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field,
method = TREE_OPERAND (rhs, 0); method = TREE_OPERAND (rhs, 0);
if (delta) if (delta)
{ {
fill_member_ptr_cst_jump_function (jfunc, rhs, delta); ipa_set_jf_member_ptr_cst (jfunc, rhs, delta);
return; return;
} }
} }
...@@ -1107,7 +1130,7 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field, ...@@ -1107,7 +1130,7 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field,
delta = rhs; delta = rhs;
if (method) if (method)
{ {
fill_member_ptr_cst_jump_function (jfunc, rhs, delta); ipa_set_jf_member_ptr_cst (jfunc, rhs, delta);
return; return;
} }
} }
...@@ -1681,13 +1704,13 @@ combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src, ...@@ -1681,13 +1704,13 @@ combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
HOST_WIDE_INT combined_offset; HOST_WIDE_INT combined_offset;
tree combined_type; tree combined_type;
combined_offset = src->value.known_type.offset + dst->value.ancestor.offset; combined_offset = ipa_get_jf_known_type_offset (src)
combined_type = dst->value.ancestor.type; + ipa_get_jf_ancestor_offset (dst);
combined_type = ipa_get_jf_ancestor_type (dst);
dst->type = IPA_JF_KNOWN_TYPE; ipa_set_jf_known_type (dst, combined_offset,
dst->value.known_type.base_type = src->value.known_type.base_type; ipa_get_jf_known_type_base_type (src),
dst->value.known_type.offset = combined_offset; combined_type);
dst->value.known_type.component_type = combined_type;
} }
/* Update the jump functions associated with call graph edge E when the call /* Update the jump functions associated with call graph edge E when the call
...@@ -1804,9 +1827,9 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie, ...@@ -1804,9 +1827,9 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie,
tree target; tree target;
if (jfunc->type == IPA_JF_CONST) if (jfunc->type == IPA_JF_CONST)
target = jfunc->value.constant; target = ipa_get_jf_constant (jfunc);
else if (jfunc->type == IPA_JF_CONST_MEMBER_PTR) else if (jfunc->type == IPA_JF_CONST_MEMBER_PTR)
target = jfunc->value.member_cst.pfn; target = ipa_get_jf_member_ptr_pfn (jfunc);
else else
return NULL; return NULL;
...@@ -1827,9 +1850,9 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie, ...@@ -1827,9 +1850,9 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
if (jfunc->type != IPA_JF_KNOWN_TYPE) if (jfunc->type != IPA_JF_KNOWN_TYPE)
return NULL; return NULL;
binfo = TYPE_BINFO (jfunc->value.known_type.base_type); binfo = TYPE_BINFO (ipa_get_jf_known_type_base_type (jfunc));
gcc_checking_assert (binfo); gcc_checking_assert (binfo);
binfo = get_binfo_at_offset (binfo, jfunc->value.known_type.offset binfo = get_binfo_at_offset (binfo, ipa_get_jf_known_type_offset (jfunc)
+ ie->indirect_info->anc_offset, + ie->indirect_info->anc_offset,
ie->indirect_info->otr_type); ie->indirect_info->otr_type);
if (binfo) if (binfo)
...@@ -1881,12 +1904,12 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, ...@@ -1881,12 +1904,12 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
jfunc = ipa_get_ith_jump_func (top, ici->param_index); jfunc = ipa_get_ith_jump_func (top, ici->param_index);
if (jfunc->type == IPA_JF_PASS_THROUGH if (jfunc->type == IPA_JF_PASS_THROUGH
&& jfunc->value.pass_through.operation == NOP_EXPR) && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
ici->param_index = jfunc->value.pass_through.formal_id; ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
else if (jfunc->type == IPA_JF_ANCESTOR) else if (jfunc->type == IPA_JF_ANCESTOR)
{ {
ici->param_index = jfunc->value.ancestor.formal_id; ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
ici->anc_offset += jfunc->value.ancestor.offset; ici->anc_offset += ipa_get_jf_ancestor_offset (jfunc);
} }
else else
/* Either we can find a destination for this edge now or never. */ /* Either we can find a destination for this edge now or never. */
......
...@@ -113,7 +113,7 @@ struct GTY(()) ipa_ancestor_jf_data ...@@ -113,7 +113,7 @@ struct GTY(()) ipa_ancestor_jf_data
{ {
/* Offset of the field representing the ancestor. */ /* Offset of the field representing the ancestor. */
HOST_WIDE_INT offset; HOST_WIDE_INT offset;
/* TYpe of the result. */ /* Type of the result. */
tree type; tree type;
/* Number of the caller's formal parameter being passed. */ /* Number of the caller's formal parameter being passed. */
int formal_id; int formal_id;
...@@ -149,6 +149,108 @@ typedef struct GTY (()) ipa_jump_func ...@@ -149,6 +149,108 @@ typedef struct GTY (()) ipa_jump_func
DEF_VEC_O (ipa_jump_func_t); DEF_VEC_O (ipa_jump_func_t);
DEF_VEC_ALLOC_O (ipa_jump_func_t, gc); DEF_VEC_ALLOC_O (ipa_jump_func_t, gc);
/* Return the offset of the component that is decribed by a known type jump
function JFUNC. */
static inline HOST_WIDE_INT
ipa_get_jf_known_type_offset (struct ipa_jump_func *jfunc)
{
gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE);
return jfunc->value.known_type.offset;
}
/* Return the base type of a known type jump function JFUNC. */
static inline tree
ipa_get_jf_known_type_base_type (struct ipa_jump_func *jfunc)
{
gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE);
return jfunc->value.known_type.base_type;
}
/* Return the component type of a known type jump function JFUNC. */
static inline tree
ipa_get_jf_known_type_component_type (struct ipa_jump_func *jfunc)
{
gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE);
return jfunc->value.known_type.component_type;
}
/* Return the constant stored in a constant jump functin JFUNC. */
static inline tree
ipa_get_jf_constant (struct ipa_jump_func *jfunc)
{
gcc_checking_assert (jfunc->type == IPA_JF_CONST);
return jfunc->value.constant;
}
/* Return the operand of a pass through jmp function JFUNC. */
static inline tree
ipa_get_jf_pass_through_operand (struct ipa_jump_func *jfunc)
{
gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
return jfunc->value.pass_through.operand;
}
/* Return the number of the caller's formal parameter that a pass through jump
function JFUNC refers to. */
static inline int
ipa_get_jf_pass_through_formal_id (struct ipa_jump_func *jfunc)
{
gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
return jfunc->value.pass_through.formal_id;
}
/* Return operation of a pass through jump function JFUNC. */
static inline enum tree_code
ipa_get_jf_pass_through_operation (struct ipa_jump_func *jfunc)
{
gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
return jfunc->value.pass_through.operation;
}
/* Return the offset of an ancestor jump function JFUNC. */
static inline HOST_WIDE_INT
ipa_get_jf_ancestor_offset (struct ipa_jump_func *jfunc)
{
gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
return jfunc->value.ancestor.offset;
}
/* Return the result type of an ancestor jump function JFUNC. */
static inline tree
ipa_get_jf_ancestor_type (struct ipa_jump_func *jfunc)
{
gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
return jfunc->value.ancestor.type;
}
/* Return the number of the caller's formal parameter that an ancestor jump
function JFUNC refers to. */
static inline int
ipa_get_jf_ancestor_formal_id (struct ipa_jump_func *jfunc)
{
gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
return jfunc->value.ancestor.formal_id;
}
/* Return the pfn part of a member pointer constant jump function JFUNC. */
static inline tree
ipa_get_jf_member_ptr_pfn (struct ipa_jump_func *jfunc)
{
gcc_checking_assert (jfunc->type == IPA_JF_CONST_MEMBER_PTR);
return jfunc->value.member_cst.pfn;
}
/* Summary describing a single formal parameter. */ /* Summary describing a single formal parameter. */
struct ipa_param_descriptor struct ipa_param_descriptor
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment