On 11/24/21 09:00, Richard Biener wrote:
On Tue, Nov 23, 2021 at 5:36 PM Martin Liška <mli...@suse.cz> wrote:

On 11/23/21 16:20, Martin Liška wrote:
Sure, so for e.g. case 1 ... 5 we would need to create a new unswitch_predicate
with 1 <= index && index <= 5 tree predicate (and the corresponding irange 
range).
Later once we unswitch on it, we should use a special unreachable_flag that will
be used for marking of dead edges (similarly how we fold gconds to 
boolean_{false/true}_node.
Does it make sense?

I have thought about it more and it's not enough. What we really want is having 
a irange
for *each edge* (2 for gconds and multiple for gswitchs). Once we select a 
unswitch_predicate,
then we need to fold_range in true/false loop all these iranges. Doing that we 
can handle situations like:

if (index < 1)
     do_something1

if (index > 2)
     do_something2

switch (index)
     case 1 ... 2:
       do_something;
...

as seen the once we unswitch on 'index < 1' and 'index > 2', then the first 
case will be taken in the false_edge
of 'index > 2' loop unswitching.

Hmm.  I'm not sure it needs to be this complicated.  We're basically
evaluating ranges/predicates based
on a fixed set of versioning predicates.  Your implementation created
"predicates" for the to be simplified
conditions but in the end we like to evaluate the actual stmt to
figure the taken/not taken edges.

Yes.

 IIRC
elsewhere Andrew showed a snipped on how to evaluate a stmt with a
given range - not sure if that

I'm using that. First I isolate a irange from a versioning-predicate with
ranger->range_on_edge and I later combine it with:
fold_range (r, stmt, parent_range).


was useful enough.  So what I think would be nice if we could somehow
use rangers path query
without an actual CFG.  So we virtuall have

   if (versioning-predicate1)
     if (versioning-predicate2)
        ;
    else
       for (;;) // out current loop
         {
           ...
               if (condition)
                 ;
          ...
               switch (var)
                  {
...
                   }
         }

and versioning-predicate1 and versioning-predicate2 are not in the IL.
What we'd like
to do is seed the path query with a "virtual" path through the two
predicates to the
entry of the loop and compute_ranges based on those.

What I can do that via building of a vector of tuple<unswitch_predicate,bool>
that would be passed to recursive calls of tree_unswitch_single_loop.
That basically describes which true/false edges are taken for the so far created
versioning-predicates. Right? That should be usable.

Then we like to
use range_of_stmt on 'if (condition)' and 'switch (var)' to determine
not taken edges.

Works for me and we would mark unreachable case BBs with a unreachable_flag
(we can't fold it away as shown in the original patch attempt).

Looking somewhat at the sources it seems like we "simply" need to do what
compute_outgoing_relations does - unfortunately the code lacks comments
so I have no idea what jt_fur_source src (...).register_outgoing_edges does ...

Anyway, for now manually simplifying things is fine but I probably would still
stick to a basic interface that marks not taken outgoing edges of a stmt based
on the set of versioning predicates.

Lemme try working on another version of the patch.

Martin


Richard.


Martin

Reply via email to