On 9/22/21 4:25 AM, Richard Biener wrote:
On Tue, Sep 21, 2021 at 3:50 PM Andrew MacLeod <amacl...@redhat.com> wrote:
On 9/21/21 9:32 AM, Richard Biener wrote:
On Tue, Sep 21, 2021 at 2:57 PM Andrew MacLeod <amacl...@redhat.com> wrote:
On 9/21/21 2:14 AM, Richard Biener wrote:
On Tue, Sep 21, 2021 at 8:09 AM Richard Biener
<richard.guent...@gmail.com> wrote:
On Tue, Sep 21, 2021 at 12:01 AM Andrew MacLeod via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
The patch sets the EXECUTABLE property on edges like VRP does, and then
removes that flag when an edge is determined to be un-executable.

This information is then used to return UNDEFINED for any requests on
un-executable edges, and to register equivalencies if all executable
edges of a PHI node are the same SSA_NAME.

This catches up a number of the cases VRP gets that ranger was missing,
and reduces the EVRP discrepancies to almost 0.

On a side note,  is there any interest/value in reversing the meaning of
that flag?  It seems to me that we could assume edges are EXECUTABLE by
default, then set a NON_EXECUTABLE flag when a pass determines the edge
cannot be executed.  This would rpevent a number fo passes from having
to loop through all the edges and set the EXECUTABLE property...   It
just seems backwards to me.
The flag is simply not kept up-to-date and it's the passes responsibility to
make use of it (aka install a default state upon entry).

To me not having EDGE_EXECUTABLE set on entry is more natural
for optimistic propagation passes, but yes, if you do on-demand greedy
processing then you need a conservative default.  But then how do you
denote a 'VARYING' (executable) state that may not drop back to 'CONSTANT"
(not executable)?  For optimistic propagation EDGE_EXECUTABLE set is
simply the varying state and since we never clear it again there's no chance
of oscillation.
Different model, we dont have a lattice whereby we track state and move
form one to another.. we just track currently best known values for
everything and recalculate them when the old values are stale.   We move
the edge to unexecutable when those values allow us to rewrite a branch
such that an edge can no longer be taken. everything else is executable.
     Any values on an unexecutable edge are then considered UNDEFINED when
combined with other values..

Btw, I fail to see how the patch makes ranger assure a sane initial state of
EDGE_EXECUTABLE (or make its use conditional).  Is the code you patched
not also used on-demand?
THe constructor for a ranger makes everything executable to start.
Calls the same routine VRP does.

    gimple_ranger::gimple_ranger () : tracer ("")
    {
@@ -41,6 +42,7 @@ gimple_ranger::gimple_ranger () : tracer ("")
      m_oracle = m_cache.oracle ();
      if (dump_file && (param_evrp_mode & EVRP_MODE_TRACE))
        tracer.enable_trace ();
+  set_all_edges_as_executable (cfun);
    }
Ah, I see.  I had the impression that with ranger we can now
do a cheap query everywhere on the range of an SSA name.  But then
the above is O(CFG size)...
One of the reasons I'd like to see it persistent :-)  We could
alternatively add another new one, something like EDGE_NEVER_EXECUTED
which is cleared by default when created and only ranger/other
interested passes utilize it and it is kept persistent.   Just seems
more appropriate to "fix" the current flag. I took a quick look at that,
but it seemed like one or more of the propagation passes may use the
flag for other nefarious purposes. It would require fixing everyone to
maintain the value properly.

   Queries are still "cheap", but there are varying amounts of lookups
and allocations that are done.  If the lack of a persistent EXECUTABLE
edge flag continues, I may make some further tweaks and make it
sensitive to whether EXECUTABLE is to be looked at or not and perhaps
only have the VRPs initiate that.  I prefer avoiding different modes
when possible tho.

Currently most/all uses of ranger are instantiated and used for the
duration of a pass, so the O(cfg) is pretty minimal with all the CFG
traversing and caching required.
Btw, there's auto_edge_flag (fun) that gets you a new flag
allocated and it's supposed to be cleared on all edges
(but I don't think we actually verify that - I suppose we should).
The downside is you have to clear it after use - but it would
in theory be possible to elide that by keeping a set of
"dirty" flags and only clear all of those when we run out of
non-dirty free flags.

Richard.

Huh, I did not know that.

Yeah, that looks like it might be a decent solution..  I'll take a closer look today.

Thanks

Andrew

Reply via email to