This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Proposed reworking of operand_equal_p
- From: kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner)
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 31 Aug 04 19:16:22 EDT
- Subject: Proposed reworking of operand_equal_p
There were stylist issues raised the last time I tried to do the proper
fix to this to check all the args of ARRAY_REF and COMPONENT_REF, so I
thought I'd run this replacement by folks.
Tested on x86-64-linux-gnu.
2004-08-31 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* fold-const.c (operand_equal_p): Remove code to allow null ARG0/1.
Define locals macros OP_SAME and OP_SAME_WITH_NULL and use throughout.
*** fold-const.c 27 Aug 2004 16:44:58 -0000 1.445
--- fold-const.c 29 Aug 2004 21:32:51 -0000
*************** int
*** 2286,2300 ****
operand_equal_p (tree arg0, tree arg1, unsigned int flags)
{
- /* If one is specified and the other isn't, they aren't equal and if
- neither is specified, they are.
-
- ??? This is temporary and is meant only to handle the cases of the
- optional operands for COMPONENT_REF and ARRAY_REF. */
- if ((arg0 && !arg1) || (!arg0 && arg1))
- return 0;
- else if (!arg0 && !arg1)
- return 1;
/* If either is ERROR_MARK, they aren't equal. */
! else if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK)
return 0;
--- 2286,2291 ----
operand_equal_p (tree arg0, tree arg1, unsigned int flags)
{
/* If either is ERROR_MARK, they aren't equal. */
! if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK)
return 0;
*************** operand_equal_p (tree arg0, tree arg1, u
*** 2388,2391 ****
--- 2379,2393 ----
return 0;
+ /* Define macros to test an operan from arg0 and arg1 for equality and a
+ variant that allows null and views null as being different from any
+ non-null value. In the latter case, if either is null, the both
+ must be; otherwise, do the normal comparison. */
+ #define OP_SAME(N) operand_equal_p (TREE_OPERAND (arg0, N), \
+ TREE_OPERAND (arg1, N), flags)
+
+ #define OP_SAME_WITH_NULL(N) \
+ ((!TREE_OPERAND (arg0, N) || !TREE_OPERAND (arg1, N)) \
+ ? TREE_OPERAND (arg0, N) == TREE_OPERAND (arg1, N) : OP_SAME (N))
+
switch (TREE_CODE_CLASS (TREE_CODE (arg0)))
{
*************** operand_equal_p (tree arg0, tree arg1, u
*** 2397,2409 ****
return 0;
! return operand_equal_p (TREE_OPERAND (arg0, 0),
! TREE_OPERAND (arg1, 0), flags);
case '<':
case '2':
! if (operand_equal_p (TREE_OPERAND (arg0, 0),
! TREE_OPERAND (arg1, 0), flags)
! && operand_equal_p (TREE_OPERAND (arg0, 1),
! TREE_OPERAND (arg1, 1), flags))
return 1;
--- 2399,2407 ----
return 0;
! return OP_SAME (0);
case '<':
case '2':
! if (OP_SAME (0) && OP_SAME (1))
return 1;
*************** operand_equal_p (tree arg0, tree arg1, u
*** 2427,2461 ****
case REALPART_EXPR:
case IMAGPART_EXPR:
! return operand_equal_p (TREE_OPERAND (arg0, 0),
! TREE_OPERAND (arg1, 0), flags);
case ARRAY_REF:
case ARRAY_RANGE_REF:
! return (operand_equal_p (TREE_OPERAND (arg0, 0),
! TREE_OPERAND (arg1, 0), flags)
! && operand_equal_p (TREE_OPERAND (arg0, 1),
! TREE_OPERAND (arg1, 1), flags)
! && operand_equal_p (TREE_OPERAND (arg0, 2),
! TREE_OPERAND (arg1, 2), flags)
! && operand_equal_p (TREE_OPERAND (arg0, 3),
! TREE_OPERAND (arg1, 3), flags));
!
case COMPONENT_REF:
! return (operand_equal_p (TREE_OPERAND (arg0, 0),
! TREE_OPERAND (arg1, 0), flags)
! && operand_equal_p (TREE_OPERAND (arg0, 1),
! TREE_OPERAND (arg1, 1), flags)
! && operand_equal_p (TREE_OPERAND (arg0, 2),
! TREE_OPERAND (arg1, 2), flags));
!
case BIT_FIELD_REF:
! return (operand_equal_p (TREE_OPERAND (arg0, 0),
! TREE_OPERAND (arg1, 0), flags)
! && operand_equal_p (TREE_OPERAND (arg0, 1),
! TREE_OPERAND (arg1, 1), flags)
! && operand_equal_p (TREE_OPERAND (arg0, 2),
! TREE_OPERAND (arg1, 2), flags));
default:
return 0;
--- 2425,2445 ----
case REALPART_EXPR:
case IMAGPART_EXPR:
! return OP_SAME (0);
case ARRAY_REF:
case ARRAY_RANGE_REF:
! /* Operands 2 and 3 may be null. */
! return (OP_SAME (0)
! && OP_SAME (1)
! && OP_SAME_WITH_NULL (2)
! && OP_SAME_WITH_NULL (3));
case COMPONENT_REF:
! /* Handle operand 2 the same as for ARRAY_REF. */
! return OP_SAME (0) && OP_SAME (1) && OP_SAME_WITH_NULL (2);
case BIT_FIELD_REF:
! return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);
!
default:
return 0;
*************** operand_equal_p (tree arg0, tree arg1, u
*** 2467,2497 ****
case ADDR_EXPR:
case TRUTH_NOT_EXPR:
! return operand_equal_p (TREE_OPERAND (arg0, 0),
! TREE_OPERAND (arg1, 0), flags);
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
! return operand_equal_p (TREE_OPERAND (arg0, 0),
! TREE_OPERAND (arg1, 0), flags)
! && operand_equal_p (TREE_OPERAND (arg0, 1),
! TREE_OPERAND (arg1, 1), flags);
case TRUTH_AND_EXPR:
case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR:
return (operand_equal_p (TREE_OPERAND (arg0, 0),
! TREE_OPERAND (arg1, 0), flags)
&& operand_equal_p (TREE_OPERAND (arg0, 1),
! TREE_OPERAND (arg1, 1), flags))
! || (operand_equal_p (TREE_OPERAND (arg0, 0),
! TREE_OPERAND (arg1, 1), flags)
! && operand_equal_p (TREE_OPERAND (arg0, 1),
! TREE_OPERAND (arg1, 0), flags));
case CALL_EXPR:
/* If the CALL_EXPRs call different functions, then they
clearly can not be equal. */
! if (! operand_equal_p (TREE_OPERAND (arg0, 0),
! TREE_OPERAND (arg1, 0), flags))
return 0;
--- 2451,2476 ----
case ADDR_EXPR:
case TRUTH_NOT_EXPR:
! return OP_SAME (0);
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
! return OP_SAME (0) && OP_SAME (1);
case TRUTH_AND_EXPR:
case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR:
+ if (OP_SAME (0) && OP_SAME (1))
+ return 1;
+
+ /* Otherwise take into account this is a commutative operation. */
return (operand_equal_p (TREE_OPERAND (arg0, 0),
! TREE_OPERAND (arg1, 1), flags)
&& operand_equal_p (TREE_OPERAND (arg0, 1),
! TREE_OPERAND (arg1, 0), flags));
case CALL_EXPR:
/* If the CALL_EXPRs call different functions, then they
clearly can not be equal. */
! if (!OP_SAME (0))
return 0;
*************** operand_equal_p (tree arg0, tree arg1, u
*** 2539,2542 ****
--- 2518,2524 ----
return 0;
}
+
+ #undef OP_SAME
+ #undef OP_SAME_WITH_NULL
}