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

--- Comment #13 from Andrew Macleod <amacleod at redhat dot com> ---
(In reply to Jakub Jelinek from comment #12)
> So, for start I think we should do:
> 1) query->range_of_expr (m_index_range, m_index_expr, swtch)
>    where query is address of gimple_ranger passed down from the caller
>    to figure out range of the index expression; case labels without

For starters, you can probably simply create a gimple_ranger on the spot to do
the query.  At least until everything works the way you want.   Its low
overhead... we had reasonable success with that early on with some pass
conversions, and ultimately we hope by next release to make this more generally
accessible without passing a ranger around anyway. 


> CASE_HIGH for
>    which m_index_range.contains_p (CASE_LOW (case)) is false can be ignored
>    for the optimization (well, handled the way it is better for the
> optimization)
>    For CASE_HIGH labels, similarly query if the range overlaps the index
> range.
>    Note, I don't remember exactly in which way the types of the index
> expression
>    and of the case labels can differ, I believe all case labels have to have
> the
>    same type, so probably for the computation of the range if it has
> different
>    type from the case label ones, it needs to call something that would
> emulate
>    the effect of conversion to that type (or vice versa?)
>    CCing Andrew for the range stuff

There are a couple of PRs related to this, I forget the current resolution, but
I originally opened https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87798 for it.

Ranger currently punts if the precision of the labels is different than the
precision of the switch expr in gimple-range-edge.cc :
outgoing_range::get_edge_range

In order to convert between types, range-op.h exports the routine
   extern void range_cast (irange &, tree type);

which does an in place conversion to type... supports full cast semantics.
there are uses of it sprinkled around.


Furthermore, IIRC there can be multiple cases sharing the same edge.. It seems
it might be useful to make more use of gimple-range-edge.h here.. (we may need
some tweaks in order to get things working with a ranger since this is a
private member to ranger)  so I would again start by simply creating my own
local outgoing_range instance and then you can ask

int_range_max range;
outgoing_range_instance.edge_range_p (range, switch_edge)

where this will give you the cumulative union of all the case-labels on that
switch edge.   (its unrelated to the index variable...  Ranger intersects this
range with the index variable range when you ask for the range of the index
variable on an edge) 

If this turns out to be useful, we can probably figure a way to get it exported
from ranger to avoid creating a local instance


The last useful bit of info that may not be obvious...  if you ask ranger for
the range of the index variable on the default edge, and if all the cases cover
the known range of the index variable, as in the first example, then ranger
will return a range of UNDEFINED ...  meaning it can never take that edge.

ie the function in the first example shows me:
=========== BB 4 ============
x_2(D)  unsigned int [0, 2]
    <bb 4> :
    switch (x_2(D)) <default: <L5> [INV], case 0: <L7> [INV], case 1: <L3>
[INV], case 2: <L4> [INV]>

4->7      x_2(D) :      UNDEFINED
4->8      x_2(D) :      unsigned int [0, 0]
4->5      x_2(D) :      unsigned int [1, 1]
4->6      x_2(D) :      unsigned int [2, 2]

where edge 4->7 is the default case...

Reply via email to