[patch] Compare addresses in operand_equal_p correctly
Zdenek Dvorak
rakdver@atrey.karlin.mff.cuni.cz
Thu Nov 9 23:37:00 GMT 2006
Hello,
operand_equal_p will claim that &a[i] != &a[i] most of the time, since
it will recursively ask whether a[i] == a[i], and fail because a[i] has
side effects. This patch makes operand_equal_p remember whether we are
inside ADDR_EXPR, and ignore side effects of the (nonexistent) memory access
in this case.
Bootstrapped & regtested on i686.
Zdenek
* tree.h (enum operand_equal_flag): Add OEP_IN_ADDRESS.
* fold-const.c (operand_equal_p): Do not take side effects into account
when OEP_IN_ADDRESS is passed in flags.
Index: tree.h
===================================================================
*** tree.h (revision 118545)
--- tree.h (working copy)
*************** extern int div_and_round_double (enum tr
*** 4251,4257 ****
enum operand_equal_flag
{
OEP_ONLY_CONST = 1,
! OEP_PURE_SAME = 2
};
extern int operand_equal_p (tree, tree, unsigned int);
--- 4257,4264 ----
enum operand_equal_flag
{
OEP_ONLY_CONST = 1,
! OEP_PURE_SAME = 2,
! OEP_IN_ADDRESS = 4
};
extern int operand_equal_p (tree, tree, unsigned int);
Index: fold-const.c
===================================================================
*** fold-const.c (revision 118545)
--- fold-const.c (working copy)
*************** truth_value_p (enum tree_code code)
*** 2479,2485 ****
If OEP_PURE_SAME is set, then pure functions with identical arguments
are considered the same. It is used when the caller has other ways
! to ensure that global memory is unchanged in between. */
int
operand_equal_p (tree arg0, tree arg1, unsigned int flags)
--- 2479,2488 ----
If OEP_PURE_SAME is set, then pure functions with identical arguments
are considered the same. It is used when the caller has other ways
! to ensure that global memory is unchanged in between.
!
! If OEP_IN_ADDRESS is set, then identical-looking memory references
! are considered equal, even if they have side effects. */
int
operand_equal_p (tree arg0, tree arg1, unsigned int flags)
*************** operand_equal_p (tree arg0, tree arg1, u
*** 2647,2654 ****
case tcc_reference:
/* If either of the pointer (or reference) expressions we are
dereferencing contain a side effect, these cannot be equal. */
! if (TREE_SIDE_EFFECTS (arg0)
! || TREE_SIDE_EFFECTS (arg1))
return 0;
switch (TREE_CODE (arg0))
--- 2650,2663 ----
case tcc_reference:
/* If either of the pointer (or reference) expressions we are
dereferencing contain a side effect, these cannot be equal. */
! if (!(flags & OEP_IN_ADDRESS)
! && (TREE_SIDE_EFFECTS (arg0)
! || TREE_SIDE_EFFECTS (arg1)))
! return 0;
!
! /* Types of structures must match. */
! if (AGGREGATE_TYPE_P (TREE_TYPE (arg0))
! && TREE_TYPE (arg0) != TREE_TYPE (arg1))
return 0;
switch (TREE_CODE (arg0))
*************** operand_equal_p (tree arg0, tree arg1, u
*** 2658,2682 ****
case MISALIGNED_INDIRECT_REF:
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. Operand 0
may be NULL when we're called to compare MEM_EXPRs. */
! return OP_SAME_WITH_NULL (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;
--- 2667,2701 ----
case MISALIGNED_INDIRECT_REF:
case REALPART_EXPR:
case IMAGPART_EXPR:
+ flags &= ~OEP_IN_ADDRESS;
return OP_SAME (0);
case ARRAY_REF:
case ARRAY_RANGE_REF:
/* Operands 2 and 3 may be null. */
! if (!OP_SAME (0))
! return false;
! flags &= ~OEP_IN_ADDRESS;
! return (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. Operand 0
may be NULL when we're called to compare MEM_EXPRs. */
! if (!OP_SAME_WITH_NULL (0))
! return false;
!
! flags &= ~OEP_IN_ADDRESS;
! return (OP_SAME (1)
! && OP_SAME_WITH_NULL (2));
case BIT_FIELD_REF:
! if (!OP_SAME (0))
! return false;
!
! flags &= ~OEP_IN_ADDRESS;
! return OP_SAME (1) && OP_SAME (2);
default:
return 0;
*************** operand_equal_p (tree arg0, tree arg1, u
*** 2686,2691 ****
--- 2705,2713 ----
switch (TREE_CODE (arg0))
{
case ADDR_EXPR:
+ flags |= OEP_IN_ADDRESS;
+ return OP_SAME (0);
+
case TRUTH_NOT_EXPR:
return OP_SAME (0);
*************** operand_equal_p (tree arg0, tree arg1, u
*** 2745,2750 ****
--- 2767,2779 ----
}
case tcc_declaration:
+ if (TREE_CODE (arg0) == FIELD_DECL)
+ return arg0 == arg1;
+
+ if ((flags & OEP_IN_ADDRESS) != 0
+ && SSA_VAR_P (arg0))
+ return arg0 == arg1;
+
/* Consider __builtin_sqrt equal to sqrt. */
return (TREE_CODE (arg0) == FUNCTION_DECL
&& DECL_BUILT_IN (arg0) && DECL_BUILT_IN (arg1)
More information about the Gcc-patches
mailing list