On Thu, Nov 14, 2019 at 10:39 AM Martin Liška <mli...@suse.cz> wrote:
>
> On 11/5/19 1:38 PM, Richard Biener wrote:
> > On Mon, Nov 4, 2019 at 3:49 PM Jakub Jelinek <ja...@redhat.com> wrote:
> >>
> >> On Mon, Nov 04, 2019 at 03:23:20PM +0100, Martin Liška wrote:
> >>> The patch adds a new pass that identifies a series of if-elseif
> >>> statements and transform then into a GIMPLE switch (if possible).
> >>> The pass runs right after tree-ssa pass and I decided to implement
> >>> matching of various forms that are introduced by folder (fold_range_test):
> >>
> >> Not a review, just a few questions:
>
> Hello.
>
> >
> > Likewise - please do not name switches -ftree-*, 'tree' doens't add anything
> > but confusion to users.  Thus use -fif-to-switch or -fconvert-if-to-switch
>
> Agree with you, I selected the later option.
>
> >
> > +The transformation can help to produce a faster code for
> > +the switch statement.
> >
> > produce faster code.
>
> Fixed.
>
> >
> > Doesn't it also produce smaller code eventually?
>
> In some situation yes, but generally it leads to more jump tables
> (which are bigger when expanded).
>
> >
> > Please to not put code transform passes into build_ssa_passes (why did
> > you choose this place)?
>
> Well, that was my initial pass selection as I wanted to have a GIMPLE
> code close to what FEs produce.
>
> >  The pass should go into pass_all_early_optimizations
> > instead, and I'm quite sure you want to run _after_ CSE.  I'd even say
> > that the pass should run as part of switch-conversion, so we build
> > a representation of a switch internally and then code-generate the optimal
> > form directly.  For now just put the pass before switch-conversion.
>
> But yes, the suggested place is much better place and we can benefit from
> VRP (that will kill dead conditions in a if-else chain)
>
> >
> > There are functions without comments in the patch and you copied
> > from DSE which shows in confusing comments left over from the original.
> >
> > +  mark_virtual_operands_for_renaming (cfun);
> >
> > if you did nothing renaming all vops is expensive.
>
> This one is needed for situations like:
>
> fn1 ()
> {
>    <unnamed type> a.0_1;
>
>    <bb 2> :
>    # VUSE <.MEM_5(D)>
>    a.0_1 = a;
>    if (a.0_1 == 0)
>      goto <bb 6>; [INV]
>    else
>      goto <bb 3>; [INV]
>
>    <bb 3> :
>    if (a.0_1 == 1)
>      goto <bb 6>; [INV]
>    else
>      goto <bb 4>; [INV]
>
>    <bb 4> :
>    if (a.0_1 == 2)
>      goto <bb 5>; [INV]
>    else
>      goto <bb 6>; [INV]
>
>    <bb 5> :
>    # .MEM_6 = VDEF <.MEM_5(D)>
>    fn2 ();
>
>    <bb 6> :
>    # .MEM_4 = PHI <.MEM_5(D)(2), .MEM_5(D)(3), .MEM_5(D)(4), .MEM_6(5)>
>    # VUSE <.MEM_4>
>    return;
>
> }
>
> where without the call, I end up with:
>
>    <bb 2> :
>    # VUSE <.MEM_5(D)>
>    a.0_1 = a;
>    switch (a.0_1) <default: <L8> [INV], case 0: <L8> [INV], case 1: <L8> 
> [INV], case 2: <L9> [INV]>
>
>    <bb 3> :
> <L9>:
>    # .MEM_6 = VDEF <.MEM_5(D)>
>    fn2 ();
>
>    <bb 4> :
>    # .MEM_4 = PHI <.MEM_6(3), (2)>

I meant you are doing it unconditionally even if you didn't transform
any if-then-else chain.

>
> >
> > I'm missing an overall comment - you are using a dominator walk
> > but do nothing in the after hook which means you are not really
> > gathering any data?  You're also setting visited bits on BBs which
> > means you are visiting alternate BBs during the DOM walk.
>
> You are right, I'm a bit cheating with the DOM walk as I also mark visited 
> BBs.
> What I want is for each if-else condition, I want to visit the first IF in 
> such
> chain. That's why I decided to iterate in DOMINATOR order.
> Can I do it simpler?

Put that in a comment, do away with domwalk and instead start from
ENTRY_BLOCK, using a worklist seeded by {first,next}_dom_son ()
and avoid putting visited blocks on that worklist.

Btw, what about if-chains nested in another if-chain?  Don't you want to
transform "inner" chains first or does it really not matter (you're adjusting
the CFG, doing that inside the domwalk is fishy since that also uses
pre-computed RPO order; the simple dom-son walking should work
but you of course might miss some blocks depending on how you set up
things).

Richard.

> Thanks,
> Martin
>
> >
> >> 1) what does it do if __builtin_expect* has been used, does it preserve
> >>     the probabilities and if in the end decides to expand as ifs, are those
> >>     probabilities retained through it?
> >> 2) for the reassoc-*.c testcases, do you get identical or better code
> >>     with the patch?
> >> 3) shouldn't it be gimple-if-to-switch.c instead?
> >> 4) what code size effect does the patch have say on cc1plus (if you don't
> >>     count the code changes of the patch itself, i.e. revert the patch in 
> >> the
> >>     stage3 and rebuild just the stage3)?
> >>
> >>> +struct case_range
> >>> +{
> >>> +  /* Default constructor.  */
> >>> +  case_range ():
> >>> +    m_min (NULL_TREE), m_max (NULL_TREE)
> >>
> >> I admit I'm never sure about coding conventions for C++,
> >> but shouldn't there be a space before :, or even better :
> >> be on the next line before m_min ?
> >>
> >>          Jakub
> >>
>

Reply via email to