This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] Crossjumping corrupts alias info
- From: Andreas Krebbel <krebbel1 at de dot ibm dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 5 Mar 2004 12:54:39 +0100
- Subject: Re: [patch] Crossjumping corrupts alias info
- Organization: IBM Entwicklung GmbH
- References: <200402201750.05271.krebbel1@de.ibm.com> <20040220230123.GE29641@redhat.com>
Hi,
I've made the changes discussed in the last email.
Bootstrapped without regressions on s390-ibm-linux and
s390x-ibm-linux. OK?
Bye,
Andreas
2004-03-05 Andreas Krebbel <krebbel1@de.ibm.com>
* rtl.h (mem_expr_equal_p): Function prototype added.
* cfgcleanup.c (merge_memattrs): New function.
(flow_find_cross_jump): Call merge_memattrs for matching insns.
* emit-rtl.c (mem_expr_equal_p): New function.
Index: gcc/rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.448.4.2
diff -p -c -r1.448.4.2 rtl.h
*** gcc/rtl.h 12 Feb 2004 15:30:45 -0000 1.448.4.2
--- gcc/rtl.h 5 Mar 2004 10:22:06 -0000
*************** extern rtx emit_copy_of_insn_after (rtx,
*** 1452,1457 ****
--- 1452,1458 ----
extern void set_reg_attrs_from_mem (rtx, rtx);
extern void set_mem_attrs_from_reg (rtx, rtx);
extern void set_reg_attrs_for_parm (rtx, rtx);
+ extern int mem_expr_equal_p (tree, tree);
/* In rtl.c */
extern rtx rtx_alloc (RTX_CODE);
Index: gcc/cfgcleanup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgcleanup.c,v
retrieving revision 1.99.2.4
diff -p -c -r1.99.2.4 cfgcleanup.c
*** gcc/cfgcleanup.c 30 Jan 2004 11:07:49 -0000 1.99.2.4
--- gcc/cfgcleanup.c 5 Mar 2004 10:22:06 -0000
*************** Software Foundation, 59 Temple Place - S
*** 48,53 ****
--- 48,54 ----
#include "params.h"
#include "tm_p.h"
#include "target.h"
+ #include "expr.h"
/* cleanup_cfg maintains following flags for each basic block. */
*************** static bool mark_effect (rtx, bitmap);
*** 84,90 ****
static void notice_new_block (basic_block);
static void update_forwarder_flag (basic_block);
static int mentions_nonequal_regs (rtx *, void *);
!
/* Set flags for newly created block. */
static void
--- 85,92 ----
static void notice_new_block (basic_block);
static void update_forwarder_flag (basic_block);
static int mentions_nonequal_regs (rtx *, void *);
! static void merge_memattrs (rtx, rtx);
!
/* Set flags for newly created block. */
static void
*************** merge_blocks_move (edge e, basic_block b
*** 857,862 ****
--- 859,946 ----
}
+ /* Removes the memory attributes of MEM expression
+ if they are not equal. */
+
+ void
+ merge_memattrs (rtx x, rtx y)
+ {
+ int i;
+ int j;
+ enum rtx_code code;
+ const char *fmt;
+
+ if (x == y)
+ return;
+ if (x == 0 || y == 0)
+ return;
+
+ code = GET_CODE (x);
+
+ if (code != GET_CODE (y))
+ return;
+
+ if (GET_MODE (x) != GET_MODE (y))
+ return;
+
+ if (code == MEM && MEM_ATTRS (x) != MEM_ATTRS (y))
+ {
+ if (! MEM_ATTRS (x))
+ MEM_ATTRS (y) = 0;
+ else if (! MEM_ATTRS (y))
+ MEM_ATTRS (x) = 0;
+ else
+ {
+ if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y))
+ {
+ set_mem_alias_set (x, 0);
+ set_mem_alias_set (y, 0);
+ }
+
+ if (! mem_expr_equal_p (MEM_EXPR (x), MEM_EXPR (y)))
+ {
+ set_mem_expr (x, 0);
+ set_mem_expr (y, 0);
+ set_mem_offset (x, 0);
+ set_mem_offset (y, 0);
+ }
+ else if (MEM_OFFSET (x) != MEM_OFFSET (y))
+ {
+ set_mem_offset (x, 0);
+ set_mem_offset (y, 0);
+ }
+
+ set_mem_size (x, MAX (MEM_SIZE (x), MEM_SIZE (y)));
+ set_mem_size (y, MEM_SIZE (x));
+
+ set_mem_align (x, MIN (MEM_ALIGN (x), MEM_ALIGN (y)));
+ set_mem_align (y, MEM_ALIGN (x));
+ }
+ }
+
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ switch (fmt[i])
+ {
+ case 'E':
+ /* Two vectors must have the same length. */
+ if (XVECLEN (x, i) != XVECLEN (y, i))
+ return;
+
+ for (j = 0; j < XVECLEN (x, i); j++)
+ merge_memattrs (XVECEXP (x, i, j), XVECEXP (y, i, j));
+
+ break;
+
+ case 'e':
+ merge_memattrs (XEXP (x, i), XEXP (y, i));
+ }
+ }
+ return;
+ }
+
+
/* Return true if I1 and I2 are equivalent and thus can be crossjumped. */
static bool
*************** flow_find_cross_jump (int mode ATTRIBUTE
*** 1016,1021 ****
--- 1100,1107 ----
if (!insns_match_p (mode, i1, i2))
break;
+
+ merge_memattrs (i1, i2);
/* Don't begin a cross-jump with a NOTE insn. */
if (INSN_P (i1))
Index: gcc/emit-rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/emit-rtl.c,v
retrieving revision 1.365.4.3
diff -p -c -r1.365.4.3 emit-rtl.c
*** gcc/emit-rtl.c 11 Feb 2004 08:07:48 -0000 1.365.4.3
--- gcc/emit-rtl.c 5 Mar 2004 10:22:06 -0000
*************** component_ref_for_mem_expr (tree ref)
*** 1520,1525 ****
--- 1520,1559 ----
TREE_OPERAND (ref, 1));
}
+ /* Returns 1 if both MEM_EXPR can be considered equal
+ and 0 otherwise. */
+
+ int
+ mem_expr_equal_p (tree expr1, tree expr2)
+ {
+ if (expr1 == expr2)
+ return 1;
+
+ if (! expr1 || ! expr2)
+ return 0;
+
+ if (TREE_CODE (expr1) != TREE_CODE (expr2))
+ return 0;
+
+ if (TREE_CODE (expr1) == COMPONENT_REF)
+ return
+ mem_expr_equal_p (TREE_OPERAND (expr1, 0),
+ TREE_OPERAND (expr2, 0))
+ && mem_expr_equal_p (TREE_OPERAND (expr1, 1), /* field decl */
+ TREE_OPERAND (expr2, 1));
+
+ if (TREE_CODE (expr1) == INDIRECT_REF)
+ return mem_expr_equal_p (TREE_OPERAND (expr1, 0),
+ TREE_OPERAND (expr2, 0));
+
+ /* Decls with different pointers can't be equal. */
+ if (DECL_P (expr1))
+ return 0;
+
+ abort(); /* ARRAY_REFs, ARRAY_RANGE_REFs and BIT_FIELD_REFs should already
+ have been resolved here. */
+ }
+
/* Given REF, a MEM, and T, either the type of X or the expression
corresponding to REF, set the memory attributes. OBJECTP is nonzero
if we are making a new object of this type. BITPOS is nonzero if