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
This commit is contained in:
parent
77a08224ee
commit
133f9369c3
10 changed files with 102 additions and 37 deletions
|
@ -1,3 +1,23 @@
|
|||
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>
|
||||
|
||||
* config/sparc/sparc.md (*nand<V64mode>_vis, *nand<V32mode>_vis):
|
||||
|
|
|
@ -251,3 +251,30 @@ struct gimple_opt_pass pass_rebuild_cgraph_edges =
|
|||
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
|
|||
ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat,
|
||||
struct ipa_jump_func *jfunc)
|
||||
{
|
||||
if (jfunc->type == IPA_CONST)
|
||||
if (jfunc->type == IPA_JF_CONST)
|
||||
{
|
||||
lat->type = IPA_CONST_VALUE;
|
||||
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;
|
||||
|
||||
|
@ -916,7 +916,7 @@ ipcp_need_redirect_p (struct cgraph_edge *cs)
|
|||
if (ipcp_lat_is_const (lat))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -293,16 +293,16 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
|
|||
type = jump_func->type;
|
||||
|
||||
fprintf (f, " param %d: ", i);
|
||||
if (type == IPA_UNKNOWN)
|
||||
if (type == IPA_JF_UNKNOWN)
|
||||
fprintf (f, "UNKNOWN\n");
|
||||
else if (type == IPA_CONST)
|
||||
else if (type == IPA_JF_CONST)
|
||||
{
|
||||
tree val = jump_func->value.constant;
|
||||
fprintf (f, "CONST: ");
|
||||
print_generic_expr (f, val, 0);
|
||||
fprintf (f, "\n");
|
||||
}
|
||||
else if (type == IPA_CONST_MEMBER_PTR)
|
||||
else if (type == IPA_JF_CONST_MEMBER_PTR)
|
||||
{
|
||||
fprintf (f, "CONST MEMBER PTR: ");
|
||||
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)
|
|||
print_generic_expr (f, jump_func->value.member_cst.delta, 0);
|
||||
fprintf (f, "\n");
|
||||
}
|
||||
else if (type == IPA_PASS_THROUGH)
|
||||
else if (type == IPA_JF_PASS_THROUGH)
|
||||
{
|
||||
fprintf (f, "PASS THROUGH: ");
|
||||
fprintf (f, "%d\n", jump_func->value.formal_id);
|
||||
|
@ -353,7 +353,7 @@ compute_scalar_jump_functions (struct ipa_node_params *info,
|
|||
|
||||
if (is_gimple_ip_invariant (arg))
|
||||
{
|
||||
functions[num].type = IPA_CONST;
|
||||
functions[num].type = IPA_JF_CONST;
|
||||
functions[num].value.constant = 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,
|
|||
|
||||
if (index >= 0)
|
||||
{
|
||||
functions[num].type = IPA_PASS_THROUGH;
|
||||
functions[num].type = IPA_JF_PASS_THROUGH;
|
||||
functions[num].value.formal_id = index;
|
||||
}
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ compute_pass_through_member_ptrs (struct ipa_node_params *info,
|
|||
gcc_assert (index >=0);
|
||||
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;
|
||||
}
|
||||
else
|
||||
|
@ -451,7 +451,7 @@ static void
|
|||
fill_member_ptr_cst_jump_function (struct ipa_jump_func *jfunc,
|
||||
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.delta = delta;
|
||||
}
|
||||
|
@ -545,7 +545,7 @@ compute_cst_member_ptr_arguments (struct ipa_jump_func *functions,
|
|||
{
|
||||
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,
|
||||
&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,
|
|||
{
|
||||
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;
|
||||
|
||||
/* 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,
|
|||
struct cgraph_node *node)
|
||||
{
|
||||
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.delta, 0);
|
||||
|
@ -953,16 +953,17 @@ update_call_notes_after_inlining (struct cgraph_edge *cs,
|
|||
}
|
||||
|
||||
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;
|
||||
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_edge *new_indirect_edge;
|
||||
tree decl;
|
||||
|
||||
nt->processed = true;
|
||||
if (jfunc->type == IPA_CONST_MEMBER_PTR)
|
||||
if (jfunc->type == IPA_JF_CONST_MEMBER_PTR)
|
||||
decl = jfunc->value.member_cst.pfn;
|
||||
else
|
||||
decl = jfunc->value.constant;
|
||||
|
|
|
@ -25,21 +25,24 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "cgraph.h"
|
||||
|
||||
/* 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
|
||||
arguments of the callsite. There are three main types of values :
|
||||
Formal - the caller's formal parameter is passed as an actual argument.
|
||||
Constant - a constant is passed as an actual argument.
|
||||
Unknown - neither of the above.
|
||||
Integer and real constants are represented as IPA_CONST.
|
||||
Finally, IPA_CONST_MEMBER_PTR stands for C++ member pointers constants. */
|
||||
Integer and real constants are represented as IPA_JF_CONST.
|
||||
Finally, IPA_JF_CONST_MEMBER_PTR stands for C++ member pointers
|
||||
constants. */
|
||||
enum jump_func_type
|
||||
{
|
||||
IPA_UNKNOWN = 0, /* newly allocated and zeroed jump functions default */
|
||||
IPA_CONST,
|
||||
IPA_CONST_MEMBER_PTR,
|
||||
IPA_PASS_THROUGH
|
||||
IPA_JF_UNKNOWN = 0, /* newly allocated and zeroed jump functions default */
|
||||
IPA_JF_CONST,
|
||||
IPA_JF_CONST_MEMBER_PTR,
|
||||
IPA_JF_PASS_THROUGH
|
||||
};
|
||||
|
||||
/* All formal parameters in the program have a lattice associated with it
|
||||
|
@ -50,7 +53,7 @@ enum jump_func_type
|
|||
IPA_CONST_VALUE - simple scalar constant,
|
||||
Cval of formal f will have a constant value if all callsites to this
|
||||
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
|
||||
{
|
||||
IPA_BOTTOM,
|
||||
|
|
|
@ -3244,6 +3244,7 @@ expand_omp_taskreg (struct omp_region *region)
|
|||
basic_block entry_bb, exit_bb, new_bb;
|
||||
struct function *child_cfun;
|
||||
tree child_fn, block, t, ws_args, *tp;
|
||||
tree save_current;
|
||||
gimple_stmt_iterator gsi;
|
||||
gimple entry_stmt, stmt;
|
||||
edge e;
|
||||
|
@ -3429,6 +3430,8 @@ expand_omp_taskreg (struct omp_region *region)
|
|||
/* Fix the callgraph edges for child_cfun. Those for cfun will be
|
||||
fixed in a following pass. */
|
||||
push_cfun (child_cfun);
|
||||
save_current = current_function_decl;
|
||||
current_function_decl = child_fn;
|
||||
if (optimize)
|
||||
optimize_omp_library_calls (entry_stmt);
|
||||
rebuild_cgraph_edges ();
|
||||
|
@ -3440,16 +3443,14 @@ expand_omp_taskreg (struct omp_region *region)
|
|||
if (flag_exceptions)
|
||||
{
|
||||
basic_block bb;
|
||||
tree save_current = current_function_decl;
|
||||
bool changed = false;
|
||||
|
||||
current_function_decl = child_fn;
|
||||
FOR_EACH_BB (bb)
|
||||
changed |= gimple_purge_dead_eh_edges (bb);
|
||||
if (changed)
|
||||
cleanup_tree_cfg ();
|
||||
current_function_decl = save_current;
|
||||
}
|
||||
current_function_decl = save_current;
|
||||
pop_cfun ();
|
||||
}
|
||||
|
||||
|
|
|
@ -551,6 +551,7 @@ init_optimization_passes (void)
|
|||
struct opt_pass **p = &pass_all_early_optimizations.pass.sub;
|
||||
NEXT_PASS (pass_rebuild_cgraph_edges);
|
||||
NEXT_PASS (pass_early_inline);
|
||||
NEXT_PASS (pass_remove_cgraph_callee_edges);
|
||||
NEXT_PASS (pass_rename_ssa_copies);
|
||||
NEXT_PASS (pass_ccp);
|
||||
NEXT_PASS (pass_forwprop);
|
||||
|
@ -587,6 +588,7 @@ init_optimization_passes (void)
|
|||
NEXT_PASS (pass_all_optimizations);
|
||||
{
|
||||
struct opt_pass **p = &pass_all_optimizations.pass.sub;
|
||||
NEXT_PASS (pass_remove_cgraph_callee_edges);
|
||||
/* Initial scalar cleanups before alias computation.
|
||||
They ensure memory accesses are not indirect wherever possible. */
|
||||
NEXT_PASS (pass_strip_predict_hints);
|
||||
|
|
|
@ -801,6 +801,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
|||
tree size_tree = NULL_TREE;
|
||||
HOST_WIDE_INT bit_offset = 0;
|
||||
bool seen_variable_array_ref = false;
|
||||
bool seen_union = false;
|
||||
|
||||
gcc_assert (!SSA_VAR_P (exp));
|
||||
|
||||
|
@ -844,6 +845,9 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
|||
tree field = TREE_OPERAND (exp, 1);
|
||||
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)
|
||||
{
|
||||
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,
|
|||
where we do not know maxsize for variable index accesses to
|
||||
the array. The simplest way to conservatively deal with this
|
||||
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
|
||||
&& maxsize != -1
|
||||
&& host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
|
||||
&& bit_offset + maxsize
|
||||
== (signed)TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))
|
||||
&& (seen_union
|
||||
|| (maxsize != -1
|
||||
&& host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
|
||||
&& bit_offset + maxsize
|
||||
== (signed) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))))
|
||||
maxsize = -1;
|
||||
|
||||
/* ??? Due to negative offsets in ARRAY_REF we can end up with
|
||||
|
|
|
@ -3639,10 +3639,6 @@ optimize_inline_calls (tree fn)
|
|||
/* Renumber the lexical scoping (non-code) blocks consecutively. */
|
||||
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 ();
|
||||
|
||||
/* 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;
|
|||
extern struct gimple_opt_pass pass_return_slot;
|
||||
extern struct gimple_opt_pass pass_reassoc;
|
||||
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_reset_cc_flags;
|
||||
extern struct gimple_opt_pass pass_local_pure_const;
|
||||
|
|
Loading…
Add table
Reference in a new issue