RTL sharing problem
Jeffrey A Law
law@cygnus.com
Mon Aug 30 23:28:00 GMT 1999
Boy another fun bug. It's amazing how many interesting problems the PA64 port
is exposing.
copy_rtx_if_shared allowed a MEM of this form to be shared:
(mem (virtual_stack_vars_rtx)
Virtual register instantiation changed the shared copy (but did not unshare
the node) into
(mem (plus (fp) (const_int))
We had two references to this shared node in the insn chain. During
instruction combination we ended up turning the mem into something like
(mem (ior (fp) (const_int)) inside a larger RTL expression.
Then we broke out the (ior (fp) (const_int) using the generic splitting
code in the combiner. This resulted in a valid 3->2 combination with
the first insn looking like
(insn X Y Z (set (dest) (ior (fp) (const_int)))
Which was perfectly fine in the context of the 3->2 combination; however
it produced an unrecognizable insn in the other reference to the shared
nodes -- (mem (ior (...)) is not a valid memory reference...
This patch fixes the problem by unsharing nodes which reference the
special registers. It may be possible to delete some code in
instantiate_virtual_registers_1 because of this change -- I'm still
evaluating the potential cleanup.
* emit-rtl.c (copy_rtx_if_shared): A MEM which references
virtual_stack_vars_rtx or virtual_incoming_args_rtx can not
be shared.
Index: emit-rtl.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/emit-rtl.c,v
retrieving revision 1.136
diff -c -3 -p -r1.136 emit-rtl.c
*** emit-rtl.c 1999/08/24 05:11:25 1.136
--- emit-rtl.c 1999/08/31 06:19:01
*************** copy_rtx_if_shared (orig)
*** 1695,1710 ****
return x;
case MEM:
! /* A MEM is allowed to be shared if its address is constant
! or is a constant plus one of the special registers. */
! if (CONSTANT_ADDRESS_P (XEXP (x, 0))
! || XEXP (x, 0) == virtual_stack_vars_rtx
! || XEXP (x, 0) == virtual_incoming_args_rtx)
return x;
if (GET_CODE (XEXP (x, 0)) == PLUS
- && (XEXP (XEXP (x, 0), 0) == virtual_stack_vars_rtx
- || XEXP (XEXP (x, 0), 0) == virtual_incoming_args_rtx)
&& CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
{
/* This MEM can appear in more than one place,
--- 1695,1712 ----
return x;
case MEM:
! /* A MEM is allowed to be shared if its address is constant.
!
! We used to allow sharing of MEMs which referenced
! virtual_stack_vars_rtx or virtual_incoming_args_rtx, but
! that can lose. instantiate_virtual_regs will not unshare
! the MEMs, and combine may change the structure of the address
! because it looks safe and profitable in one context, but
! in some other context it creates unrecognizable RTL. */
! if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
return x;
if (GET_CODE (XEXP (x, 0)) == PLUS
&& CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
{
/* This MEM can appear in more than one place,
More information about the Gcc-patches
mailing list