diff options
author | Cong Hou <congh@google.com> | 2013-11-14 15:59:47 -0500 |
---|---|---|
committer | Cong Hou <congh@gcc.gnu.org> | 2013-11-14 15:59:47 -0500 |
commit | 93bdc3edf1f077a3af43ef2e2a8114b2ad3f933d (patch) | |
tree | 5b4788fbe5d619ba4dd0343e1e3048b6b0ca4fd3 /gcc/tree-vect-data-refs.c | |
parent | 5e94175fa5906a1417a229fe9ec93faa10502583 (diff) | |
download | gcc-93bdc3edf1f077a3af43ef2e2a8114b2ad3f933d.tar.gz |
tree-vectorizer.h (struct dr_with_seg_len): Remove the base address field as it can be obtained from dr.
2013-11-14 Cong Hou <congh@google.com>
* tree-vectorizer.h (struct dr_with_seg_len): Remove the base
address field as it can be obtained from dr. Rename the struct.
* tree-vect-data-refs.c (comp_dr_with_seg_len_pair): Consider
steps of data references during sort.
(vect_prune_runtime_alias_test_list): Adjust with the change to
struct dr_with_seg_len.
* tree-vect-loop-manip.c (vect_create_cond_for_alias_checks):
Adjust with the change to struct dr_with_seg_len.
2013-11-14 Cong Hou <congh@google.com>
* gcc.dg/vect/vect-alias-check.c: Update.
From-SVN: r204822
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r-- | gcc/tree-vect-data-refs.c | 126 |
1 files changed, 55 insertions, 71 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 1e5ee3dd07b..2d0c3dc9e2d 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -2623,7 +2623,7 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) } -/* Operator == between two dr_addr_with_seg_len objects. +/* Operator == between two dr_with_seg_len objects. This equality operator is used to make sure two data refs are the same one so that we will consider to combine the @@ -2631,62 +2631,51 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) refs. */ static bool -operator == (const dr_addr_with_seg_len& d1, - const dr_addr_with_seg_len& d2) +operator == (const dr_with_seg_len& d1, + const dr_with_seg_len& d2) { - return operand_equal_p (d1.basic_addr, d2.basic_addr, 0) - && compare_tree (d1.offset, d2.offset) == 0 - && compare_tree (d1.seg_len, d2.seg_len) == 0; + return operand_equal_p (DR_BASE_ADDRESS (d1.dr), + DR_BASE_ADDRESS (d2.dr), 0) + && compare_tree (d1.offset, d2.offset) == 0 + && compare_tree (d1.seg_len, d2.seg_len) == 0; } -/* Function comp_dr_addr_with_seg_len_pair. +/* Function comp_dr_with_seg_len_pair. - Comparison function for sorting objects of dr_addr_with_seg_len_pair_t + Comparison function for sorting objects of dr_with_seg_len_pair_t so that we can combine aliasing checks in one scan. */ static int -comp_dr_addr_with_seg_len_pair (const void *p1_, const void *p2_) +comp_dr_with_seg_len_pair (const void *p1_, const void *p2_) { - const dr_addr_with_seg_len_pair_t* p1 = - (const dr_addr_with_seg_len_pair_t *) p1_; - const dr_addr_with_seg_len_pair_t* p2 = - (const dr_addr_with_seg_len_pair_t *) p2_; - - const dr_addr_with_seg_len &p11 = p1->first, - &p12 = p1->second, - &p21 = p2->first, - &p22 = p2->second; - - int comp_res = compare_tree (p11.basic_addr, p21.basic_addr); - if (comp_res != 0) + const dr_with_seg_len_pair_t* p1 = (const dr_with_seg_len_pair_t *) p1_; + const dr_with_seg_len_pair_t* p2 = (const dr_with_seg_len_pair_t *) p2_; + + const dr_with_seg_len &p11 = p1->first, + &p12 = p1->second, + &p21 = p2->first, + &p22 = p2->second; + + /* For DR pairs (a, b) and (c, d), we only consider to merge the alias checks + if a and c have the same basic address snd step, and b and d have the same + address and step. Therefore, if any a&c or b&d don't have the same address + and step, we don't care the order of those two pairs after sorting. */ + int comp_res; + + if ((comp_res = compare_tree (DR_BASE_ADDRESS (p11.dr), + DR_BASE_ADDRESS (p21.dr))) != 0) return comp_res; - - comp_res = compare_tree (p12.basic_addr, p22.basic_addr); - if (comp_res != 0) + if ((comp_res = compare_tree (DR_BASE_ADDRESS (p12.dr), + DR_BASE_ADDRESS (p22.dr))) != 0) + return comp_res; + if ((comp_res = compare_tree (DR_STEP (p11.dr), DR_STEP (p21.dr))) != 0) + return comp_res; + if ((comp_res = compare_tree (DR_STEP (p12.dr), DR_STEP (p22.dr))) != 0) + return comp_res; + if ((comp_res = compare_tree (p11.offset, p21.offset)) != 0) + return comp_res; + if ((comp_res = compare_tree (p12.offset, p22.offset)) != 0) return comp_res; - - if (TREE_CODE (p11.offset) != INTEGER_CST - || TREE_CODE (p21.offset) != INTEGER_CST) - { - comp_res = compare_tree (p11.offset, p21.offset); - if (comp_res != 0) - return comp_res; - } - else if (tree_int_cst_compare (p11.offset, p21.offset) < 0) - return -1; - else if (tree_int_cst_compare (p11.offset, p21.offset) > 0) - return 1; - if (TREE_CODE (p12.offset) != INTEGER_CST - || TREE_CODE (p22.offset) != INTEGER_CST) - { - comp_res = compare_tree (p12.offset, p22.offset); - if (comp_res != 0) - return comp_res; - } - else if (tree_int_cst_compare (p12.offset, p22.offset) < 0) - return -1; - else if (tree_int_cst_compare (p12.offset, p22.offset) > 0) - return 1; return 0; } @@ -2721,11 +2710,11 @@ vect_vfa_segment_size (struct data_reference *dr, tree length_factor) segment_length = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr))); else segment_length = size_binop (MULT_EXPR, - fold_convert (sizetype, DR_STEP (dr)), - fold_convert (sizetype, length_factor)); + fold_convert (sizetype, DR_STEP (dr)), + fold_convert (sizetype, length_factor)); if (vect_supportable_dr_alignment (dr, false) - == dr_explicit_realign_optimized) + == dr_explicit_realign_optimized) { tree vector_size = TYPE_SIZE_UNIT (STMT_VINFO_VECTYPE (vinfo_for_stmt (DR_STMT (dr)))); @@ -2747,7 +2736,7 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo) { vec<ddr_p> may_alias_ddrs = LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo); - vec<dr_addr_with_seg_len_pair_t>& comp_alias_ddrs = + vec<dr_with_seg_len_pair_t>& comp_alias_ddrs = LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo); int vect_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo); tree scalar_loop_iters = LOOP_VINFO_NITERS (loop_vinfo); @@ -2826,18 +2815,11 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo) segment_length_a = vect_vfa_segment_size (dr_a, length_factor); segment_length_b = vect_vfa_segment_size (dr_b, length_factor); - dr_addr_with_seg_len_pair_t dr_with_seg_len_pair - (dr_addr_with_seg_len - (dr_a, DR_BASE_ADDRESS (dr_a), - size_binop (PLUS_EXPR, DR_OFFSET (dr_a), DR_INIT (dr_a)), - segment_length_a), - dr_addr_with_seg_len - (dr_b, DR_BASE_ADDRESS (dr_b), - size_binop (PLUS_EXPR, DR_OFFSET (dr_b), DR_INIT (dr_b)), - segment_length_b)); - - if (compare_tree (dr_with_seg_len_pair.first.basic_addr, - dr_with_seg_len_pair.second.basic_addr) > 0) + dr_with_seg_len_pair_t dr_with_seg_len_pair + (dr_with_seg_len (dr_a, segment_length_a), + dr_with_seg_len (dr_b, segment_length_b)); + + if (compare_tree (DR_BASE_ADDRESS (dr_a), DR_BASE_ADDRESS (dr_b)) > 0) swap (dr_with_seg_len_pair.first, dr_with_seg_len_pair.second); comp_alias_ddrs.safe_push (dr_with_seg_len_pair); @@ -2845,17 +2827,17 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo) /* Second, we sort the collected data ref pairs so that we can scan them once to combine all possible aliasing checks. */ - comp_alias_ddrs.qsort (comp_dr_addr_with_seg_len_pair); + comp_alias_ddrs.qsort (comp_dr_with_seg_len_pair); /* Third, we scan the sorted dr pairs and check if we can combine alias checks of two neighbouring dr pairs. */ for (size_t i = 1; i < comp_alias_ddrs.length (); ++i) { /* Deal with two ddrs (dr_a1, dr_b1) and (dr_a2, dr_b2). */ - dr_addr_with_seg_len *dr_a1 = &comp_alias_ddrs[i-1].first, - *dr_b1 = &comp_alias_ddrs[i-1].second, - *dr_a2 = &comp_alias_ddrs[i].first, - *dr_b2 = &comp_alias_ddrs[i].second; + dr_with_seg_len *dr_a1 = &comp_alias_ddrs[i-1].first, + *dr_b1 = &comp_alias_ddrs[i-1].second, + *dr_a2 = &comp_alias_ddrs[i].first, + *dr_b2 = &comp_alias_ddrs[i].second; /* Remove duplicate data ref pairs. */ if (*dr_a1 == *dr_a2 && *dr_b1 == *dr_b2) @@ -2892,7 +2874,9 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo) swap (dr_a2, dr_b2); } - if (!operand_equal_p (dr_a1->basic_addr, dr_a2->basic_addr, 0) + if (!operand_equal_p (DR_BASE_ADDRESS (dr_a1->dr), + DR_BASE_ADDRESS (dr_a2->dr), + 0) || !host_integerp (dr_a1->offset, 0) || !host_integerp (dr_a2->offset, 0)) continue; @@ -2919,8 +2903,8 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo) HOST_WIDE_INT min_seg_len_b = (TREE_CODE (dr_b1->seg_len) == INTEGER_CST) ? - TREE_INT_CST_LOW (dr_b1->seg_len) : - vect_factor; + TREE_INT_CST_LOW (dr_b1->seg_len) : + vect_factor; if (diff <= min_seg_len_b || (TREE_CODE (dr_a1->seg_len) == INTEGER_CST |