aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/tree-data-ref.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/tree-data-ref.c')
-rw-r--r--gcc-4.9/gcc/tree-data-ref.c58
1 files changed, 48 insertions, 10 deletions
diff --git a/gcc-4.9/gcc/tree-data-ref.c b/gcc-4.9/gcc/tree-data-ref.c
index f279bf391..bd681d70b 100644
--- a/gcc-4.9/gcc/tree-data-ref.c
+++ b/gcc-4.9/gcc/tree-data-ref.c
@@ -663,6 +663,9 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
case SSA_NAME:
{
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0))
+ return false;
+
gimple def_stmt = SSA_NAME_DEF_STMT (op0);
enum tree_code subcode;
@@ -970,6 +973,24 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
fold_convert (ssizetype, memoff));
memoff = build_int_cst (TREE_TYPE (memoff), 0);
}
+ /* Adjust the offset so it is a multiple of the access type
+ size and thus we separate bases that can possibly be used
+ to produce partial overlaps (which the access_fn machinery
+ cannot handle). */
+ double_int rem;
+ if (TYPE_SIZE_UNIT (TREE_TYPE (ref))
+ && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (ref))) == INTEGER_CST
+ && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (ref))))
+ rem = tree_to_double_int (off).mod
+ (tree_to_double_int (TYPE_SIZE_UNIT (TREE_TYPE (ref))), false,
+ TRUNC_MOD_EXPR);
+ else
+ /* If we can't compute the remainder simply force the initial
+ condition to zero. */
+ rem = tree_to_double_int (off);
+ off = double_int_to_tree (ssizetype, tree_to_double_int (off) - rem);
+ memoff = double_int_to_tree (TREE_TYPE (memoff), rem);
+ /* And finally replace the initial condition. */
access_fn = chrec_replace_initial_condition
(access_fn, fold_convert (orig_type, off));
/* ??? This is still not a suitable base object for
@@ -983,7 +1004,6 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
ref = fold_build2_loc (EXPR_LOCATION (ref),
MEM_REF, TREE_TYPE (ref),
base, memoff);
- DR_UNCONSTRAINED_BASE (dr) = true;
MR_DEPENDENCE_CLIQUE (ref) = MR_DEPENDENCE_CLIQUE (old);
MR_DEPENDENCE_BASE (ref) = MR_DEPENDENCE_BASE (old);
access_fns.safe_push (access_fn);
@@ -1398,14 +1418,20 @@ dr_may_alias_p (const struct data_reference *a, const struct data_reference *b,
&& MR_DEPENDENCE_BASE (addr_a) != MR_DEPENDENCE_BASE (addr_b))
return false;
- /* If we had an evolution in a MEM_REF BASE_OBJECT we do not know
- the size of the base-object. So we cannot do any offset/overlap
- based analysis but have to rely on points-to information only. */
+ /* If we had an evolution in a pointer-based MEM_REF BASE_OBJECT we
+ do not know the size of the base-object. So we cannot do any
+ offset/overlap based analysis but have to rely on points-to
+ information only. */
if (TREE_CODE (addr_a) == MEM_REF
- && DR_UNCONSTRAINED_BASE (a))
+ && TREE_CODE (TREE_OPERAND (addr_a, 0)) == SSA_NAME)
{
- if (TREE_CODE (addr_b) == MEM_REF
- && DR_UNCONSTRAINED_BASE (b))
+ /* For true dependences we can apply TBAA. */
+ if (flag_strict_aliasing
+ && DR_IS_WRITE (a) && DR_IS_READ (b)
+ && !alias_sets_conflict_p (get_alias_set (DR_REF (a)),
+ get_alias_set (DR_REF (b))))
+ return false;
+ if (TREE_CODE (addr_b) == MEM_REF)
return ptr_derefs_may_alias_p (TREE_OPERAND (addr_a, 0),
TREE_OPERAND (addr_b, 0));
else
@@ -1413,9 +1439,21 @@ dr_may_alias_p (const struct data_reference *a, const struct data_reference *b,
build_fold_addr_expr (addr_b));
}
else if (TREE_CODE (addr_b) == MEM_REF
- && DR_UNCONSTRAINED_BASE (b))
- return ptr_derefs_may_alias_p (build_fold_addr_expr (addr_a),
- TREE_OPERAND (addr_b, 0));
+ && TREE_CODE (TREE_OPERAND (addr_b, 0)) == SSA_NAME)
+ {
+ /* For true dependences we can apply TBAA. */
+ if (flag_strict_aliasing
+ && DR_IS_WRITE (a) && DR_IS_READ (b)
+ && !alias_sets_conflict_p (get_alias_set (DR_REF (a)),
+ get_alias_set (DR_REF (b))))
+ return false;
+ if (TREE_CODE (addr_a) == MEM_REF)
+ return ptr_derefs_may_alias_p (TREE_OPERAND (addr_a, 0),
+ TREE_OPERAND (addr_b, 0));
+ else
+ return ptr_derefs_may_alias_p (build_fold_addr_expr (addr_a),
+ TREE_OPERAND (addr_b, 0));
+ }
/* Otherwise DR_BASE_OBJECT is an access that covers the whole object
that is being subsetted in the loop nest. */