This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
validate_replace_rtx_1 fix
- To: gcc-patches at gcc dot gnu dot org, patches at x86-64 dot org, rth at cygnus dot com, kenner at vlsi1 dot ultra dot nyu dot edu
- Subject: validate_replace_rtx_1 fix
- From: Jan Hubicka <jh at suse dot cz>
- Date: Thu, 17 May 2001 19:56:04 +0200
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. */