diff options
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r-- | gcc/tree-ssa-alias.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index fd78105..7554e20 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -1486,9 +1486,27 @@ nonoverlapping_refs_since_match_p (tree match1, tree ref1, .nonoverlapping_refs_since_match_p_no_alias; return 1; } - partial_overlap = false; if (cmp == -1) - seen_unmatched_ref_p = true; + { + seen_unmatched_ref_p = true; + /* We can not maintain the invariant that bases are either + same or completely disjoint. However we can still recover + from type based alias analysis if we reach referneces to + same sizes. We do not attempt to match array sizes, so + just finish array walking and look for component refs. */ + if (!flag_strict_aliasing) + { + ++alias_stats.nonoverlapping_refs_since_match_p_may_alias; + return -1; + } + for (i++; i < narray_refs1; i++) + { + component_refs1.pop (); + component_refs2.pop (); + } + break; + } + partial_overlap = false; } } @@ -1503,7 +1521,14 @@ nonoverlapping_refs_since_match_p (tree match1, tree ref1, } ref1 = component_refs1.pop (); if (TREE_CODE (ref1) != COMPONENT_REF) - seen_unmatched_ref_p = true; + { + seen_unmatched_ref_p = true; + if (!flag_strict_aliasing) + { + ++alias_stats.nonoverlapping_refs_since_match_p_may_alias; + return -1; + } + } } while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref1, 0)))); @@ -1517,7 +1542,14 @@ nonoverlapping_refs_since_match_p (tree match1, tree ref1, } ref2 = component_refs2.pop (); if (TREE_CODE (ref2) != COMPONENT_REF) - seen_unmatched_ref_p = true; + { + if (!flag_strict_aliasing) + { + ++alias_stats.nonoverlapping_refs_since_match_p_may_alias; + return -1; + } + seen_unmatched_ref_p = true; + } } while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref2, 0)))); @@ -1537,6 +1569,8 @@ nonoverlapping_refs_since_match_p (tree match1, tree ref1, partial_overlap = false; + gcc_checking_assert (!seen_unmatched_ref_p || flag_strict_aliasing); + /* If we skipped array refs on type of different sizes, we can no longer be sure that there are not partial overlaps. */ if (seen_unmatched_ref_p |