https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036

--- Comment #23 from Andrew Macleod <amacleod at redhat dot com> ---
(In reply to Richard Biener from comment #19)

>   <bb 2> [local count: 1073741824]:
>   _1 = vptr_14(D) == 0;
>   _2 = ownvptr_15(D) != 0;
>   _3 = _1 | _2;
>   if (_3 != 0)
>     goto <bb 4>; [67.00%]
>   else
>     goto <bb 3>; [33.00%]
> 
>   <bb 4> [local count: 719407024]:
>   if (vptr_14(D) != 0)
>     goto <bb 5>; [25.37%]
>   else
>     goto <bb 9>; [74.63%]
> 
>   <bb 5> [local count: 182536112]:
>   if (_2 != 0)
>     goto <bb 7>; [80.00%]
>   else
>     goto <bb 6>; [20.00%]
> 
> from _3 != 0 && vptr_14(D) != 0 follows _2 != 0.  Why do we not see this?

Its complex. Too many layers of indirection for it to currently be
automatically detected.

>From _3 != 0 && vptr_14(D) != 0 it follows that _2 != 0. Why don’t we derive
that?

The issue is dependency structure. _2 depends only on ownvptr_15, and nothing
directly ties _2 to vptr_14. The only connection is indirect via _3 = _1 | _2,
where _1 = (vptr_14 == 0).

When vptr_14 is refined on edge 4→5 to ~[0,0], we can calculate _1 = [0,0], but
that requires explicitly querying _1. Since _3 itself doesn’t change on that
edge, GORI has no trigger to revisit _3, and thus no reason to re-evaluate _2.

Ranger tracks forward dependencies (e.g. _3 depends on _1 and _2), but it does
not track reverse dependencies. So when vptr_14 changes, we don’t know that _3
may need recomputation unless _3 is *explicitly* queried. And even if _3 were
recomputed, there’s no mechanism to propagate that refinement sideways to _2,
since _2 is not directly dependent on _3.

Logically this is straightforward, but efficiently detecting and propagating
these second-order effects without providing the reverse dependencies is
non-trivial.

Reply via email to