[patch] Crossjumping corrupts alias info

Andreas Krebbel krebbel1@de.ibm.com
Wed Mar 3 08:30:00 GMT 2004


Hello Richard,

I've reworked the patch again. As you've probably noticed I'm not
very familar with the gcc tree stuff, but I hope the patch will do it 
in the right way now. Thanks for reviewing it again and again!

As Mark Mitchell has recently wrote in:
http://gcc.gnu.org/ml/gcc/2004-03/msg00074.html
I've simply compared pointers if both tree nodes are decls instead of
comparing IDENTIFIER_POINTER (DECL_NAME ( ...)).

Bootstrapped without regressions on s390-ibm-linux and s390x-ibm-linux.

OK?
 
Bye,

-Andreas-

2004-03-02  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	2 Mar 2004 17:53:03 -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/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	2 Mar 2004 17:53:04 -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));
+   
+   if ((DECL_P (expr1) && DECL_P (expr2))     /* two different decls */
+       || (DECL_P (expr1) || DECL_P (expr2))) /* one of them not a decl */
+     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
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	2 Mar 2004 17:53:04 -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,948 ----
  }
   
  
+ /* 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;
+ 
+   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':
+  	  if (GET_CODE(x) == 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_OFFSET (x) != MEM_OFFSET (y))
+ 		      || ! 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);
+ 		    }
+ 		  
+ 		  if (MEM_SIZE (x) != MEM_SIZE (y))
+ 		    {
+ 		      set_mem_size (x, 0);
+ 		      set_mem_size (y, 0);
+ 		    }
+ 		  
+ 		  if (MEM_ALIGN (x) != MEM_ALIGN (y))
+ 		    {
+ 		      set_mem_align (x, 0);
+ 		      set_mem_align (y, 0);
+ 		    }
+ 		}
+ 	    }
+ 	  
+ 	  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 ****
--- 1102,1109 ----
  
        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))



More information about the Gcc-patches mailing list