diff options
Diffstat (limited to 'gcc-4.9/gcc/tree-data-ref.c')
-rw-r--r-- | gcc-4.9/gcc/tree-data-ref.c | 58 |
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. */ |