diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3dcd84a66ef..084aa13494e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2014-07-08 Jan Hubicka + + * tree-ssa-alias.c (walk_aliased_vdefs_1): Add FUNCTION_ENTRY_REACHED + parameter. + (walk_aliased_vdefs): Likewise. + * tree-ssa-alias.h (walk_aliased_vdefs): Likewise. + * ipa-prop.c (stmt_may_be_vtbl_ptr_store): Skip clobbers + (detect_type_change_from_memory_writes): Check if entry was reached. + 2014-07-08 Richard Biener PR tree-optimization/61681 diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 34e766d18f1..c6dd610fc5d 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -638,7 +638,8 @@ stmt_may_be_vtbl_ptr_store (gimple stmt) { if (is_gimple_call (stmt)) return false; - /* TODO: Skip clobbers, doing so triggers problem in PR60306. */ + if (gimple_clobber_p (stmt)) + return false; else if (is_gimple_assign (stmt)) { tree lhs = gimple_assign_lhs (stmt); @@ -817,6 +818,7 @@ detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type, { struct type_change_info tci; ao_ref ao; + bool entry_reached = false; gcc_checking_assert (DECL_P (arg) || TREE_CODE (arg) == MEM_REF @@ -847,13 +849,16 @@ detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type, tci.multiple_types_encountered = false; walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change, - &tci, NULL); + &tci, NULL, &entry_reached); if (!tci.type_maybe_changed) return false; if (!tci.known_current_type || tci.multiple_types_encountered - || offset != 0) + || offset != 0 + /* When the walk reached function entry, it means that type + is set along some paths but not along others. */ + || entry_reached) jfunc->type = IPA_JF_UNKNOWN; else ipa_set_jf_known_type (jfunc, 0, tci.known_current_type, comp_type); diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 5cc9cb58f75..5a8f7bda50b 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -2643,6 +2643,9 @@ walk_non_aliased_vuses (ao_ref *ref, tree vuse, WALKER is called with REF, the current vdef and DATA. If WALKER returns true the walk is stopped, otherwise it continues. + If function entry is reached, FUNCTION_ENTRY_REACHED is set to true. + The pointer may be NULL and then we do not track this information. + At PHI nodes walk_aliased_vdefs forks into one walk for reach PHI argument (but only one walk continues on merge points), the return value is true if any of the walks was successful. @@ -2652,8 +2655,11 @@ walk_non_aliased_vuses (ao_ref *ref, tree vuse, static unsigned int walk_aliased_vdefs_1 (ao_ref *ref, tree vdef, bool (*walker)(ao_ref *, tree, void *), void *data, - bitmap *visited, unsigned int cnt) + bitmap *visited, unsigned int cnt, + bool *function_entry_reached) { + if (function_entry_reached) + *function_entry_reached = false; do { gimple def_stmt = SSA_NAME_DEF_STMT (vdef); @@ -2663,7 +2669,11 @@ walk_aliased_vdefs_1 (ao_ref *ref, tree vdef, return cnt; if (gimple_nop_p (def_stmt)) - return cnt; + { + if (function_entry_reached) + *function_entry_reached = true; + return cnt; + } else if (gimple_code (def_stmt) == GIMPLE_PHI) { unsigned i; @@ -2671,7 +2681,8 @@ walk_aliased_vdefs_1 (ao_ref *ref, tree vdef, *visited = BITMAP_ALLOC (NULL); for (i = 0; i < gimple_phi_num_args (def_stmt); ++i) cnt += walk_aliased_vdefs_1 (ref, gimple_phi_arg_def (def_stmt, i), - walker, data, visited, 0); + walker, data, visited, 0, + function_entry_reached); return cnt; } @@ -2690,7 +2701,8 @@ walk_aliased_vdefs_1 (ao_ref *ref, tree vdef, unsigned int walk_aliased_vdefs (ao_ref *ref, tree vdef, bool (*walker)(ao_ref *, tree, void *), void *data, - bitmap *visited) + bitmap *visited, + bool *function_entry_reached) { bitmap local_visited = NULL; unsigned int ret; @@ -2698,7 +2710,8 @@ walk_aliased_vdefs (ao_ref *ref, tree vdef, timevar_push (TV_ALIAS_STMT_WALK); ret = walk_aliased_vdefs_1 (ref, vdef, walker, data, - visited ? visited : &local_visited, 0); + visited ? visited : &local_visited, 0, + function_entry_reached); if (local_visited) BITMAP_FREE (local_visited); diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h index c0b472bd3be..e46f89e7e25 100644 --- a/gcc/tree-ssa-alias.h +++ b/gcc/tree-ssa-alias.h @@ -123,7 +123,8 @@ extern void *walk_non_aliased_vuses (ao_ref *, tree, void *); extern unsigned int walk_aliased_vdefs (ao_ref *, tree, bool (*)(ao_ref *, tree, void *), - void *, bitmap *); + void *, bitmap *, + bool *function_entry_reached = NULL); extern void dump_alias_info (FILE *); extern void debug_alias_info (void); extern void dump_points_to_solution (FILE *, struct pt_solution *);