On Wed, Jun 9, 2021 at 5:24 PM Andrew MacLeod <amacl...@redhat.com> wrote:
>
> On 6/9/21 7:48 AM, Richard Biener wrote:
> > On Tue, Jun 8, 2021 at 4:48 PM Andrew MacLeod <amacl...@redhat.com> wrote:
> >>
> >>
> >> Richard.
> >>
> >>>> Andrew
> >>>>
> >> OK, so this would be the simple way I'd tackle this in gcc11. This
> >> should be quite safe.  Just treat debug_stmts as if they are not stmts..
> >> and make a global query.   EVRP will still provide a contextual range as
> >> good as it ever did, but it wont trigger ranger lookups on debug uses
> >> any more.
> >>
> >> It bootstraps on x86_64-pc-linux-gnu.  Is there a process other than
> >> getting the OK to check this into the gcc 11 branch?  Does it go into
> >> releases/gcc-11 ?
> > it would go into releases/gcc-11, yes.
> >
> > Now,
> >
> > diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
> > index 6158a754dd6..fd7fa5e3dbb 100644
> > --- a/gcc/gimple-range.cc
> > +++ b/gcc/gimple-range.cc
> > @@ -945,7 +945,7 @@ gimple_ranger::range_of_expr (irange &r, tree
> > expr, gimple *stmt)
> >       return get_tree_range (r, expr);
> >
> >     // If there is no statement, just get the global value.
> > -  if (!stmt)
> > +  if (!stmt || is_gimple_debug (stmt))
> >       {
> >
> > unfortunately the function is not documented so I'm just guessing here - why
> > do we end up passing in a debug stmt as 'stmt'?  (how should expr and stmt
> > relate?)  So isn't it better to do this check before
> >
> >    if (!gimple_range_ssa_p (expr))
> >      return get_tree_range (r, expr);
> This parts just handles the non-ssa names, so constants, types , things
> for which there is no lookup involved.. At least in GCC 11.
> >
> > or even more better, assert we don't get a debug stmt here and fixup whoever
> > calls range_of_expr to not do that for debug stmts?  When I add this
> > assertion not even libgcc can configure...  backtraces look like
>
> range_of_expr is the basic API for asking for the range of EXPR as if it
> occurs as a use on STMT.  STMT provides the context for a location in
> the IL.  if STMT isn't provided, it picks up the global range. EXPR does
> not necessarily have to occur on stmt, it's just the context point for
> finding the range.   It should be documented in value-query.h where it
> is initially declared, but I see it is not.  Sorry about that.. It seems
> to have gotten lost in the myriad of moves that were made. We have a
> definite lack of documentation on everything... that is next in
> priority,  once I get the remaining relation code in.
>
> I don't think its wrong to supply a debug stmt.  stmt is simply the
> location in the IL for which we are querying the range of EXPR. So this
> is something like
>
> # DEBUG d => d_10
>
> and the query is asking for the range of d_10 at this point in the IL..
> ie, what would it be on this stmt.   There isn't anything wrong with
> that..  and we certainly make no attempt to stop it for that reason..
> This change does prevent any analytics from happening (as does the one
> on trunk).
>
> >
> > #0  fancy_abort (file=0x2a71420 
> > "../../src/gcc-11-branch/gcc/gimple-range.cc",
> >      line=944,
> >      function=0x2a71638 <gimple_ranger::range_of_expr(irange&,
> > tree_node*, gimple*)::__FUNCTION__> "range_of_expr")
> >      at ../../src/gcc-11-branch/gcc/diagnostic.c:1884
> > #1  0x0000000001f28275 in gimple_ranger::range_of_expr (this=0x3274eb0, 
> > r=...,
> >      expr=<ssa_name 0x7ffff66d3000 8>, stmt=<gimple_debug 0x7ffff657e300>)
> >      at ../../src/gcc-11-branch/gcc/gimple-range.cc:944
> > #2  0x000000000151ab7c in range_query::value_of_expr (this=0x3274eb0,
> >      name=<ssa_name 0x7ffff66d3000 8>, stmt=<gimple_debug 0x7ffff657e300>)
> >      at ../../src/gcc-11-branch/gcc/value-query.cc:86
> > #3  0x0000000001f36ce3 in hybrid_folder::value_of_expr (this=0x7fffffffd990,
> >      op=<ssa_name 0x7ffff66d3000 8>, stmt=<gimple_debug 0x7ffff657e300>)
> >      at ../../src/gcc-11-branch/gcc/gimple-ssa-evrp.c:235
> > #4  0x0000000001387804 in substitute_and_fold_engine::replace_uses_in (
> >      this=0x7fffffffd990, stmt=<gimple_debug 0x7ffff657e300>)
> >      at ../../src/gcc-11-branch/gcc/tree-ssa-propagate.c:871
> >
> > so after EVRP we substitute and fold - but note we're not expecting to do
> > any more analysis in this phase but simply use the computed lattice,
> > since we don't substitute in unreachable code regions and thus SSA form
> > is temporarily broken that might otherwise cause issues.
> >
> > But yes, substitute and fold does substitute into debug stmts (but we don't
> > analyze debug stmts).  So maybe somehow arrange for the substitute_and_fold
> In which case this change is exactly what is needed. S&F will call
> range_of_expr asking for the range on the debug_stmt, and this change
> returns the global range instead of looking it up.
> > phase to always only use global ranges?  Maybe add the ability to
> > "lock" a ranger instance (disabling any further on-demand processing)?
>
> The change on trunk is better as it effectively makes debug stmts always
> use whatever the best value we know is without doing anything new. It
> only reverts to the global range if there is nothing better.  It depends
> on a bunch of other structural changes I wouldn't want to try to port
> back to gcc 11, too much churn.
>
> It might be possible to "lock" ranger, but the concept of a lattice
> doesn't really apply. There is no lattice..  there are only values as
> they appear at various points in the IL. We tracxk that mostly by
> propagating ranges to basic blocks.  When a query is made, if there is a
> readily available value it will use it. Unless it has reason to believe
> it is possible to improve it, in which case it may decide to go and check.
>
>
> > Anyway, inheritance is a bit mazy here, so the patch does look sensible.
> >
> So what this boils down to I think is that disabling any kind of lookup
> from a debug stmt is generally a good thing. That was a oversight on my
> part.  I think for GCC 11 this is sufficient. It will introduce no new
> analytics for debug stmts.
>
> For trunk, we could consider a lockdown, but I'm not sure even that is
> sufficient.. "When" do you lock it down..   The old model being used was
> "once a value is set, we don't revisit it", but we revisit things
> frequently during the initial DOM walk if the edges that need updating
> take us there.

