------- 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