public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug target/40375] New: redundant register move with -mthumb
@ 2009-06-08 3:21 carrot at google dot com
2009-06-08 3:24 ` [Bug target/40375] " carrot at google dot com
` (9 more replies)
0 siblings, 10 replies; 11+ messages in thread
From: carrot at google dot com @ 2009-06-08 3:21 UTC (permalink / raw)
To: gcc-bugs
Compile the following code with -mthumb -O2 -Os,
extern void foo(int*, const char*, int);
void test(const char name[], int style)
{
foo(0, name, style);
}
I got:
push {r4, lr}
mov r3, r0 // A
mov r2, r1 // B
mov r0, #0 // C
mov r1, r3 // D
bl foo
pop {r4, pc}
Instructions A and D move register r0 to r1, actually it can be replaced with 1
instruction
mov r1, r0
and place it between B and C.
--
Summary: redundant register move with -mthumb
Product: gcc
Version: 4.5.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: carrot at google dot com
GCC build triplet: i686-linux
GCC host triplet: i686-linux
GCC target triplet: arm-eabi
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40375
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug target/40375] redundant register move with -mthumb
2009-06-08 3:21 [Bug target/40375] New: redundant register move with -mthumb carrot at google dot com
@ 2009-06-08 3:24 ` carrot at google dot com
2009-06-08 3:27 ` pinskia at gcc dot gnu dot org
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: carrot at google dot com @ 2009-06-08 3:24 UTC (permalink / raw)
To: gcc-bugs
------- Comment #1 from carrot at google dot com 2009-06-08 03:23 -------
Created an attachment (id=17962)
--> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=17962&action=view)
test case shows the redundant register move
This problem occurs quite frequently if both caller and callee have multiple
parameters.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40375
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug target/40375] redundant register move with -mthumb
2009-06-08 3:21 [Bug target/40375] New: redundant register move with -mthumb carrot at google dot com
2009-06-08 3:24 ` [Bug target/40375] " carrot at google dot com
@ 2009-06-08 3:27 ` pinskia at gcc dot gnu dot org
2009-06-08 11:41 ` steven at gcc dot gnu dot org
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2009-06-08 3:27 UTC (permalink / raw)
To: gcc-bugs
------- Comment #2 from pinskia at gcc dot gnu dot org 2009-06-08 03:27 -------
This might be caused by scheduling before the register allocator (or maybe the
lack of).
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40375
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug target/40375] redundant register move with -mthumb
2009-06-08 3:21 [Bug target/40375] New: redundant register move with -mthumb carrot at google dot com
2009-06-08 3:24 ` [Bug target/40375] " carrot at google dot com
2009-06-08 3:27 ` pinskia at gcc dot gnu dot org
@ 2009-06-08 11:41 ` steven at gcc dot gnu dot org
2009-06-08 15:43 ` rguenth at gcc dot gnu dot org
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: steven at gcc dot gnu dot org @ 2009-06-08 11:41 UTC (permalink / raw)
To: gcc-bugs
------- Comment #3 from steven at gcc dot gnu dot org 2009-06-08 11:41 -------
"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
2) Why postreload (the post-reload CSE pass) does not eliminate the redundant
move
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40375
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug target/40375] redundant register move with -mthumb
2009-06-08 3:21 [Bug target/40375] New: redundant register move with -mthumb carrot at google dot com
` (2 preceding siblings ...)
2009-06-08 11:41 ` steven at gcc dot gnu dot org
@ 2009-06-08 15:43 ` rguenth at gcc dot gnu dot org
2009-06-09 3:46 ` carrot at google dot com
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2009-06-08 15:43 UTC (permalink / raw)
To: gcc-bugs
--
rguenth at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
Severity|normal |enhancement
Keywords| |missed-optimization
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40375
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug target/40375] redundant register move with -mthumb
2009-06-08 3:21 [Bug target/40375] New: redundant register move with -mthumb carrot at google dot com
` (3 preceding siblings ...)
2009-06-08 15:43 ` rguenth at gcc dot gnu dot org
@ 2009-06-09 3:46 ` carrot at google dot com
2009-06-09 8:34 ` steven at gcc dot gnu dot org
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: carrot at google dot com @ 2009-06-09 3:46 UTC (permalink / raw)
To: gcc-bugs
------- 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
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug target/40375] redundant register move with -mthumb
2009-06-08 3:21 [Bug target/40375] New: redundant register move with -mthumb carrot at google dot com
` (4 preceding siblings ...)
2009-06-09 3:46 ` carrot at google dot com
@ 2009-06-09 8:34 ` steven at gcc dot gnu dot org
2009-06-09 13:52 ` carrot at google dot com
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: steven at gcc dot gnu dot org @ 2009-06-09 8:34 UTC (permalink / raw)
To: gcc-bugs
------- Comment #5 from steven at gcc dot gnu dot org 2009-06-09 08:34 -------
Hmm, I was under the impression that postreload-cse could move instructions
too, but that was just wishful thinking.
I don't really see how the scheduler can solve this. The scheduler would have
to know what the live ranges of r0 and r133 overlap, but we don't have an
interference graph in the scheduler. Maybe calculating conflicts locally and
adjusting scheduling priorities based on that? What improvement to pre-RA
scheduling do you have in mind?
Perhaps an easier solution would be to change the order of the parameter loads
or stores. Right now GCC does this from this pre-RA to post-RA:
(set (reg:SI 133) (reg:SI r0))
(set (reg:SI 134) (reg:SI r1))
(set (reg:SI r0) (const_int 0))
(set (reg:SI r1) (reg:SI r133))
(set (reg:SI r2) (reg:SI r134))
(call "foo")
==>
(set (reg:SI r3) (reg:SI r0))
(set (reg:SI r2) (reg:SI r1))
(set (reg:SI r0) (const_int 0))
(set (reg:SI r1) (reg:SI r3))
(set (reg:SI r2) (reg:SI r2)) // NOP move, so eliminated
(call "foo")
==>
(set (reg:SI r3) (reg:SI r0))
(set (reg:SI r2) (reg:SI r1))
(set (reg:SI r0) (const_int 0))
(set (reg:SI r1) (reg:SI r3))
(call "foo")
There is always going to be a conflict if GCC generate the above RTL before
register allocation, so maybe the generated RTL should be changed. If GCC
would emit the parameter stores before the call in reverse order, then the
conflicts would go away too:
(set (reg:SI 133) (reg:SI r0))
(set (reg:SI 134) (reg:SI r1))
(set (reg:SI r2) (reg:SI r134))
(set (reg:SI r1) (reg:SI r133))
(set (reg:SI r0) (const_int 0))
(call "foo")
==>
(set (reg:SI r0) (reg:SI r0)) // NOP move, so eliminated
(set (reg:SI r2) (reg:SI r1))
(set (reg:SI r2) (reg:SI r2)) // NOP move, so eliminated
(set (reg:SI r1) (reg:SI r0))
(set (reg:SI r0) (const_int 0))
(call "foo")
==>
(set (reg:SI r2) (reg:SI r1))
(set (reg:SI r1) (reg:SI r0))
(set (reg:SI r0) (const_int 0))
(call "foo")
--
steven at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Ever Confirmed|0 |1
Last reconfirmed|0000-00-00 00:00:00 |2009-06-09 08:34:25
date| |
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40375
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug target/40375] redundant register move with -mthumb
2009-06-08 3:21 [Bug target/40375] New: redundant register move with -mthumb carrot at google dot com
` (5 preceding siblings ...)
2009-06-09 8:34 ` steven at gcc dot gnu dot org
@ 2009-06-09 13:52 ` carrot at google dot com
2009-06-09 14:32 ` ramana at gcc dot gnu dot org
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: carrot at google dot com @ 2009-06-09 13:52 UTC (permalink / raw)
To: gcc-bugs
------- Comment #6 from carrot at google dot com 2009-06-09 13:52 -------
(In reply to comment #5)
> Hmm, I was under the impression that postreload-cse could move instructions
> too, but that was just wishful thinking.
>
I will look into postreload-cse.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40375
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug target/40375] redundant register move with -mthumb
2009-06-08 3:21 [Bug target/40375] New: redundant register move with -mthumb carrot at google dot com
` (6 preceding siblings ...)
2009-06-09 13:52 ` carrot at google dot com
@ 2009-06-09 14:32 ` ramana at gcc dot gnu dot org
2009-09-25 8:11 ` [Bug middle-end/40375] redundant register move with scheduler before RA turned off pinskia at gcc dot gnu dot org
2010-02-10 10:55 ` steven at gcc dot gnu dot org
9 siblings, 0 replies; 11+ messages in thread
From: ramana at gcc dot gnu dot org @ 2009-06-09 14:32 UTC (permalink / raw)
To: gcc-bugs
------- Comment #7 from ramana at gcc dot gnu dot org 2009-06-09 14:32 -------
(In reply to comment #6)
> (In reply to comment #5)
> > Hmm, I was under the impression that postreload-cse could move instructions
> > too, but that was just wishful thinking.
> >
> I will look into postreload-cse.
>
I've looked at this superficially and something that I noticed was that in the
ARM case (i.e !-mthumb) there aren't any redundant moves -
It works fine in the Register allocator but the only difference that I can see
/ think of is that we support sibling calls for ARM mode. We don't have sibling
calls supported for Thumb.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40375
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug middle-end/40375] redundant register move with scheduler before RA turned off
2009-06-08 3:21 [Bug target/40375] New: redundant register move with -mthumb carrot at google dot com
` (7 preceding siblings ...)
2009-06-09 14:32 ` ramana at gcc dot gnu dot org
@ 2009-09-25 8:11 ` pinskia at gcc dot gnu dot org
2010-02-10 10:55 ` steven at gcc dot gnu dot org
9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2009-09-25 8:11 UTC (permalink / raw)
To: gcc-bugs
------- Comment #8 from pinskia at gcc dot gnu dot org 2009-09-25 08:10 -------
PPC has the same issue with -fno-schedule-insns:
test:
stwu 1,-16(1)
mflr 0
stw 0,20(1)
mr 0,3
mr 5,4
li 3,0
mr 4,0
bl foo
lwz 0,20(1)
addi 1,1,16
mtlr 0
blr
--
pinskia at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
Component|target |middle-end
GCC build triplet|i686-linux |
GCC host triplet|i686-linux |
GCC target triplet|arm-eabi |arm-eabi, powerpc*-*
Summary|redundant register move with|redundant register move with
|-mthumb |scheduler before RA turned
| |off
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40375
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug middle-end/40375] redundant register move with scheduler before RA turned off
2009-06-08 3:21 [Bug target/40375] New: redundant register move with -mthumb carrot at google dot com
` (8 preceding siblings ...)
2009-09-25 8:11 ` [Bug middle-end/40375] redundant register move with scheduler before RA turned off pinskia at gcc dot gnu dot org
@ 2010-02-10 10:55 ` steven at gcc dot gnu dot org
9 siblings, 0 replies; 11+ messages in thread
From: steven at gcc dot gnu dot org @ 2010-02-10 10:55 UTC (permalink / raw)
To: gcc-bugs
------- Comment #9 from steven at gcc dot gnu dot org 2010-02-10 10:55 -------
Reconfirmed with r156595 and r156650 (with and without -fschedule-insns, and
-fsched-pressure makes no difference either).
Vlad, you added some register pressure awareness to the scheduler. Do you think
there is a way to teach the scheduler to unconditionally move insns, or at
least simple moves, around if it reduces register pressure? (See comment #5 in
this PR.)
--
steven at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |vmakarov at gcc dot gnu dot
| |org
Last reconfirmed|2009-06-09 08:34:25 |2010-02-10 10:55:07
date| |
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40375
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2010-02-10 10:55 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-08 3:21 [Bug target/40375] New: redundant register move with -mthumb carrot at google dot com
2009-06-08 3:24 ` [Bug target/40375] " carrot at google dot com
2009-06-08 3:27 ` pinskia at gcc dot gnu dot org
2009-06-08 11:41 ` steven at gcc dot gnu dot org
2009-06-08 15:43 ` rguenth at gcc dot gnu dot org
2009-06-09 3:46 ` carrot at google dot com
2009-06-09 8:34 ` steven at gcc dot gnu dot org
2009-06-09 13:52 ` carrot at google dot com
2009-06-09 14:32 ` ramana at gcc dot gnu dot org
2009-09-25 8:11 ` [Bug middle-end/40375] redundant register move with scheduler before RA turned off pinskia at gcc dot gnu dot org
2010-02-10 10:55 ` steven at gcc dot gnu dot org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).