Hi,

While teaching dce.c on the dataflow-branch to delete noop-moves,
I noticed that most noop moves are produced by reload.  It inserts
duplicate insns for some reloads, postreload turns the duplicate
reload into a simple reg-reg move (but the lhs and rhs are the same
register of course), and then dce.c removes these moves because
they are noop-moves.

Example:
Before reload we just have some variable, ivtmp.46, in a pseudo:
(insn 45 43 47 6 (set (reg:SI 62 [ D.1617 ])
        (reg:SI 63 [ ivtmp.46 ])) 40 {*movsi_1} (nil)
    (nil))

After reload we have this:
(insn 45 43 102 6 (set (reg:SI 4 si [orig:62 D.1617 ] [62])
        (mem/c:SI (plus:SI (reg/f:SI 6 bp)
                (const_int -16 [0xfffffffffffffff0])) [0 ivtmp.46+0 S4 A8])) 40 
{*movsi_1} (nil)
    (nil))

(insn 102 45 47 6 (set (reg:SI 4 si [orig:62 D.1617 ] [62])
        (mem/c:SI (plus:SI (reg/f:SI 6 bp)
                (const_int -16 [0xfffffffffffffff0])) [0 ivtmp.46+0 S4 A8])) 40 
{*movsi_1} (nil)
    (nil))

Note, that these insns are identical.
After postreload it looks like this:
(insn 45 43 102 6 (set (reg:SI 4 si [orig:62 D.1617 ] [62])
        (mem/c:SI (plus:SI (reg/f:SI 6 bp)
                (const_int -16 [0xfffffffffffffff0])) [0 ivtmp.46+0 S4 A8])) 40 
{*movsi_1} (nil)
    (nil))

(insn 102 45 47 6 (set (reg:SI 4 si [orig:62 D.1617 ] [62])
        (reg:SI 4 si [orig:62 D.1617 ] [62])) 40 {*movsi_1} (nil)
    (nil))

Then on the dataflow-branch, dce removes insn 102.  On mainline,
flow2 takes care of that.


Test case for ix86 is this:

/* This is reduced from count_reg_usage in cse.c.
   Compile with gcc -S -march=i686 -m32 -O -fno-tree-ch t.c -da
   and look at the .greg and .postreload RTL dumps.
   With "gcc (GCC) 4.2.0 20060225 (experimental)", look for insn 45
   and insn 102.  */

typedef struct rtvec_def
{
  unsigned num_elem;
  struct rtx_def *elem[1];
} *rtvec;

typedef struct rtx_def
{
  struct rtvec_def *rtvec[1];
} *rtx;

extern int rtx_length[];

void
foo (rtx x, const char c, int code)
{
  int i, j;

  for (i = (rtx_length[code]) - 1; i >= 0; i--)
    {
      if (c == 'e')
        asm volatile ("":::"0", "1", "2", "3", "4", "5");
      else if (c == 'E')
        for (j = x->rtvec[i]->num_elem - 1; j >= 0; j--)
          foo (x->rtvec[i]->elem[j], c, code);
    }
}


I don't understand reload at all.  Could someone help me figure out why
we have two identical insns there?  We produce hundreds of basically
dead insns like this, and we need post-reload passes to clean them up.
So if we can avoid emitting the second, redundant insn, that'd be a win.

Gr.
Steven

Reply via email to