*** tree-data-ref.c.orig Wed Feb 9 12:16:36 2005 --- tree-data-ref.c Wed Feb 9 12:28:54 2005 *************** array_base_name_differ_p (struct data_re *** 109,117 **** { tree base_a = DR_BASE_NAME (a); tree base_b = DR_BASE_NAME (b); ! tree ta = TREE_TYPE (base_a); ! tree tb = TREE_TYPE (base_b); /* Determine if same base. Example: for the array accesses a[i], b[i] or pointer accesses *a, *b, bases are a, b. */ --- 109,123 ---- { tree base_a = DR_BASE_NAME (a); tree base_b = DR_BASE_NAME (b); ! tree ta, tb; + if (!base_a || !base_b) + return false; + + ta = TREE_TYPE (base_a); + tb = TREE_TYPE (base_b); + + gcc_assert (!POINTER_TYPE_P (ta) && !POINTER_TYPE_P (tb)); /* Determine if same base. Example: for the array accesses a[i], b[i] or pointer accesses *a, *b, bases are a, b. */ *************** array_base_name_differ_p (struct data_re *** 174,197 **** || (TREE_CODE (base_b) == VAR_DECL && (TREE_CODE (base_a) == COMPONENT_REF && TREE_CODE (TREE_OPERAND (base_a, 0)) == VAR_DECL))) - { - *differ_p = true; - return true; - } - - if (!alias_sets_conflict_p (get_alias_set (base_a), get_alias_set (base_b))) - { - *differ_p = true; - return true; - } - - /* An instruction writing through a restricted pointer is - "independent" of any instruction reading or writing through a - different pointer, in the same block/scope. */ - if ((TREE_CODE (ta) == POINTER_TYPE && TYPE_RESTRICT (ta) - && !DR_IS_READ(a)) - || (TREE_CODE (tb) == POINTER_TYPE && TYPE_RESTRICT (tb) - && !DR_IS_READ(b))) { *differ_p = true; return true; --- 180,185 ---- *** tree-vectorizer.c.patch1 Wed Feb 9 11:18:38 2005 --- tree-vectorizer.c Wed Feb 9 12:52:12 2005 *************** static bool vect_compute_data_ref_alignm *** 223,241 **** static bool vect_analyze_data_ref_access (struct data_reference *); static bool vect_can_force_dr_alignment_p (tree, unsigned int); static struct data_reference * vect_analyze_pointer_ref_access ! (tree, tree, bool); static bool vect_can_advance_ivs_p (loop_vec_info); static tree vect_get_base_and_offset (struct data_reference *, tree, tree, loop_vec_info, tree *, tree *, tree *, bool*); - static struct data_reference * vect_analyze_pointer_ref_access - (tree, tree, bool); static tree vect_get_ptr_offset (tree, tree, tree *); static tree vect_get_memtag_and_dr (tree, tree, bool, loop_vec_info, tree, struct data_reference **); static bool vect_analyze_offset_expr (tree, struct loop *, tree, tree *, tree *, tree *); static tree vect_strip_conversion (tree); /* Utility functions for the code transformation. */ static tree vect_create_destination_var (tree, tree); --- 223,242 ---- static bool vect_analyze_data_ref_access (struct data_reference *); static bool vect_can_force_dr_alignment_p (tree, unsigned int); static struct data_reference * vect_analyze_pointer_ref_access ! (tree, tree, bool, tree*); static bool vect_can_advance_ivs_p (loop_vec_info); static tree vect_get_base_and_offset (struct data_reference *, tree, tree, loop_vec_info, tree *, tree *, tree *, bool*); static tree vect_get_ptr_offset (tree, tree, tree *); static tree vect_get_memtag_and_dr (tree, tree, bool, loop_vec_info, tree, struct data_reference **); static bool vect_analyze_offset_expr (tree, struct loop *, tree, tree *, tree *, tree *); static tree vect_strip_conversion (tree); + static bool vect_base_addr_differ_p (struct data_reference *, + struct data_reference *drb, bool *); + /* Utility functions for the code transformation. */ static tree vect_create_destination_var (tree, tree); *************** vect_create_addr_base_for_vector_ref (tr *** 1960,1966 **** struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); tree data_ref_base = unshare_expr (STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info)); ! tree base_name = unshare_expr (DR_BASE_NAME (dr)); tree ref = DR_REF (dr); tree scalar_type = TREE_TYPE (ref); tree scalar_ptr_type = build_pointer_type (scalar_type); --- 1961,1967 ---- struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); tree data_ref_base = unshare_expr (STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info)); ! tree base_name = build_fold_indirect_ref (data_ref_base); tree ref = DR_REF (dr); tree scalar_type = TREE_TYPE (ref); tree scalar_ptr_type = build_pointer_type (scalar_type); *************** vect_create_data_ref_ptr (tree stmt, blo *** 2130,2136 **** { tree base_name; stmt_vec_info stmt_info = vinfo_for_stmt (stmt); - struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); tree vectype = STMT_VINFO_VECTYPE (stmt_info); --- 2131,2136 ---- *************** vect_create_data_ref_ptr (tree stmt, blo *** 2154,2160 **** tree data_ref_ptr; tree type, tmp, size; ! base_name = unshare_expr (DR_BASE_NAME (dr)); if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC)) { tree data_ref_base = base_name; --- 2154,2162 ---- tree data_ref_ptr; tree type, tmp, size; ! base_name = build_fold_indirect_ref (unshare_expr ( ! STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info))); ! if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC)) { tree data_ref_base = base_name; *************** vect_analyze_scalar_cycles (loop_vec_inf *** 4087,4092 **** --- 4089,4149 ---- } + /* Function vect_base_addr_differ_p. + + This is the simplest data dependence test: determines whether the + data references A and B access the same array/region. Returns + false when the property is not computable at compile time. + Otherwise return true, and DIFFER_P will record the result. This + utility will not be necessary when alias_sets_conflict_p will be + less conservative. */ + + + static bool + vect_base_addr_differ_p (struct data_reference *dra, + struct data_reference *drb, + bool *differ_p) + { + tree stmt_a = DR_STMT (dra); + stmt_vec_info stmt_info_a = vinfo_for_stmt (stmt_a); + tree stmt_b = DR_STMT (drb); + stmt_vec_info stmt_info_b = vinfo_for_stmt (stmt_b); + tree addr_a = STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info_a); + tree addr_b = STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info_b); + tree type_a = TREE_TYPE (addr_a); + tree type_b = TREE_TYPE (addr_b); + HOST_WIDE_INT alias_set_a, alias_set_b; + + gcc_assert (POINTER_TYPE_P (type_a) && POINTER_TYPE_P (type_b)); + + /* Both references are ADDR_EXPR, i.e., we have the objects. */ + if (TREE_CODE (addr_a) == ADDR_EXPR && TREE_CODE (addr_b) == ADDR_EXPR) + return array_base_name_differ_p (dra, drb, differ_p); + + alias_set_a = (TREE_CODE (addr_a) == ADDR_EXPR) ? + get_alias_set (TREE_OPERAND (addr_a, 0)) : get_alias_set (addr_a); + alias_set_b = (TREE_CODE (addr_b) == ADDR_EXPR) ? + get_alias_set (TREE_OPERAND (addr_b, 0)) : get_alias_set (addr_b); + + if (!alias_sets_conflict_p (alias_set_a, alias_set_b)) + { + *differ_p = true; + return true; + } + + /* An instruction writing through a restricted pointer is "independent" of any + instruction reading or writing through a different pointer, in the same + block/scope. */ + else if ((TYPE_RESTRICT (type_a) && !DR_IS_READ (dra)) + || (TYPE_RESTRICT (type_b) && !DR_IS_READ (drb))) + { + *differ_p = true; + return true; + } + return false; + } + + /* Function vect_analyze_data_ref_dependence. Return TRUE if there (might) exist a dependence between a memory-reference *************** vect_analyze_data_ref_dependence (struct *** 4100,4106 **** bool differ_p; struct data_dependence_relation *ddr; ! if (!array_base_name_differ_p (dra, drb, &differ_p)) { if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS, LOOP_LOC (loop_vinfo))) --- 4157,4163 ---- bool differ_p; struct data_dependence_relation *ddr; ! if (!vect_base_addr_differ_p (dra, drb, &differ_p)) { if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS, LOOP_LOC (loop_vinfo))) *************** vect_analyze_data_ref_accesses (loop_vec *** 4658,4664 **** that represents it (DR). Otherwise - return NULL. */ static struct data_reference * ! vect_analyze_pointer_ref_access (tree memref, tree stmt, bool is_read) { stmt_vec_info stmt_info = vinfo_for_stmt (stmt); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); --- 4715,4722 ---- that represents it (DR). Otherwise - return NULL. */ static struct data_reference * ! vect_analyze_pointer_ref_access (tree memref, tree stmt, bool is_read, ! tree *ptr_init) { stmt_vec_info stmt_info = vinfo_for_stmt (stmt); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); *************** vect_analyze_pointer_ref_access (tree me *** 4756,4762 **** fprintf (vect_dump, "Access function of ptr indx: "); print_generic_expr (vect_dump, indx_access_fn, TDF_SLIM); } ! dr = init_data_ref (stmt, memref, init, indx_access_fn, is_read); return dr; } --- 4814,4821 ---- fprintf (vect_dump, "Access function of ptr indx: "); print_generic_expr (vect_dump, indx_access_fn, TDF_SLIM); } ! dr = init_data_ref (stmt, memref, NULL_TREE, indx_access_fn, is_read); ! *ptr_init = init; return dr; } *************** vect_get_memtag_and_dr (tree memref, tre *** 4804,4809 **** --- 4863,4869 ---- tree ref_to_be_analyzed, tag, dr_base; struct data_reference *new_dr; bool base_aligned_p; + tree ptr_init; if (*dr) { *************** vect_get_memtag_and_dr (tree memref, tre *** 4887,4898 **** switch (TREE_CODE (memref)) { case INDIRECT_REF: ! new_dr = vect_analyze_pointer_ref_access (memref, stmt, is_read); if (!new_dr) return NULL_TREE; *dr = new_dr; ! symbl = DR_BASE_NAME (new_dr); ! ref_to_be_analyzed = DR_BASE_NAME (new_dr); break; case ARRAY_REF: --- 4947,4959 ---- switch (TREE_CODE (memref)) { case INDIRECT_REF: ! new_dr = vect_analyze_pointer_ref_access (memref, stmt, is_read, ! &ptr_init); if (!new_dr) return NULL_TREE; *dr = new_dr; ! symbl = ptr_init; ! ref_to_be_analyzed = ptr_init; break; case ARRAY_REF: