Hello,

> >>>    (parallel [
> >>>              (set (pc)
> >>>                   (if_then_else (lt:SI (reg:SI 45)    <---
> >>>                                        (reg:SI 26))
> >>>                                 (label_ref:HI 129)
> >>>                                 (pc)))
> >>>              (clobber (reg:SI 45))                    <-- must be the 
> >>>              same
> >>>              (clobber (scratch:BI))
> >>>              ])
> 
> >actually, I probably misunderstood what you meant.  The problem is that
> >invariant motion rewrites just part of the considered insn, changing
> >reg:45 to another register in if_then_else, but leaving it the same in
> >the clobber?
> 
> Correct.  I originally had a patch like this
> 
> Index: gcc/loop-invariant.c
> ===================================================================
> --- gcc/loop-invariant.c      (revision 125308)
> +++ gcc/loop-invariant.c      (working copy)
> @@ -1212,7 +1212,14 @@ move_invariant_reg (struct loop *loop, u
>    if (inv->def)
>      {
>        for (use = inv->def->uses; use; use = use->next)
> -     *use->pos = reg;
> +     {
> +       rtx orig = *use->pos;
> +
> +       /* Use replace_rtx() in case there are other references to
> +          ORIG inside the insn which are not recorded in the USE
> +          list.  eg references inside CLOBBERs.  */
> +       replace_rtx (use->insn, orig, reg);
> +     }
>      }
> 
>    return true;
> 
> which I thought would solve the problem, but I found that it introduced 
> regressions into the gcc testsuite for an x86_64-linux-gnulibc 
> toolchain, so I abandoned it.  (I did not investigate why it caused 
> regressions, I just assumed that my approach was wrong).

It will break in situations like

loop {
insn 1: (set reg:1 something_invariant)
insn 2: (set reg:1 (plus reg:1 something_else))
}

When we move the insn 1 out of the loop, we want this to be rewritten as

insn 1: (set reg:3 something_invariant)

loop {
insn 2: (set reg:1 (plus reg:3 something_else))
}

While your patch would rewrite insn 2 to set reg:3.  What could work
would be going through the it might be more efficient to go through defs
recorded by df, and rewriting those with DF_REF_MUST_CLOBBER flag.

Zdenek

Reply via email to