aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/fold-const.c47
-rw-r--r--gcc/tree-core.h2
-rw-r--r--gcc/tree-ssa-tail-merge.c2
4 files changed, 35 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e368c9f..64388a4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2015-11-07 Jan Hubicka <hubicka@ucw.cz>
+
+ * tree-core.h (size_type_kind): Remove OEP_CONSTANT_ADDRESS_OF and
+ add OEP_MATCH_SIDE_EFFECTS.
+ * fold-const.c (operand_equal_p): Update documentation; handle
+ OEP_MATCH_SIDE_EFFECTS.
+ * tree-ssa-tail-merge.c (gimple_operand_equal_value_p): Use
+ OEP_MATCH_SIDE_EFFECTS.
+
2015-11-06 Benedikt Huber <benedikt.huber@theobroma-systems.com>
Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index ee9b349..fb613da 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -2649,8 +2649,7 @@ combine_comparisons (location_t loc,
}
/* Return nonzero if two operands (typically of the same tree node)
- are necessarily equal. If either argument has side-effects this
- function returns zero. FLAGS modifies behavior as follows:
+ are necessarily equal. FLAGS modifies behavior as follows:
If OEP_ONLY_CONST is set, only return nonzero for constants.
This function tests whether the operands are indistinguishable;
@@ -2675,9 +2674,14 @@ combine_comparisons (location_t loc,
to ensure that global memory is unchanged in between.
If OEP_ADDRESS_OF is set, we are actually comparing addresses of objects,
- not values of expressions. OEP_CONSTANT_ADDRESS_OF in addition to
- OEP_ADDRESS_OF is used for ADDR_EXPR with TREE_CONSTANT flag set and we
- further ignore any side effects on SAVE_EXPRs then. */
+ not values of expressions.
+
+ Unless OEP_MATCH_SIDE_EFFECTS is set, the function returns false on
+ any operand with side effect. This is unnecesarily conservative in the
+ case we know that arg0 and arg1 are in disjoint code paths (such as in
+ ?: operator). In addition OEP_MATCH_SIDE_EFFECTS is used when comparing
+ addresses with TREE_CONSTANT flag set so we know that &var == &var
+ even if var is volatile. */
int
operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
@@ -2698,9 +2702,8 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
{
/* Address of INTEGER_CST is not defined; check that we did not forget
- to drop the OEP_ADDRESS_OF/OEP_CONSTANT_ADDRESS_OF flags. */
- gcc_checking_assert (!(flags
- & (OEP_ADDRESS_OF | OEP_CONSTANT_ADDRESS_OF)));
+ to drop the OEP_ADDRESS_OF flags. */
+ gcc_checking_assert (!(flags & OEP_ADDRESS_OF));
return tree_int_cst_equal (arg0, arg1);
}
@@ -2806,7 +2809,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
they are necessarily equal as well. */
if (arg0 == arg1 && ! (flags & OEP_ONLY_CONST)
&& (TREE_CODE (arg0) == SAVE_EXPR
- || (flags & OEP_CONSTANT_ADDRESS_OF)
+ || (flags & OEP_MATCH_SIDE_EFFECTS)
|| (! TREE_SIDE_EFFECTS (arg0) && ! TREE_SIDE_EFFECTS (arg1))))
return 1;
@@ -2865,11 +2868,10 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
TREE_STRING_LENGTH (arg0)));
case ADDR_EXPR:
- gcc_checking_assert (!(flags
- & (OEP_ADDRESS_OF | OEP_CONSTANT_ADDRESS_OF)));
+ gcc_checking_assert (!(flags & OEP_ADDRESS_OF));
return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0),
flags | OEP_ADDRESS_OF
- | OEP_CONSTANT_ADDRESS_OF);
+ | OEP_MATCH_SIDE_EFFECTS);
case CONSTRUCTOR:
/* In GIMPLE empty constructors are allowed in initializers of
aggregates. */
@@ -2928,7 +2930,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
/* If either of the pointer (or reference) expressions we are
dereferencing contain a side effect, these cannot be equal,
but their addresses can be. */
- if ((flags & OEP_CONSTANT_ADDRESS_OF) == 0
+ if ((flags & OEP_MATCH_SIDE_EFFECTS) == 0
&& (TREE_SIDE_EFFECTS (arg0)
|| TREE_SIDE_EFFECTS (arg1)))
return 0;
@@ -2936,11 +2938,11 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
switch (TREE_CODE (arg0))
{
case INDIRECT_REF:
- if (!(flags & (OEP_ADDRESS_OF | OEP_CONSTANT_ADDRESS_OF))
+ if (!(flags & OEP_ADDRESS_OF)
&& (TYPE_ALIGN (TREE_TYPE (arg0))
!= TYPE_ALIGN (TREE_TYPE (arg1))))
return 0;
- flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF);
+ flags &= ~OEP_ADDRESS_OF;
return OP_SAME (0);
case REALPART_EXPR:
@@ -2950,7 +2952,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
case TARGET_MEM_REF:
case MEM_REF:
- if (!(flags & (OEP_ADDRESS_OF | OEP_CONSTANT_ADDRESS_OF)))
+ if (!(flags & OEP_ADDRESS_OF))
{
/* Require equal access sizes */
if (TYPE_SIZE (TREE_TYPE (arg0)) != TYPE_SIZE (TREE_TYPE (arg1))
@@ -2975,7 +2977,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
!= TYPE_ALIGN (TREE_TYPE (arg1)))
return 0;
}
- flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF);
+ flags &= ~OEP_ADDRESS_OF;
return (OP_SAME (0) && OP_SAME (1)
/* TARGET_MEM_REF require equal extra operands. */
&& (TREE_CODE (arg0) != TARGET_MEM_REF
@@ -2990,7 +2992,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
may have different types but same value here. */
if (!OP_SAME (0))
return 0;
- flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF);
+ flags &= ~OEP_ADDRESS_OF;
return ((tree_int_cst_equal (TREE_OPERAND (arg0, 1),
TREE_OPERAND (arg1, 1))
|| OP_SAME (1))
@@ -3003,13 +3005,13 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
if (!OP_SAME_WITH_NULL (0)
|| !OP_SAME (1))
return 0;
- flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF);
+ flags &= ~OEP_ADDRESS_OF;
return OP_SAME_WITH_NULL (2);
case BIT_FIELD_REF:
if (!OP_SAME (0))
return 0;
- flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF);
+ flags &= ~OEP_ADDRESS_OF;
return OP_SAME (1) && OP_SAME (2);
default:
@@ -3021,9 +3023,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
{
case ADDR_EXPR:
/* Be sure we pass right ADDRESS_OF flag. */
- gcc_checking_assert (!(flags
- & (OEP_ADDRESS_OF
- | OEP_CONSTANT_ADDRESS_OF)));
+ gcc_checking_assert (!(flags & OEP_ADDRESS_OF));
return operand_equal_p (TREE_OPERAND (arg0, 0),
TREE_OPERAND (arg1, 0),
flags | OEP_ADDRESS_OF);
@@ -3089,6 +3089,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
return 0;
}
+ /* FIXME: We could skip this test for OEP_MATCH_SIDE_EFFECTS. */
{
unsigned int cef = call_expr_flags (arg0);
if (flags & OEP_PURE_SAME)
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index f2299f2..a976915 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -737,7 +737,7 @@ enum size_type_kind {
enum operand_equal_flag {
OEP_ONLY_CONST = 1,
OEP_PURE_SAME = 2,
- OEP_CONSTANT_ADDRESS_OF = 4,
+ OEP_MATCH_SIDE_EFFECTS = 4,
OEP_ADDRESS_OF = 8
};
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index 3e9718b..7ea092a 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -1081,7 +1081,7 @@ gimple_operand_equal_value_p (tree t1, tree t2)
|| t2 == NULL_TREE)
return false;
- if (operand_equal_p (t1, t2, 0))
+ if (operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS))
return true;
return gvn_uses_equal (t1, t2);