This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] Crossjumping corrupts alias info


Hello Richard,

I've reworked the patch. Crossjumping now allows the same
insns to be merged as before. Afterwards the memory attributes are
removed in case they were different.

gcc 3.4. branch bootstrapped without regressions on s390-ibm-linux and 
s390x-ibm-linux.

OK?

Bye,

-Andreas-

2004-02-25  Andreas Krebbel  <krebbel1@de.ibm.com>

	* rtl.h (mem_expr_equal_p): Function prototype added.
	* cfgcleanup.c (MEM_ATTRIBUTES_EQUAL_P): New macro.
	(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/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	25 Feb 2004 12:00:10 -0000
*************** enum bb_flags
*** 67,72 ****
--- 67,80 ----
  
  #define FORWARDER_BLOCK_P(BB) (BB_FLAGS (BB) & BB_FORWARDER_BLOCK)
  
+ /* Compare the attributes of two MEM rtx.  */
+ #define MEM_ATTRIBUTES_EQUAL_P(RTX1, RTX2)                         \
+ ((MEM_ALIAS_SET (RTX1) == MEM_ALIAS_SET (RTX2)                     \
+   && MEM_OFFSET (RTX1) == MEM_OFFSET (RTX2)                        \
+   && MEM_SIZE (RTX1) == MEM_SIZE (RTX2)                            \
+   && MEM_ALIGN (RTX1) == MEM_ALIGN (RTX2)                          \
+   && mem_expr_equal_p (MEM_EXPR (RTX1), MEM_EXPR (RTX2))) ? 1 : 0)
+ 
  static bool try_crossjump_to_edge (int, edge, edge);
  static bool try_crossjump_bb (int, basic_block);
  static bool outgoing_edges_match (int, basic_block, 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
--- 92,99 ----
  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 ****
--- 866,924 ----
  }
   
  
+ /* 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_ATTRIBUTES_EQUAL_P (x, y))
+ 	    {
+ 	      x->u.fld[1].rtmem = 0;
+ 	      y->u.fld[1].rtmem = 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
*************** insns_match_p (int mode ATTRIBUTE_UNUSED
*** 886,892 ****
  
    if (GET_CODE (i1) == CALL_INSN
        && (!rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1),
! 		        CALL_INSN_FUNCTION_USAGE (i2))
  	  || SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2)))
      return false;
  
--- 948,954 ----
  
    if (GET_CODE (i1) == CALL_INSN
        && (!rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1),
! 			CALL_INSN_FUNCTION_USAGE (i2))
  	  || SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2)))
      return false;
  
*************** flow_find_cross_jump (int mode ATTRIBUTE
*** 1016,1021 ****
--- 1078,1085 ----
  
        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/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	25 Feb 2004 12:00:12 -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	25 Feb 2004 12:00:12 -0000
*************** component_ref_for_mem_expr (tree ref)
*** 1520,1525 ****
--- 1520,1551 ----
  		  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)
+     {
+       /* COMPONENT_REF of something variable. The pointers to the 
+ 	 component refs maybe unequal but the operand must match.  */
+       if (! TREE_OPERAND (expr1, 0) && ! TREE_OPERAND (expr2, 0))
+ 	return TREE_OPERAND (expr1, 1) == TREE_OPERAND (expr2, 1);
+     }
+ 
+   return 0;
+ }
+ 
  /* 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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]