> The problem is in that r0-6313 change, which made count_reg_usage not
> count uses of the pseudo which the containing SET sets.  That is needed
> so we can delete those instructions as trivially dead if they are really
> dead, but has the following problem.  After fwprop proper we have:
> (insn 7 2 8 2 (set (reg/v:DI 101 [ g ])
>         (const_int -1 [0xffffffffffffffff])) "pr119594.c":8:10 95
> {*movdi_internal} (nil))
> ...
> (insn 26 24 27 7 (set (reg:DI 104 [ g ])
>         (zero_extend:DI (subreg:SI (reg/v:DI 101 [ g ]) 0)))
> "pr119594.c":11:8 175 {*zero_extendsidi2} (expr_list:REG_EQUAL (const_int
> 4294967295 [0xffffffff])
>         (expr_list:REG_DEAD (reg/v:DI 101 [ g ])
>             (nil))))
> (insn 27 26 28 7 (set (reg/v:DI 101 [ g ])
>         (zero_extend:DI (subreg:SI (reg/v:DI 101 [ g ]) 0)))
> "pr119594.c":11:8 175 {*zero_extendsidi2} (expr_list:REG_EQUAL (const_int
> 4294967295 [0xffffffff])
>         (expr_list:REG_UNUSED (reg/v:DI 101 [ g ])
>             (nil))))
> and nothing else uses or sets the 101 and 104 pseudos.  The subpass doesn't
> look at REG_UNUSED or REG_DEAD notes (correctly, as they aren't guaranteed
> to be accurate).  The last change in the IL was forward propagation of
> (reg:DI 104 [ g ]) value into the following insn.
> Now, count_reg_usage doesn't count anything on insn 7, the SET_DEST is a
> reg, so we don't count that and SET_SRC doesn't contain any regs.
> On insn 26 it counts one usage of pseudo 101 (so counts[101] = 1) and
> on insn 27 since r0-6313 doesn't count anything as that insn sets
> pseudo 101 to something that uses it, it isn't a side-effect instruction
> and can't throw.
> 
> Now, after counting reg usages the subpass walks the IL from end to start,
> sees insn 27, counts[101] is non-zero, so insn_live_p is true, nothing is
> deleted.  Then sees insn 26, counts[104] is zero, insn_live_p is false,
> we delete the insn and decrease associated counts, in this case counts[101]
> becomes zero.  And finally later we process insn 7, counts[101] is now zero,
> insn_live_p is false, we delete the insn (and decrease associated counts,
> which aren't any).
> Except that this resulted in insn 27 staying in the IL but using a REG
> which is no longer set (and worse, having a REG_EQUAL note of something we
> need later in the same bb, so we then assume pseudo 101 contains 0xffffffff,
> which it no longer does.
> 
> Now, if insn 26 was after insn 27, this would work just fine, we'd first
> delete that and then insn 27 and then insn 7, which is why most of the time
> it happens to work fine.

I guess the question is: how much do we pessimize if we tweak r0-6313 change?
For example, we could say that a use of REG in the SET_SRC does not count if 
REG is also set in the SET_DEST *only* if there is no previous use of REG:

    case REG:
      if (x == dest)
        {
           if (incr > 0 && counts[REGNO (x)] != 0)
                counts[REGNO (x)] += incr;
        }
      else
        counts[REGNO (x)] += incr;
      return;

IIUC this would both fix the bug and preserve the deletion if insn 26 and 27 
are swapped.

-- 
Eric Botcazou


Reply via email to