Commit 133f9369 by Martin Jambor Committed by Martin Jambor

ipa-prop.h (jump_func_type): Rename IPA_UNKNOWN...

2009-03-30  Martin Jambor  <mjambor@suse.cz>

	* ipa-prop.h (jump_func_type): Rename IPA_UNKNOWN, IPA_CONST,
	IPA_CONST_MEMBER_PTR, and IPA_PASS_THROUGH to IPA_JF_UNKNOWN,
	IPA_JF_CONST, IPA_JF_CONST_MEMBER_PTR, and IPA_JF_PASS_THROUGH
	respectively.

	* tree-dfa.c (get_ref_base_and_extent): Return -1 maxsize if
	seen_variable_array_ref while also traversing a union.

	* tree-inline.c (optimize_inline_calls): Do not call
	cgraph_node_remove_callees.
	* cgraphbuild.c (remove_cgraph_callee_edges): New function.
	(pass_remove_cgraph_callee_edges): New variable.
	* passes.c (init_optimization_passes): Add
	pass_remove_cgraph_callee_edges after early inlining and before all
	late intraprocedural passes.

	* omp-low.c (expand_omp_taskreg): Always set current_function_decl.

From-SVN: r145291
parent 77a08224
2009-03-30 Martin Jambor <mjambor@suse.cz>
* ipa-prop.h (jump_func_type): Rename IPA_UNKNOWN, IPA_CONST,
IPA_CONST_MEMBER_PTR, and IPA_PASS_THROUGH to IPA_JF_UNKNOWN,
IPA_JF_CONST, IPA_JF_CONST_MEMBER_PTR, and IPA_JF_PASS_THROUGH
respectively.
* tree-dfa.c (get_ref_base_and_extent): Return -1 maxsize if
seen_variable_array_ref while also traversing a union.
* tree-inline.c (optimize_inline_calls): Do not call
cgraph_node_remove_callees.
* cgraphbuild.c (remove_cgraph_callee_edges): New function.
(pass_remove_cgraph_callee_edges): New variable.
* passes.c (init_optimization_passes): Add
pass_remove_cgraph_callee_edges after early inlining and before all
late intraprocedural passes.
* omp-low.c (expand_omp_taskreg): Always set current_function_decl.
2009-03-30 Paolo Bonzini <bonzini@gnu.org> 2009-03-30 Paolo Bonzini <bonzini@gnu.org>
* config/sparc/sparc.md (*nand<V64mode>_vis, *nand<V32mode>_vis): * config/sparc/sparc.md (*nand<V64mode>_vis, *nand<V32mode>_vis):
......
...@@ -251,3 +251,30 @@ struct gimple_opt_pass pass_rebuild_cgraph_edges = ...@@ -251,3 +251,30 @@ struct gimple_opt_pass pass_rebuild_cgraph_edges =
0, /* todo_flags_finish */ 0, /* todo_flags_finish */
} }
}; };
static unsigned int
remove_cgraph_callee_edges (void)
{
cgraph_node_remove_callees (cgraph_node (current_function_decl));
return 0;
}
struct gimple_opt_pass pass_remove_cgraph_callee_edges =
{
{
GIMPLE_PASS,
NULL, /* name */
NULL, /* gate */
remove_cgraph_callee_edges, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
0, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0, /* todo_flags_finish */
}
};
...@@ -310,12 +310,12 @@ static void ...@@ -310,12 +310,12 @@ static void
ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat, ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat,
struct ipa_jump_func *jfunc) struct ipa_jump_func *jfunc)
{ {
if (jfunc->type == IPA_CONST) if (jfunc->type == IPA_JF_CONST)
{ {
lat->type = IPA_CONST_VALUE; lat->type = IPA_CONST_VALUE;
lat->constant = jfunc->value.constant; lat->constant = jfunc->value.constant;
} }
else if (jfunc->type == IPA_PASS_THROUGH) else if (jfunc->type == IPA_JF_PASS_THROUGH)
{ {
struct ipcp_lattice *caller_lat; struct ipcp_lattice *caller_lat;
...@@ -916,7 +916,7 @@ ipcp_need_redirect_p (struct cgraph_edge *cs) ...@@ -916,7 +916,7 @@ ipcp_need_redirect_p (struct cgraph_edge *cs)
if (ipcp_lat_is_const (lat)) if (ipcp_lat_is_const (lat))
{ {
jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i); jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
if (jump_func->type != IPA_CONST) if (jump_func->type != IPA_JF_CONST)
return true; return true;
} }
} }
......
...@@ -293,16 +293,16 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node) ...@@ -293,16 +293,16 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
type = jump_func->type; type = jump_func->type;
fprintf (f, " param %d: ", i); fprintf (f, " param %d: ", i);
if (type == IPA_UNKNOWN) if (type == IPA_JF_UNKNOWN)
fprintf (f, "UNKNOWN\n"); fprintf (f, "UNKNOWN\n");
else if (type == IPA_CONST) else if (type == IPA_JF_CONST)
{ {
tree val = jump_func->value.constant; tree val = jump_func->value.constant;
fprintf (f, "CONST: "); fprintf (f, "CONST: ");
print_generic_expr (f, val, 0); print_generic_expr (f, val, 0);
fprintf (f, "\n"); fprintf (f, "\n");
} }
else if (type == IPA_CONST_MEMBER_PTR) else if (type == IPA_JF_CONST_MEMBER_PTR)
{ {
fprintf (f, "CONST MEMBER PTR: "); fprintf (f, "CONST MEMBER PTR: ");
print_generic_expr (f, jump_func->value.member_cst.pfn, 0); print_generic_expr (f, jump_func->value.member_cst.pfn, 0);
...@@ -310,7 +310,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node) ...@@ -310,7 +310,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
print_generic_expr (f, jump_func->value.member_cst.delta, 0); print_generic_expr (f, jump_func->value.member_cst.delta, 0);
fprintf (f, "\n"); fprintf (f, "\n");
} }
else if (type == IPA_PASS_THROUGH) else if (type == IPA_JF_PASS_THROUGH)
{ {
fprintf (f, "PASS THROUGH: "); fprintf (f, "PASS THROUGH: ");
fprintf (f, "%d\n", jump_func->value.formal_id); fprintf (f, "%d\n", jump_func->value.formal_id);
...@@ -353,7 +353,7 @@ compute_scalar_jump_functions (struct ipa_node_params *info, ...@@ -353,7 +353,7 @@ compute_scalar_jump_functions (struct ipa_node_params *info,
if (is_gimple_ip_invariant (arg)) if (is_gimple_ip_invariant (arg))
{ {
functions[num].type = IPA_CONST; functions[num].type = IPA_JF_CONST;
functions[num].value.constant = arg; functions[num].value.constant = arg;
} }
else if ((TREE_CODE (arg) == SSA_NAME) && SSA_NAME_IS_DEFAULT_DEF (arg)) else if ((TREE_CODE (arg) == SSA_NAME) && SSA_NAME_IS_DEFAULT_DEF (arg))
...@@ -362,7 +362,7 @@ compute_scalar_jump_functions (struct ipa_node_params *info, ...@@ -362,7 +362,7 @@ compute_scalar_jump_functions (struct ipa_node_params *info,
if (index >= 0) if (index >= 0)
{ {
functions[num].type = IPA_PASS_THROUGH; functions[num].type = IPA_JF_PASS_THROUGH;
functions[num].value.formal_id = index; functions[num].value.formal_id = index;
} }
} }
...@@ -430,7 +430,7 @@ compute_pass_through_member_ptrs (struct ipa_node_params *info, ...@@ -430,7 +430,7 @@ compute_pass_through_member_ptrs (struct ipa_node_params *info,
gcc_assert (index >=0); gcc_assert (index >=0);
if (!ipa_is_param_modified (info, index)) if (!ipa_is_param_modified (info, index))
{ {
functions[num].type = IPA_PASS_THROUGH; functions[num].type = IPA_JF_PASS_THROUGH;
functions[num].value.formal_id = index; functions[num].value.formal_id = index;
} }
else else
...@@ -451,7 +451,7 @@ static void ...@@ -451,7 +451,7 @@ static void
fill_member_ptr_cst_jump_function (struct ipa_jump_func *jfunc, fill_member_ptr_cst_jump_function (struct ipa_jump_func *jfunc,
tree pfn, tree delta) tree pfn, tree delta)
{ {
jfunc->type = IPA_CONST_MEMBER_PTR; jfunc->type = IPA_JF_CONST_MEMBER_PTR;
jfunc->value.member_cst.pfn = pfn; jfunc->value.member_cst.pfn = pfn;
jfunc->value.member_cst.delta = delta; jfunc->value.member_cst.delta = delta;
} }
...@@ -545,7 +545,7 @@ compute_cst_member_ptr_arguments (struct ipa_jump_func *functions, ...@@ -545,7 +545,7 @@ compute_cst_member_ptr_arguments (struct ipa_jump_func *functions,
{ {
arg = gimple_call_arg (call, num); arg = gimple_call_arg (call, num);
if (functions[num].type == IPA_UNKNOWN if (functions[num].type == IPA_JF_UNKNOWN
&& type_like_member_ptr_p (TREE_TYPE (arg), &method_field, && type_like_member_ptr_p (TREE_TYPE (arg), &method_field,
&delta_field)) &delta_field))
determine_cst_member_ptr (call, arg, method_field, delta_field, determine_cst_member_ptr (call, arg, method_field, delta_field,
...@@ -885,7 +885,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs, ...@@ -885,7 +885,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
{ {
struct ipa_jump_func *src, *dst = ipa_get_ith_jump_func (args, i); struct ipa_jump_func *src, *dst = ipa_get_ith_jump_func (args, i);
if (dst->type != IPA_PASS_THROUGH) if (dst->type != IPA_JF_PASS_THROUGH)
continue; continue;
/* We must check range due to calls with variable number of arguments: */ /* We must check range due to calls with variable number of arguments: */
...@@ -910,7 +910,7 @@ print_edge_addition_message (FILE *f, struct ipa_param_call_note *nt, ...@@ -910,7 +910,7 @@ print_edge_addition_message (FILE *f, struct ipa_param_call_note *nt,
struct cgraph_node *node) struct cgraph_node *node)
{ {
fprintf (f, "ipa-prop: Discovered an indirect call to a known target ("); fprintf (f, "ipa-prop: Discovered an indirect call to a known target (");
if (jfunc->type == IPA_CONST_MEMBER_PTR) if (jfunc->type == IPA_JF_CONST_MEMBER_PTR)
{ {
print_node_brief (f, "", jfunc->value.member_cst.pfn, 0); print_node_brief (f, "", jfunc->value.member_cst.pfn, 0);
print_node_brief (f, ", ", jfunc->value.member_cst.delta, 0); print_node_brief (f, ", ", jfunc->value.member_cst.delta, 0);
...@@ -953,16 +953,17 @@ update_call_notes_after_inlining (struct cgraph_edge *cs, ...@@ -953,16 +953,17 @@ update_call_notes_after_inlining (struct cgraph_edge *cs,
} }
jfunc = ipa_get_ith_jump_func (top, nt->formal_id); jfunc = ipa_get_ith_jump_func (top, nt->formal_id);
if (jfunc->type == IPA_PASS_THROUGH) if (jfunc->type == IPA_JF_PASS_THROUGH)
nt->formal_id = jfunc->value.formal_id; nt->formal_id = jfunc->value.formal_id;
else if (jfunc->type == IPA_CONST || jfunc->type == IPA_CONST_MEMBER_PTR) else if (jfunc->type == IPA_JF_CONST
|| jfunc->type == IPA_JF_CONST_MEMBER_PTR)
{ {
struct cgraph_node *callee; struct cgraph_node *callee;
struct cgraph_edge *new_indirect_edge; struct cgraph_edge *new_indirect_edge;
tree decl; tree decl;
nt->processed = true; nt->processed = true;
if (jfunc->type == IPA_CONST_MEMBER_PTR) if (jfunc->type == IPA_JF_CONST_MEMBER_PTR)
decl = jfunc->value.member_cst.pfn; decl = jfunc->value.member_cst.pfn;
else else
decl = jfunc->value.constant; decl = jfunc->value.constant;
......
...@@ -25,21 +25,24 @@ along with GCC; see the file COPYING3. If not see ...@@ -25,21 +25,24 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h" #include "cgraph.h"
/* The following definitions and interfaces are used by /* The following definitions and interfaces are used by
interprocedural analyses. */ interprocedural analyses or parameters. */
/* ipa-prop.c stuff (ipa-cp, indirect inlining): */
/* A jump function for a callsite represents the values passed as actual /* A jump function for a callsite represents the values passed as actual
arguments of the callsite. There are three main types of values : arguments of the callsite. There are three main types of values :
Formal - the caller's formal parameter is passed as an actual argument. Formal - the caller's formal parameter is passed as an actual argument.
Constant - a constant is passed as an actual argument. Constant - a constant is passed as an actual argument.
Unknown - neither of the above. Unknown - neither of the above.
Integer and real constants are represented as IPA_CONST. Integer and real constants are represented as IPA_JF_CONST.
Finally, IPA_CONST_MEMBER_PTR stands for C++ member pointers constants. */ Finally, IPA_JF_CONST_MEMBER_PTR stands for C++ member pointers
constants. */
enum jump_func_type enum jump_func_type
{ {
IPA_UNKNOWN = 0, /* newly allocated and zeroed jump functions default */ IPA_JF_UNKNOWN = 0, /* newly allocated and zeroed jump functions default */
IPA_CONST, IPA_JF_CONST,
IPA_CONST_MEMBER_PTR, IPA_JF_CONST_MEMBER_PTR,
IPA_PASS_THROUGH IPA_JF_PASS_THROUGH
}; };
/* All formal parameters in the program have a lattice associated with it /* All formal parameters in the program have a lattice associated with it
...@@ -50,7 +53,7 @@ enum jump_func_type ...@@ -50,7 +53,7 @@ enum jump_func_type
IPA_CONST_VALUE - simple scalar constant, IPA_CONST_VALUE - simple scalar constant,
Cval of formal f will have a constant value if all callsites to this Cval of formal f will have a constant value if all callsites to this
function have the same constant value passed to f. function have the same constant value passed to f.
Integer and real constants are represented as IPA_CONST. */ Integer and real constants are represented as IPA_CONST_VALUE. */
enum ipa_lattice_type enum ipa_lattice_type
{ {
IPA_BOTTOM, IPA_BOTTOM,
......
...@@ -3244,6 +3244,7 @@ expand_omp_taskreg (struct omp_region *region) ...@@ -3244,6 +3244,7 @@ expand_omp_taskreg (struct omp_region *region)
basic_block entry_bb, exit_bb, new_bb; basic_block entry_bb, exit_bb, new_bb;
struct function *child_cfun; struct function *child_cfun;
tree child_fn, block, t, ws_args, *tp; tree child_fn, block, t, ws_args, *tp;
tree save_current;
gimple_stmt_iterator gsi; gimple_stmt_iterator gsi;
gimple entry_stmt, stmt; gimple entry_stmt, stmt;
edge e; edge e;
...@@ -3429,6 +3430,8 @@ expand_omp_taskreg (struct omp_region *region) ...@@ -3429,6 +3430,8 @@ expand_omp_taskreg (struct omp_region *region)
/* Fix the callgraph edges for child_cfun. Those for cfun will be /* Fix the callgraph edges for child_cfun. Those for cfun will be
fixed in a following pass. */ fixed in a following pass. */
push_cfun (child_cfun); push_cfun (child_cfun);
save_current = current_function_decl;
current_function_decl = child_fn;
if (optimize) if (optimize)
optimize_omp_library_calls (entry_stmt); optimize_omp_library_calls (entry_stmt);
rebuild_cgraph_edges (); rebuild_cgraph_edges ();
...@@ -3440,16 +3443,14 @@ expand_omp_taskreg (struct omp_region *region) ...@@ -3440,16 +3443,14 @@ expand_omp_taskreg (struct omp_region *region)
if (flag_exceptions) if (flag_exceptions)
{ {
basic_block bb; basic_block bb;
tree save_current = current_function_decl;
bool changed = false; bool changed = false;
current_function_decl = child_fn;
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
changed |= gimple_purge_dead_eh_edges (bb); changed |= gimple_purge_dead_eh_edges (bb);
if (changed) if (changed)
cleanup_tree_cfg (); cleanup_tree_cfg ();
current_function_decl = save_current;
} }
current_function_decl = save_current;
pop_cfun (); pop_cfun ();
} }
......
...@@ -551,6 +551,7 @@ init_optimization_passes (void) ...@@ -551,6 +551,7 @@ init_optimization_passes (void)
struct opt_pass **p = &pass_all_early_optimizations.pass.sub; struct opt_pass **p = &pass_all_early_optimizations.pass.sub;
NEXT_PASS (pass_rebuild_cgraph_edges); NEXT_PASS (pass_rebuild_cgraph_edges);
NEXT_PASS (pass_early_inline); NEXT_PASS (pass_early_inline);
NEXT_PASS (pass_remove_cgraph_callee_edges);
NEXT_PASS (pass_rename_ssa_copies); NEXT_PASS (pass_rename_ssa_copies);
NEXT_PASS (pass_ccp); NEXT_PASS (pass_ccp);
NEXT_PASS (pass_forwprop); NEXT_PASS (pass_forwprop);
...@@ -587,6 +588,7 @@ init_optimization_passes (void) ...@@ -587,6 +588,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_all_optimizations); NEXT_PASS (pass_all_optimizations);
{ {
struct opt_pass **p = &pass_all_optimizations.pass.sub; struct opt_pass **p = &pass_all_optimizations.pass.sub;
NEXT_PASS (pass_remove_cgraph_callee_edges);
/* Initial scalar cleanups before alias computation. /* Initial scalar cleanups before alias computation.
They ensure memory accesses are not indirect wherever possible. */ They ensure memory accesses are not indirect wherever possible. */
NEXT_PASS (pass_strip_predict_hints); NEXT_PASS (pass_strip_predict_hints);
......
...@@ -801,6 +801,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, ...@@ -801,6 +801,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
tree size_tree = NULL_TREE; tree size_tree = NULL_TREE;
HOST_WIDE_INT bit_offset = 0; HOST_WIDE_INT bit_offset = 0;
bool seen_variable_array_ref = false; bool seen_variable_array_ref = false;
bool seen_union = false;
gcc_assert (!SSA_VAR_P (exp)); gcc_assert (!SSA_VAR_P (exp));
...@@ -844,6 +845,9 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, ...@@ -844,6 +845,9 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
tree field = TREE_OPERAND (exp, 1); tree field = TREE_OPERAND (exp, 1);
tree this_offset = component_ref_field_offset (exp); tree this_offset = component_ref_field_offset (exp);
if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == UNION_TYPE)
seen_union = true;
if (this_offset && TREE_CODE (this_offset) == INTEGER_CST) if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
{ {
HOST_WIDE_INT hthis_offset = tree_low_cst (this_offset, 0); HOST_WIDE_INT hthis_offset = tree_low_cst (this_offset, 0);
...@@ -934,12 +938,22 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, ...@@ -934,12 +938,22 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
where we do not know maxsize for variable index accesses to where we do not know maxsize for variable index accesses to
the array. The simplest way to conservatively deal with this the array. The simplest way to conservatively deal with this
is to punt in the case that offset + maxsize reaches the is to punt in the case that offset + maxsize reaches the
base type boundary. */ base type boundary.
Unfortunately this is difficult to determine reliably when unions are
involved and so we are conservative in such cases.
FIXME: This approach may be too conservative, we probably want to at least
check that the union is the last field/element at its level or even
propagate the calculated offsets back up the access chain and check
there. */
if (seen_variable_array_ref if (seen_variable_array_ref
&& maxsize != -1 && (seen_union
|| (maxsize != -1
&& host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1) && host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
&& bit_offset + maxsize && bit_offset + maxsize
== (signed)TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp)))) == (signed) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))))
maxsize = -1; maxsize = -1;
/* ??? Due to negative offsets in ARRAY_REF we can end up with /* ??? Due to negative offsets in ARRAY_REF we can end up with
......
...@@ -3639,10 +3639,6 @@ optimize_inline_calls (tree fn) ...@@ -3639,10 +3639,6 @@ optimize_inline_calls (tree fn)
/* Renumber the lexical scoping (non-code) blocks consecutively. */ /* Renumber the lexical scoping (non-code) blocks consecutively. */
number_blocks (fn); number_blocks (fn);
/* We are not going to maintain the cgraph edges up to date.
Kill it so it won't confuse us. */
cgraph_node_remove_callees (id.dst_node);
fold_cond_expr_cond (); fold_cond_expr_cond ();
/* It would be nice to check SSA/CFG/statement consistency here, but it is /* It would be nice to check SSA/CFG/statement consistency here, but it is
......
...@@ -389,6 +389,7 @@ extern struct gimple_opt_pass pass_uncprop; ...@@ -389,6 +389,7 @@ extern struct gimple_opt_pass pass_uncprop;
extern struct gimple_opt_pass pass_return_slot; extern struct gimple_opt_pass pass_return_slot;
extern struct gimple_opt_pass pass_reassoc; extern struct gimple_opt_pass pass_reassoc;
extern struct gimple_opt_pass pass_rebuild_cgraph_edges; extern struct gimple_opt_pass pass_rebuild_cgraph_edges;
extern struct gimple_opt_pass pass_remove_cgraph_callee_edges;
extern struct gimple_opt_pass pass_build_cgraph_edges; extern struct gimple_opt_pass pass_build_cgraph_edges;
extern struct gimple_opt_pass pass_reset_cc_flags; extern struct gimple_opt_pass pass_reset_cc_flags;
extern struct gimple_opt_pass pass_local_pure_const; extern struct gimple_opt_pass pass_local_pure_const;
......
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