{
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);
{
struct type_change_info tci;
ao_ref ao;
+ bool entry_reached = false;
gcc_checking_assert (DECL_P (arg)
|| TREE_CODE (arg) == MEM_REF
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);
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.
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);
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;
*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;
}
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;
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);