------- Comment #4 from carrot at google dot com 2009-06-09 03:46 ------- Thank you, Steven.
(In reply to comment #3) > "might be" is such a useless statement. > > Carrot, you are aware of the -fdump-rtl-all and -dAP options, I assume? Then > you should have no trouble finding out: > 1) Where the move comes from This is rtl dump before RA, everything is in normal state: cat obj/reg.c.173r.asmcons ;; Function test (test) (note 1 0 5 NOTE_INSN_DELETED) (note 5 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) (insn 2 5 3 2 src/./reg.c:3 (set (reg/v/f:SI 133 [ name ]) (reg:SI 0 r0 [ name ])) 168 {*thumb1_movsi_insn} (expr_list:REG_DEAD (reg:SI 0 r0 [ name ]) (nil))) (insn 3 2 4 2 src/./reg.c:3 (set (reg/v:SI 134 [ style ]) (reg:SI 1 r1 [ style ])) 168 {*thumb1_movsi_insn} (expr_list:REG_DEAD (reg:SI 1 r1 [ style ]) (nil))) (note 4 3 7 2 NOTE_INSN_FUNCTION_BEG) (insn 7 4 8 2 src/./reg.c:4 (set (reg:SI 0 r0) (const_int 0 [0x0])) 168 {*thumb1_movsi_insn} (nil)) (insn 8 7 9 2 src/./reg.c:4 (set (reg:SI 1 r1) (reg/v/f:SI 133 [ name ])) 168 {*thumb1_movsi_insn} (expr_list:REG_DEAD (reg/v/f:SI 133 [ name ]) (nil))) (insn 9 8 10 2 src/./reg.c:4 (set (reg:SI 2 r2) (reg/v:SI 134 [ style ])) 168 {*thumb1_movsi_insn} (expr_list:REG_DEAD (reg/v:SI 134 [ style ]) (nil))) (call_insn 10 9 0 2 src/./reg.c:4 (parallel [ (call (mem:SI (symbol_ref:SI ("foo") [flags 0x41] <function_decl 0xf7f6a680 foo>) [0 S4 A32]) (const_int 0 [0x0])) (use (const_int 0 [0x0])) (clobber (reg:SI 14 lr)) ]) 256 {*call_insn} (expr_list:REG_DEAD (reg:SI 2 r2) (expr_list:REG_DEAD (reg:SI 1 r1) (expr_list:REG_DEAD (reg:SI 0 r0) (nil)))) (expr_list:REG_DEP_TRUE (use (reg:SI 2 r2)) (expr_list:REG_DEP_TRUE (use (reg:SI 1 r1)) (expr_list:REG_DEP_TRUE (use (reg:SI 0 r0)) (nil))))) Here is rtl dump after RA, quite straightforward but inefficient: (note 1 0 5 NOTE_INSN_DELETED) (note 5 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) (insn 2 5 3 2 src/./reg.c:3 (set (reg/v/f:SI 3 r3 [orig:133 name ] [133]) (reg:SI 0 r0 [ name ])) 168 {*thumb1_movsi_insn} (nil)) (insn 3 2 4 2 src/./reg.c:3 (set (reg/v:SI 2 r2 [orig:134 style ] [134]) (reg:SI 1 r1 [ style ])) 168 {*thumb1_movsi_insn} (nil)) (note 4 3 7 2 NOTE_INSN_FUNCTION_BEG) (insn 7 4 8 2 src/./reg.c:4 (set (reg:SI 0 r0) (const_int 0 [0x0])) 168 {*thumb1_movsi_insn} (nil)) (insn 8 7 10 2 src/./reg.c:4 (set (reg:SI 1 r1) (reg/v/f:SI 3 r3 [orig:133 name ] [133])) 168 {*thumb1_movsi_insn} (nil)) (call_insn 10 8 18 2 src/./reg.c:4 (parallel [ (call (mem:SI (symbol_ref:SI ("foo") [flags 0x41] <function_decl 0xf7f6a680 foo>) [0 S4 A32]) (const_int 0 [0x0])) (use (const_int 0 [0x0])) (clobber (reg:SI 14 lr)) ]) 256 {*call_insn} (nil) (expr_list:REG_DEP_TRUE (use (reg:SI 2 r2)) (expr_list:REG_DEP_TRUE (use (reg:SI 1 r1)) (expr_list:REG_DEP_TRUE (use (reg:SI 0 r0)) (nil))))) (note 18 10 0 NOTE_INSN_DELETED) > 2) Why postreload (the post-reload CSE pass) does not eliminate the redundant > move > It seems the post-reload CSE pass can't handle this case. Because at instruction C r0 is killed so instruction can't use r0. In order to make it work for this case we must move instruction D before C first. As Andrew said we need to improve scheduling before RA to handle this. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40375