From 11beb29cdf62c021907f686e269adb45ba282396 Mon Sep 17 00:00:00 2001 From: rguenth Date: Fri, 18 Sep 2015 07:57:00 +0000 Subject: [PATCH] 2015-09-18 Richard Biener PR tree-optimization/66142 * fold-const.c (operand_equal_p): When OEP_ADDRESS_OF treat MEM[&x] and x the same. * tree-ssa-sccvn.h (vn_reference_fold_indirect): Remove. * tree-ssa-sccvn.c (vn_reference_fold_indirect): Return true when we simplified sth. (vn_reference_maybe_forwprop_address): Likewise. (valueize_refs_1): When we simplified through vn_reference_fold_indirect or vn_reference_maybe_forwprop_address set valueized_anything to true. (vn_reference_lookup_3): Use stmt_kills_ref_p to see whether one ref kills the other instead of just a offset-based test. * tree-ssa-alias.c (stmt_kills_ref_p): Use OEP_ADDRESS_OF for the operand_equal_p test to compare bases and also compare sizes. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@227896 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 18 ++++++++++++++++++ gcc/fold-const.c | 29 ++++++++++++++++++++++++++--- gcc/tree-ssa-alias.c | 13 ++++++++++--- gcc/tree-ssa-sccvn.c | 34 ++++++++++++++++++++-------------- gcc/tree-ssa-sccvn.h | 2 -- 5 files changed, 74 insertions(+), 22 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0faf86b..3ee1a2d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2015-09-18 Richard Biener + + PR tree-optimization/66142 + * fold-const.c (operand_equal_p): When OEP_ADDRESS_OF + treat MEM[&x] and x the same. + * tree-ssa-sccvn.h (vn_reference_fold_indirect): Remove. + * tree-ssa-sccvn.c (vn_reference_fold_indirect): Return true + when we simplified sth. + (vn_reference_maybe_forwprop_address): Likewise. + (valueize_refs_1): When we simplified through + vn_reference_fold_indirect or vn_reference_maybe_forwprop_address + set valueized_anything to true. + (vn_reference_lookup_3): Use stmt_kills_ref_p to see whether + one ref kills the other instead of just a offset-based test. + * tree-ssa-alias.c (stmt_kills_ref_p): Use OEP_ADDRESS_OF + for the operand_equal_p test to compare bases and also compare + sizes. + 2015-09-17 Christian Bruel * config/arm/arm.md (*call_value_symbol): Fix operand for interworking. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index a27ef22..ce2c469 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2752,10 +2752,33 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) TREE_OPERAND (arg1, 0), flags); } - if (TREE_CODE (arg0) != TREE_CODE (arg1) + if (TREE_CODE (arg0) != TREE_CODE (arg1)) + { /* NOP_EXPR and CONVERT_EXPR are considered equal. */ - && !(CONVERT_EXPR_P (arg0) && CONVERT_EXPR_P (arg1))) - return 0; + if (CONVERT_EXPR_P (arg0) && CONVERT_EXPR_P (arg1)) + ; + else if (flags & OEP_ADDRESS_OF) + { + /* If we are interested in comparing addresses ignore + MEM_REF wrappings of the base that can appear just for + TBAA reasons. */ + if (TREE_CODE (arg0) == MEM_REF + && DECL_P (arg1) + && TREE_CODE (TREE_OPERAND (arg0, 0)) == ADDR_EXPR + && TREE_OPERAND (TREE_OPERAND (arg0, 0), 0) == arg1 + && integer_zerop (TREE_OPERAND (arg0, 1))) + return 1; + else if (TREE_CODE (arg1) == MEM_REF + && DECL_P (arg0) + && TREE_CODE (TREE_OPERAND (arg1, 0)) == ADDR_EXPR + && TREE_OPERAND (TREE_OPERAND (arg1, 0), 0) == arg0 + && integer_zerop (TREE_OPERAND (arg1, 1))) + return 1; + return 0; + } + else + return 0; + } /* This is needed for conversions and for COMPONENT_REF. Might as well play it safe and always test this. */ diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 0445052..bc4b525 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -2282,9 +2282,16 @@ stmt_kills_ref_p (gimple stmt, ao_ref *ref) if (saved_lhs0) TREE_OPERAND (lhs, 0) = saved_lhs0; } - /* Finally check if lhs is equal or equal to the base candidate - of the access. */ - if (operand_equal_p (lhs, base, 0)) + /* Finally check if the lhs has the same address and size as the + base candidate of the access. */ + if (lhs == base + || (((TYPE_SIZE (TREE_TYPE (lhs)) + == TYPE_SIZE (TREE_TYPE (base))) + || (TYPE_SIZE (TREE_TYPE (lhs)) + && TYPE_SIZE (TREE_TYPE (base)) + && operand_equal_p (TYPE_SIZE (TREE_TYPE (lhs)), + TYPE_SIZE (TREE_TYPE (base)), 0))) + && operand_equal_p (lhs, base, OEP_ADDRESS_OF))) return true; } diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index f7904e2..ef477e1 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -1184,7 +1184,7 @@ copy_reference_ops_from_call (gcall *call, /* Fold *& at position *I_P in a vn_reference_op_s vector *OPS. Updates *I_P to point to the last element of the replacement. */ -void +static bool vn_reference_fold_indirect (vec *ops, unsigned int *i_p) { @@ -1210,12 +1210,14 @@ vn_reference_fold_indirect (vec *ops, mem_op->off = tree_to_shwi (mem_op->op0); else mem_op->off = -1; + return true; } + return false; } /* Fold *& at position *I_P in a vn_reference_op_s vector *OPS. Updates *I_P to point to the last element of the replacement. */ -static void +static bool vn_reference_maybe_forwprop_address (vec *ops, unsigned int *i_p) { @@ -1228,12 +1230,12 @@ vn_reference_maybe_forwprop_address (vec *ops, def_stmt = SSA_NAME_DEF_STMT (op->op0); if (!is_gimple_assign (def_stmt)) - return; + return false; code = gimple_assign_rhs_code (def_stmt); if (code != ADDR_EXPR && code != POINTER_PLUS_EXPR) - return; + return false; off = offset_int::from (mem_op->op0, SIGNED); @@ -1265,11 +1267,11 @@ vn_reference_maybe_forwprop_address (vec *ops, ops->pop (); ops->safe_splice (tem); --*i_p; - return; + return true; } if (!addr_base || TREE_CODE (addr_base) != MEM_REF) - return; + return false; off += addr_offset; off += mem_ref_offset (addr_base); @@ -1282,7 +1284,7 @@ vn_reference_maybe_forwprop_address (vec *ops, ptroff = gimple_assign_rhs2 (def_stmt); if (TREE_CODE (ptr) != SSA_NAME || TREE_CODE (ptroff) != INTEGER_CST) - return; + return false; off += wi::to_offset (ptroff); op->op0 = ptr; @@ -1303,6 +1305,7 @@ vn_reference_maybe_forwprop_address (vec *ops, vn_reference_maybe_forwprop_address (ops, i_p); else if (TREE_CODE (op->op0) == ADDR_EXPR) vn_reference_fold_indirect (ops, i_p); + return true; } /* Optimize the reference REF to a constant if possible or return @@ -1475,11 +1478,17 @@ valueize_refs_1 (vec orig, bool *valueized_anything) && vro->op0 && TREE_CODE (vro->op0) == ADDR_EXPR && orig[i - 1].opcode == MEM_REF) - vn_reference_fold_indirect (&orig, &i); + { + if (vn_reference_fold_indirect (&orig, &i)) + *valueized_anything = true; + } else if (i > 0 && vro->opcode == SSA_NAME && orig[i - 1].opcode == MEM_REF) - vn_reference_maybe_forwprop_address (&orig, &i); + { + if (vn_reference_maybe_forwprop_address (&orig, &i)) + *valueized_anything = true; + } /* If it transforms a non-constant ARRAY_REF into a constant one, adjust the constant offset. */ else if (vro->opcode == ARRAY_REF @@ -1880,7 +1889,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, || handled_component_p (gimple_assign_rhs1 (def_stmt)))) { tree base2; - HOST_WIDE_INT offset2, size2, maxsize2; + HOST_WIDE_INT maxsize2; int i, j; auto_vec rhs; vn_reference_op_t vro; @@ -1891,8 +1900,6 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, /* See if the assignment kills REF. */ base2 = ao_ref_base (&lhs_ref); - offset2 = lhs_ref.offset; - size2 = lhs_ref.size; maxsize2 = lhs_ref.max_size; if (maxsize2 == -1 || (base != base2 @@ -1901,8 +1908,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, || TREE_OPERAND (base, 0) != TREE_OPERAND (base2, 0) || !tree_int_cst_equal (TREE_OPERAND (base, 1), TREE_OPERAND (base2, 1)))) - || offset2 > offset - || offset2 + size2 < offset + maxsize) + || !stmt_kills_ref_p (def_stmt, ref)) return (void *)-1; /* Find the common base of ref and the lhs. lhs_ops already diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h index 41d14af..704663d 100644 --- a/gcc/tree-ssa-sccvn.h +++ b/gcc/tree-ssa-sccvn.h @@ -204,8 +204,6 @@ vn_nary_op_t vn_nary_op_insert (tree, tree); vn_nary_op_t vn_nary_op_insert_stmt (gimple, tree); vn_nary_op_t vn_nary_op_insert_pieces (unsigned int, enum tree_code, tree, tree *, tree, unsigned int); -void vn_reference_fold_indirect (vec *, - unsigned int *); bool ao_ref_init_from_vn_reference (ao_ref *, alias_set_type, tree, vec ); tree vn_reference_lookup_pieces (tree, alias_set_type, tree, -- 2.7.4