re PR tree-optimization/66142 (Loop is not vectorized because not sufficient support for GOMP_SIMD_LANE)

2015-09-18  Richard Biener  <rguenther@suse.de>

	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.

From-SVN: r227896
This commit is contained in:
Richard Biener 2015-09-18 07:57:00 +00:00 committed by Richard Biener
parent 9ace6a8733
commit a0f79fcc43
5 changed files with 74 additions and 22 deletions

View File

@ -1,3 +1,21 @@
2015-09-18 Richard Biener <rguenther@suse.de>
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 <christian.bruel@st.com>
* config/arm/arm.md (*call_value_symbol): Fix operand for interworking.

View File

@ -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. */

View File

@ -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;
}

View File

@ -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<vn_reference_op_s> *ops,
unsigned int *i_p)
{
@ -1210,12 +1210,14 @@ vn_reference_fold_indirect (vec<vn_reference_op_s> *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<vn_reference_op_s> *ops,
unsigned int *i_p)
{
@ -1228,12 +1230,12 @@ vn_reference_maybe_forwprop_address (vec<vn_reference_op_s> *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<vn_reference_op_s> *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<vn_reference_op_s> *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<vn_reference_op_s> *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<vn_reference_op_s> 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<vn_reference_op_s> 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

View File

@ -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<vn_reference_op_s> *,
unsigned int *);
bool ao_ref_init_from_vn_reference (ao_ref *, alias_set_type, tree,
vec<vn_reference_op_s> );
tree vn_reference_lookup_pieces (tree, alias_set_type, tree,