[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