[Bug rtl-optimization/39837] [4.3/4.4/4.5 regression] extra spills due to RTL LICM
steven at gcc dot gnu dot org
gcc-bugzilla@gcc.gnu.org
Sat Jan 2 00:42:00 GMT 2010
------- Comment #6 from steven at gcc dot gnu dot org 2010-01-02 00:42 -------
Working with "gcc (GCC) 4.5.0 20090808 (experimental) [trunk revision 150579]",
I looked at what loop-invariant.c did to the test case.
This is the "t.c.154r.loop2" RTL dump (obtained with -fdump-rtl-all-slim):
;; Function test (test)
3 NOTE_INSN_BASIC_BLOCK
6 r135:SI=unspec[const(unspec[const(unspec[0x0] 21+0x4)] 24)] 3
7 r135:SI=unspec[r135:SI,0x4,0x0] 4
8 use r135:SI
2 NOTE_INSN_FUNCTION_BEG
L20:
5 NOTE_INSN_BASIC_BLOCK
9 r137:SI=unspec[`g'] 3
10 r136:SI=[r135:SI+r137:SI]
REG_DEAD: r137:SI
REG_EQUAL: `g'
11 r133:SI=[r136:SI+0x8]
REG_EQUAL: [const(`g'+0x8)] ! Pay close attention here...
14 r138:SI=r136:SI+0x8
REG_DEAD: r136:SI
REG_EQUAL: const(`g'+0x8) ! ...and here
15 r0:SI=r133:SI
16 r1:SI=r138:SI
REG_DEAD: r138:SI
REG_EQUAL: const(`g'+0x8)
17 r2:SI=r133:SI
REG_DEAD: r133:SI
18 r0:SI=call [`func'] argc:0x0
REG_DEAD: r2:SI
REG_DEAD: r1:SI
19 r134:SI=r0:SI
REG_DEAD: r0:SI
21 pc={(r134:SI!=0x0)?L20:pc}
REG_DEAD: r134:SI
REG_BR_PROB: 0x238c
24 NOTE_INSN_BASIC_BLOCK
The code has a load from the address "const(`g'+0x8)" and a load of the
constant itself to a register:
11 r133:SI=[r136:SI+0x8]
14 r138:SI=r136:SI+0x8
loop-invariant.c correctly notices the constant in insn 14 can be moved and it
moves the set to reg 138 from basic block 3 to basic block 2 (from the
"t.c.156r.loop2_invariant" dump, all "deferring rescan insn*" lines removed):
Set in insn 9 is invariant (0), cost 4, depends on
Set in insn 10 is invariant (1), cost 4, depends on 0
Set in insn 14 is invariant (2), cost 4, depends on 1
Set in insn 16 is invariant (3), cost 0, depends on 2
Decided to move invariant 2
Decided to move invariant 1
Decided to move invariant 0
changing bb of uid 9
from 3 to 2
changing bb of uid 10
from 3 to 2
changing bb of uid 14
from 3 to 2
The resulting RTL dump is this:
3 NOTE_INSN_BASIC_BLOCK
6 r135:SI=unspec[const(unspec[const(unspec[0x0] 21+0x4)] 24)] 3
7 r135:SI=unspec[r135:SI,0x4,0x0] 4
8 use r135:SI
2 NOTE_INSN_FUNCTION_BEG
9 r140:SI=unspec[`g'] 3
10 r141:SI=[r135:SI+r140:SI]
REG_DEAD: r137:SI
REG_EQUAL: `g'
14 r142:SI=r141:SI+0x8
REG_DEAD: r136:SI
REG_EQUAL: const(`g'+0x8)
L20:
5 NOTE_INSN_BASIC_BLOCK
46 r137:SI=r140:SI
47 r136:SI=r141:SI
11 r133:SI=[r141:SI+0x8] ! Aha! Why not r133=[r142] here?
REG_EQUAL: [const(`g'+0x8)]
48 r138:SI=r142:SI
15 r0:SI=r133:SI
16 r1:SI=r142:SI
REG_DEAD: r138:SI
REG_EQUAL: const(`g'+0x8)
17 r2:SI=r133:SI
REG_DEAD: r133:SI
18 r0:SI=call [`func'] argc:0x0
REG_DEAD: r2:SI
REG_DEAD: r1:SI
19 r134:SI=r0:SI
REG_DEAD: r0:SI
21 pc={(r134:SI!=0x0)?L45:pc}
REG_DEAD: r134:SI
REG_BR_PROB: 0x238c
L45:
44 NOTE_INSN_BASIC_BLOCK
24 NOTE_INSN_BASIC_BLOCK
After loop-invariant.c, reg 142 is set to "const(`g'+0x8)" in basic block 2,
before the loop:
14 r142:SI=r141:SI+0x8
But inside the loop, r142 is only used in insn 48 to set reg 138 (it was set in
insn 14 before loop-invariant.c). The fact that r142="const(`g'+0x8)" is not
used in insn 11:
11 r133:SI=[r141:SI+0x8]
48 r138:SI=r142:SI
Somehow, loop-invariant has failed to notice or exploit the equivalence.
--
steven at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
Last reconfirmed|2009-06-22 16:28:19 |2010-01-02 00:42:32
date| |
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39837
More information about the Gcc-bugs
mailing list