So I was thinking of locking it down before the substitute & fold phase
given there is the analysis & propagation stage before.  Was there before,
not sure if it still is when ranger is used or whether everything is done
from the substitute-and-fold DOM walk.

>  When we get to the bottom of a loop, if we've learned
> something new, we propagate that back to the top and update what needs
> updating.  we can't lock that down, but it still changes the values that
> were originally seen thanks to the backend propagation.   Locking it
> down after the DOM walk will prevent anything new from happening then,
> but along the way things were done which cause issues. like the earlier
> case where we evolve to a constant, then further evolved to UNDEFINED.
>
>    I know the S&F mechanism is mostly driven by this "we decided it was
> a constant, substitute it everywhere" model  which is a bit orthogonal
> to how we operate... It has required a few concessions to map to that
> model since that isnt our "bottom" or "top", but I think we have a
> handle on them now.  Ideally when we get thru more of this, I'd like to
> change the way RVRP does the substitution too, as we've found it a bit
> limiting by times.
>
> If we run into more issues with the S&F engine, I'll see if disabling
> lookups and reverting to just a non-invasive query at the end resolves
> it better.
>
> I do think this is the right patch for GCC11, and it should be quite safe.

OK - agreed.  Thanks for the detailed explanation.

Richard.

Reply via email to