On Mon, Oct 19, 2015 at 6:23 PM, Jeff Law <l...@redhat.com> wrote:
> If I hack up GCC's old jump threader to avoid threading across backedges and
> instead let the FSM threader handle that case, then we end up with cases
> where the FSM threader creates irreducible loops with marginal benefit.
>
> This can be seen in ssa-dom-thread-2{d,e,f}.c.
>
> We've long avoided such threads in the old jump threader.  We generally want
> to avoid them in the FSM threader as well.  The only case where we're going
> to allow them is when we're able to eliminate a multi-way branch from the
> loop.
>
> Bootstrapped and regression tested on x86_64-linux-gnu.  Also tested the
> above mentioned testcases with my hacked up compiler.
>
> Installed on the trunk.

Note that this fixed some of the size regressions I see on SPEC CPU 2000
but not all, esp. 176.gcc seems to be as bad as before (seen with plain -O2
on x86_64).

Richard.

> Jeff
>
> commit 518690952b62c1d38b89cdbef0490a7d11f06c40
> Author: Jeff Law <l...@redhat.com>
> Date:   Mon Oct 19 10:23:26 2015 -0600
>
>     [PATCH] Don't allow FSM threader to create irreducible loops unless it
> eliminates a multi-way branch
>
>         * tree-ssa-threadupdate.c (valid_jump_thread_path): Reject paths
>         that create irreducible loops unless the path elimiantes a multiway
>         branch.
>
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index 89a42c1..ff3d3fc 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,9 @@
> +2015-10-19  Jeff Law  <l...@redhat.com>
> +
> +       * tree-ssa-threadupdate.c (valid_jump_thread_path): Reject paths
> +       that create irreducible loops unless the path elimiantes a multiway
> +       branch.
> +
>  2015-10-19  Richard Biener  <rguent...@suse.de>
>
>         PR tree-optimization/67975
> diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
> index 5632a88..8e3437a 100644
> --- a/gcc/tree-ssa-threadupdate.c
> +++ b/gcc/tree-ssa-threadupdate.c
> @@ -2553,11 +2553,31 @@ static bool
>  valid_jump_thread_path (vec<jump_thread_edge *> *path)
>  {
>    unsigned len = path->length ();
> +  bool multiway_branch = false;
>
> -  /* Check that the path is connected.  */
> +  /* Check that the path is connected and see if there's a multi-way
> +     branch on the path.  */
>    for (unsigned int j = 0; j < len - 1; j++)
> -    if ((*path)[j]->e->dest != (*path)[j+1]->e->src)
> -      return false;
> +    {
> +      if ((*path)[j]->e->dest != (*path)[j+1]->e->src)
> +        return false;
> +      gimple *last = last_stmt ((*path)[j]->e->dest);
> +      multiway_branch |= (last && gimple_code (last) == GIMPLE_SWITCH);
> +    }
> +
> +  /* If we are trying to thread the loop latch to a block that does
> +     not dominate the loop latch, then that will create an irreducible
> +     loop.  We avoid that unless the jump thread has a multi-way
> +     branch, in which case we have deemed it worth losing other
> +     loop optimizations later if we can eliminate the multi-way branch.  */
> +  edge e = (*path)[0]->e;
> +  struct loop *loop = e->dest->loop_father;
> +  if (!multiway_branch
> +      && loop->latch
> +      && loop_latch_edge (loop) == e
> +      && (determine_bb_domination_status (loop, path->last ()->e->dest)
> +         == DOMST_NONDOMINATING))
> +    return false;
>
>    return true;
>  }
> @@ -2650,7 +2670,9 @@ thread_through_all_blocks (bool may_peel_loop_headers)
>        if (bitmap_bit_p (threaded_blocks, entry->src->index)
>           /* Verify that the jump thread path is still valid: a
>              previous jump-thread may have changed the CFG, and
> -            invalidated the current path.  */
> +            invalidated the current path or the requested jump
> +            thread might create irreducible loops which should
> +            generally be avoided.  */
>           || !valid_jump_thread_path (path))
>         {
>           /* Remove invalid FSM jump-thread paths.  */
>

Reply via email to