http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52285



Steven Bosscher <steven at gcc dot gnu.org> changed:



           What    |Removed                     |Added

----------------------------------------------------------------------------

             Status|NEW                         |ASSIGNED

                 CC|steven at gcc dot gnu.org   |

         AssignedTo|unassigned at gcc dot       |steven at gcc dot gnu.org

                   |gnu.org                     |



--- Comment #10 from Steven Bosscher <steven at gcc dot gnu.org> 2012-11-13 
10:30:27 UTC ---

There are several reasons why RTL LIM cannot currently hoist the (frame) rtx.





The first is that in general it stays away from any HARD_REGISTER_P reg with

a 10-foot pole.  For most hard registers this is probably a good strategy:

Anything that's in a "real" hard register at this point is there for a reason

(function return, global reg, whatever) and almost certainly not invariant in

a loop.





Second, RTL LIM only hoists expression that can be assigned to the original

SET_DEST of a single set. In the case of this PR, the insn in case is:



;;   UD chains for insn luid 2 uid 15

;;      reg 20 { }

;;      reg 63 { d2(bb 4 insn 12) }

(insn 15 12 16 4 (set (reg:CCZ 17 flags)

        (compare:CCZ (reg/v/f:DI 63 [ p ])

            (reg/f:DI 20 frame))) PR52285.c:10 8 {*cmpdi_1}

     (nil))



This fails in may_assign_reg_p because (reg:CCZ 17) can't be assigned to (it

is a hard register, and I suppose it has class NO_REGS), so the SET_SRC is

not even considered by find_invariant_insn as a potential invariant.  I think

this condition can be relaxed with something like,



Index: loop-invariant.c

===================================================================

--- loop-invariant.c    (revision 193454)

+++ loop-invariant.c    (working copy)

@@ -874,11 +874,11 @@

   dest = SET_DEST (set);



   if (!REG_P (dest)

-      || HARD_REGISTER_P (dest))

+      || HARD_REGISTER_P (dest)

+      || !may_assign_reg_p (dest))

     simple = false;



-  if (!may_assign_reg_p (SET_DEST (set))

-      || !check_maybe_invariant (SET_SRC (set)))

+  if (!check_maybe_invariant (SET_SRC (set)))

     return;



   /* If the insn can throw exception, ...





Finally, RTL LIM cannot hoist parts of expressions.  It only hoists the

SET_SRC as a whole, or nothing at all.  I have patches for that, originally

developed to hoist addresses out of MEMs.  I'll dust them off and see if

I can make it handle "(reg:frame + CONST_INT)" and other expressions that 

involve eliminable regs.

Reply via email to