[Bug rtl-optimization/71785] Computed gotos are mostly optimized away

rndfax at yandex dot ru gcc-bugzilla@gcc.gnu.org
Thu Nov 21 19:44:00 GMT 2019


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

--- Comment #20 from Aleksey <rndfax at yandex dot ru> ---
(In reply to Segher Boessenkool from comment #19)
> '-freorder-blocks'
>      Reorder basic blocks in the compiled function in order to reduce
>      number of taken branches and improve code locality.
> 
>      Enabled at levels '-O', '-O2', '-O3', '-Os'.
> 
> If you disable this option, you get more taken branches and a less linear
> control flow.  As documented.

If compgoto would have been depended on this option then that would explained
observed behavior. But compgoto does not depend on it. And it says:
/* Duplicate the blocks containing computed gotos.  This basically unfactors
   computed gotos that were factored early on in the compilation process to
   speed up edge based data flow.  We used to not unfactor them again, which
   can seriously pessimize code with many computed jumps in the source code,
   such as interpreters.  See e.g. PR15242.  */
static void
duplicate_computed_gotos (function *fun)

"This basically unfactors computed gotos that were factored early"

And it works fine until one last predecessor. Why until the last predecessor?
That's the point.

> 
> > START - the very first "goto *xxx" - was not optimized, since "bb 5" has
> > only 1 predecessor.
> > But it's optimized in later step "bbro". That's exactly why option
> > "-fno-reorder-blocks" breaks first jump optimization.
> > 
> > Can someone explain why there are such conditions:
> >       if (single_pred_p (bb))
> >           return false;
> > 
> >       if (single_pred_p (bb))
> >           continue;
> > in maybe_duplicate_computed_goto function?
> 
> It duplicates the code, one copy for every predecessor to jump to.

I showed that not for every predecessor.

> It does not move existing blocks elsewhere.

I provided RTL dump, it says that it removes edges. It moves the code. It even
says this:

/* Duplicates basic block BB and redirects edge E to it.
...
basic_block                                                                    
                                                                               
        duplicate_block (basic_block bb, edge e, basic_block after,
copy_bb_data *id)

Edge count in bb decreases, so code is moving.

And by answering the question I meant "what are these conditions for".
Why bb with one predecessor is not optimized?
Why not just optimize it right here right now?


More information about the Gcc-bugs mailing list