aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2009-03-30 13:06:52 +0000
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2009-03-30 13:06:52 +0000
commitba3a7ba09d49083f5a2cd9284aa249993a705b21 (patch)
treea998017d535126ebe28c42696a5e141a4c23b459 /gcc
parenta3cad4e45e03b201be558abc0b2d7e3d974491f6 (diff)
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145291 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/cgraphbuild.c27
-rw-r--r--gcc/ipa-cp.c6
-rw-r--r--gcc/ipa-prop.c29
-rw-r--r--gcc/ipa-prop.h19
-rw-r--r--gcc/omp-low.c7
-rw-r--r--gcc/passes.c2
-rw-r--r--gcc/tree-dfa.c24
-rw-r--r--gcc/tree-inline.c4
-rw-r--r--gcc/tree-pass.h1
10 files changed, 102 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8f696913e03..1215863c452 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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):
diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index 3868712b3f7..c7d6aa72329 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -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 */
+ }
+};
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index f6864bb43fa..3fae0297a78 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -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;
}
}
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index c8db7d2bcd6..eab3aa7249a 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -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;
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index aca7bf8ef25..5943a2af6f4 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -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,
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index c56915f6546..40658760d38 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -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 ();
}
diff --git a/gcc/passes.c b/gcc/passes.c
index bf312f9171a..4e8944ae1f7 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -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);
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index 5241e64c929..082ac082bf3 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -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
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 37d9098034f..609a0818ad7 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -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
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 96239c494d8..2db0f226510 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -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;