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]

validate_replace_rtx_1 fix


Hi,
as previous change has much less smooth than I've hoped for, I've decided to continue
in small steps.  This step fixes the validate_replace_rtx_1 bug, that rtxes are not
properly canonicalizes when simple object is replaced by expression or vice versa.

Originally I've copied the condition from combine, but I've found that the
condition is overactive. If both operands are SUBREGs, it returns always 1 and
gcc keeps swapping them over and over, so I've created new function for testing
that that avoids this problem.

If this gets accepted, I would like to convert rest of compiler to use this bit.

Honza

Thu May 17 19:53:30 CEST 2001  Jan Hubicka  <jh@suse.cz>

	* recog.c (validate_replace_rtx_1): Properly canonicalize expression
	* rtl.h (swap_commutative_operands_p): Declare.
	* rtlanal.c (swap_commutative_operands_p): New.

Index: recog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/recog.c,v
retrieving revision 1.101
diff -c -3 -p -r1.101 recog.c
*** recog.c	2001/05/17 15:00:35	1.101
--- recog.c	2001/05/17 17:42:47
*************** validate_replace_rtx_1 (loc, from, to, o
*** 468,474 ****
  
        validate_replace_rtx_1 (&XEXP (x, 0), from, to, object);
        validate_replace_rtx_1 (&XEXP (x, 1), from, to, object);
!       if (prev_changes != num_changes && CONSTANT_P (XEXP (x, 0)))
  	{
  	  validate_change (object, loc,
  			   gen_rtx_fmt_ee (GET_RTX_CLASS (code) == 'c' ? code
--- 468,475 ----
  
        validate_replace_rtx_1 (&XEXP (x, 0), from, to, object);
        validate_replace_rtx_1 (&XEXP (x, 1), from, to, object);
!       if (prev_changes != num_changes
! 	  && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
  	{
  	  validate_change (object, loc,
  			   gen_rtx_fmt_ee (GET_RTX_CLASS (code) == 'c' ? code
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.259
diff -c -3 -p -r1.259 rtl.h
*** rtl.h	2001/05/17 15:00:35	1.259
--- rtl.h	2001/05/17 17:42:47
*************** extern int reg_used_between_p		PARAMS ((
*** 1366,1371 ****
--- 1370,1376 ----
  extern int reg_referenced_between_p	PARAMS ((rtx, rtx, rtx));
  extern int reg_set_between_p		PARAMS ((rtx, rtx, rtx));
  extern int regs_set_between_p		PARAMS ((rtx, rtx, rtx));
+ extern int swap_commutative_operands_p	PARAMS ((rtx, rtx));
  extern int modified_between_p		PARAMS ((rtx, rtx, rtx));
  extern int no_labels_between_p		PARAMS ((rtx, rtx));
  extern int no_jumps_between_p		PARAMS ((rtx, rtx));
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtlanal.c,v
retrieving revision 1.95
diff -c -3 -p -r1.95 rtlanal.c
*** rtlanal.c	2001/05/13 21:16:57	1.95
--- rtlanal.c	2001/05/17 17:42:48
*************** regno_use_in (regno, x)
*** 2533,2538 ****
--- 2533,2570 ----
    return NULL_RTX;
  }
  
+ /* Return 1 iff it is neccesary to swap operands of commutative operation
+    in order to canonicalize expression.  */
+ int
+ swap_commutative_operands_p (x, y)
+      rtx x, y;
+ {
+    /* Constant ought to go second.  */
+    if (CONSTANT_P (x))
+      {
+ 	/* A constant is always made the second operand.  */
+ 	if (!CONSTANT_P (y))
+ 	  return 1;
+ 	/* CONST_INT is the preffered over other constants.  */
+ 	if (GET_CODE (x) == CONST_INT && GET_CODE (y) != CONST_INT)
+ 	  return 1;
+ 	/* CONST_DOUBLE should be the second otherwise.  */
+ 	if (GET_CODE (x) == CONST_DOUBLE && GET_CODE (y) != CONST_DOUBLE)
+ 	  return 1;
+      }
+    /* Make complex expression the first.  */
+    if (GET_RTX_CLASS (GET_CODE (x)) == 'o'
+        && GET_RTX_CLASS (GET_CODE (y)) != 'o')
+      return 1;
+    /* Put SUBREG the second.  */
+    if (GET_CODE (x) == SUBREG
+        && GET_RTX_CLASS (GET_CODE (SUBREG_REG (x))) == 'o'
+        && GET_RTX_CLASS (GET_CODE (y)) != 'o'
+        && (GET_CODE (x) != SUBREG
+ 	   || GET_RTX_CLASS (GET_CODE (SUBREG_REG (y))) != 'o'))
+      return 1;
+    return 0;
+ }
  
  /* Return 1 if X is an autoincrement side effect and the register is
     not the stack pointer.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]