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