Commit 93bdc3ed by Cong Hou Committed by Cong Hou

tree-vectorizer.h (struct dr_with_seg_len): Remove the base address field as it…

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
parent 5e94175f
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 Jeff Law <law@redhat.com> 2013-11-14 Jeff Law <law@redhat.com>
PR middle-end/59127 PR middle-end/59127
2013-11-14 Cong Hou <congh@google.com>
* gcc.dg/vect/vect-alias-check.c: Update.
2013-11-14 Paolo Carlini <paolo.carlini@oracle.com> 2013-11-14 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/57887 PR c++/57887
......
/* { dg-require-effective-target vect_int } */ /* { dg-require-effective-target vect_int } */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -ftree-vectorize --param=vect-max-version-for-alias-checks=2 -fdump-tree-vect-details" } */ /* { dg-additional-options "--param=vect-max-version-for-alias-checks=2" } */
/* A test case showing three potential alias checks between /* A test case showing four potential alias checks between a[i] and b[0], b[1],
a[i] and b[i], b[i+7], b[i+14]. With alias checks merging b[i+1] and b[i+2]. With alias check merging enabled, those four checks
enabled, those tree checks can be merged into one, and the can be merged into two, and the loop will be vectorized with
loop will be vectorized with vect-max-version-for-alias-checks=2. */ vect-max-version-for-alias-checks=2. */
void foo (int *a, int *b) void foo (int *a, int *b)
{ {
int i; int i;
for (i = 0; i < 1000; ++i) for (i = 0; i < 1000; ++i)
a[i] = b[i] + b[i+7] + b[i+14]; a[i] = b[0] + b[1] + b[i+1] + b[i+2];
} }
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
......
...@@ -2623,7 +2623,7 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) ...@@ -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 This equality operator is used to make sure two data refs
are the same one so that we will consider to combine the 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) ...@@ -2631,62 +2631,51 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
refs. */ refs. */
static bool static bool
operator == (const dr_addr_with_seg_len& d1, operator == (const dr_with_seg_len& d1,
const dr_addr_with_seg_len& d2) const dr_with_seg_len& d2)
{ {
return operand_equal_p (d1.basic_addr, d2.basic_addr, 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.offset, d2.offset) == 0
&& compare_tree (d1.seg_len, d2.seg_len) == 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. */ so that we can combine aliasing checks in one scan. */
static int 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_with_seg_len_pair_t* p1 = (const dr_with_seg_len_pair_t *) p1_;
(const dr_addr_with_seg_len_pair_t *) p1_; const dr_with_seg_len_pair_t* p2 = (const dr_with_seg_len_pair_t *) p2_;
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, const dr_with_seg_len &p11 = p1->first,
&p12 = p1->second, &p12 = p1->second,
&p21 = p2->first, &p21 = p2->first,
&p22 = p2->second; &p22 = p2->second;
int comp_res = compare_tree (p11.basic_addr, p21.basic_addr); /* For DR pairs (a, b) and (c, d), we only consider to merge the alias checks
if (comp_res != 0) if a and c have the same basic address snd step, and b and d have the same
return comp_res; 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;
comp_res = compare_tree (p12.basic_addr, p22.basic_addr); if ((comp_res = compare_tree (DR_BASE_ADDRESS (p11.dr),
if (comp_res != 0) DR_BASE_ADDRESS (p21.dr))) != 0)
return comp_res; return comp_res;
if ((comp_res = compare_tree (DR_BASE_ADDRESS (p12.dr),
if (TREE_CODE (p11.offset) != INTEGER_CST DR_BASE_ADDRESS (p22.dr))) != 0)
|| TREE_CODE (p21.offset) != INTEGER_CST)
{
comp_res = compare_tree (p11.offset, p21.offset);
if (comp_res != 0)
return comp_res; return comp_res;
} if ((comp_res = compare_tree (DR_STEP (p11.dr), DR_STEP (p21.dr))) != 0)
else if (tree_int_cst_compare (p11.offset, p21.offset) < 0) return comp_res;
return -1; if ((comp_res = compare_tree (DR_STEP (p12.dr), DR_STEP (p22.dr))) != 0)
else if (tree_int_cst_compare (p11.offset, p21.offset) > 0) return comp_res;
return 1; if ((comp_res = compare_tree (p11.offset, p21.offset)) != 0)
if (TREE_CODE (p12.offset) != INTEGER_CST return comp_res;
|| TREE_CODE (p22.offset) != INTEGER_CST) if ((comp_res = compare_tree (p12.offset, p22.offset)) != 0)
{
comp_res = compare_tree (p12.offset, p22.offset);
if (comp_res != 0)
return comp_res; 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; return 0;
} }
...@@ -2747,7 +2736,7 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo) ...@@ -2747,7 +2736,7 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
{ {
vec<ddr_p> may_alias_ddrs = vec<ddr_p> may_alias_ddrs =
LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo); 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); LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo);
int vect_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo); int vect_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
tree scalar_loop_iters = LOOP_VINFO_NITERS (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) ...@@ -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_a = vect_vfa_segment_size (dr_a, length_factor);
segment_length_b = vect_vfa_segment_size (dr_b, 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_with_seg_len_pair_t dr_with_seg_len_pair
(dr_addr_with_seg_len (dr_with_seg_len (dr_a, segment_length_a),
(dr_a, DR_BASE_ADDRESS (dr_a), dr_with_seg_len (dr_b, segment_length_b));
size_binop (PLUS_EXPR, DR_OFFSET (dr_a), DR_INIT (dr_a)),
segment_length_a), if (compare_tree (DR_BASE_ADDRESS (dr_a), DR_BASE_ADDRESS (dr_b)) > 0)
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)
swap (dr_with_seg_len_pair.first, dr_with_seg_len_pair.second); swap (dr_with_seg_len_pair.first, dr_with_seg_len_pair.second);
comp_alias_ddrs.safe_push (dr_with_seg_len_pair); comp_alias_ddrs.safe_push (dr_with_seg_len_pair);
...@@ -2845,14 +2827,14 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo) ...@@ -2845,14 +2827,14 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
/* Second, we sort the collected data ref pairs so that we can scan /* Second, we sort the collected data ref pairs so that we can scan
them once to combine all possible aliasing checks. */ 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 /* Third, we scan the sorted dr pairs and check if we can combine
alias checks of two neighbouring dr pairs. */ alias checks of two neighbouring dr pairs. */
for (size_t i = 1; i < comp_alias_ddrs.length (); ++i) for (size_t i = 1; i < comp_alias_ddrs.length (); ++i)
{ {
/* Deal with two ddrs (dr_a1, dr_b1) and (dr_a2, dr_b2). */ /* 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_with_seg_len *dr_a1 = &comp_alias_ddrs[i-1].first,
*dr_b1 = &comp_alias_ddrs[i-1].second, *dr_b1 = &comp_alias_ddrs[i-1].second,
*dr_a2 = &comp_alias_ddrs[i].first, *dr_a2 = &comp_alias_ddrs[i].first,
*dr_b2 = &comp_alias_ddrs[i].second; *dr_b2 = &comp_alias_ddrs[i].second;
...@@ -2892,7 +2874,9 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo) ...@@ -2892,7 +2874,9 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
swap (dr_a2, dr_b2); 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_a1->offset, 0)
|| !host_integerp (dr_a2->offset, 0)) || !host_integerp (dr_a2->offset, 0))
continue; continue;
......
...@@ -2245,7 +2245,7 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo, ...@@ -2245,7 +2245,7 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo,
void void
vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo, tree * cond_expr) vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo, tree * cond_expr)
{ {
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); LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo);
tree part_cond_expr; tree part_cond_expr;
...@@ -2263,15 +2263,15 @@ vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo, tree * cond_expr) ...@@ -2263,15 +2263,15 @@ vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo, tree * cond_expr)
for (size_t i = 0, s = comp_alias_ddrs.length (); i < s; ++i) for (size_t i = 0, s = comp_alias_ddrs.length (); i < s; ++i)
{ {
const dr_addr_with_seg_len& dr_a = comp_alias_ddrs[i].first; const dr_with_seg_len& dr_a = comp_alias_ddrs[i].first;
const dr_addr_with_seg_len& dr_b = comp_alias_ddrs[i].second; const dr_with_seg_len& dr_b = comp_alias_ddrs[i].second;
tree segment_length_a = dr_a.seg_len; tree segment_length_a = dr_a.seg_len;
tree segment_length_b = dr_b.seg_len; tree segment_length_b = dr_b.seg_len;
tree addr_base_a tree addr_base_a
= fold_build_pointer_plus (dr_a.basic_addr, dr_a.offset); = fold_build_pointer_plus (DR_BASE_ADDRESS (dr_a.dr), dr_a.offset);
tree addr_base_b tree addr_base_b
= fold_build_pointer_plus (dr_b.basic_addr, dr_b.offset); = fold_build_pointer_plus (DR_BASE_ADDRESS (dr_b.dr), dr_b.offset);
if (dump_enabled_p ()) if (dump_enabled_p ())
{ {
......
...@@ -176,32 +176,33 @@ typedef struct _slp_oprnd_info ...@@ -176,32 +176,33 @@ typedef struct _slp_oprnd_info
/* This struct is used to store the information of a data reference, /* This struct is used to store the information of a data reference,
including the data ref itself, its basic address, the access offset including the data ref itself, the access offset (calculated by summing its
and the segment length for aliasing checks. This is used to generate offset and init) and the segment length for aliasing checks.
alias checks. */ This is used to merge alias checks. */
struct dr_addr_with_seg_len struct dr_with_seg_len
{ {
dr_addr_with_seg_len (data_reference* d, tree addr, tree off, tree len) dr_with_seg_len (data_reference_p d, tree len)
: dr (d), basic_addr (addr), offset (off), seg_len (len) {} : dr (d),
offset (size_binop (PLUS_EXPR, DR_OFFSET (d), DR_INIT (d))),
seg_len (len) {}
data_reference *dr; data_reference_p dr;
tree basic_addr;
tree offset; tree offset;
tree seg_len; tree seg_len;
}; };
/* This struct contains two dr_addr_with_seg_len objects with aliasing data /* This struct contains two dr_with_seg_len objects with aliasing data
refs. Two comparisons are generated from them. */ refs. Two comparisons are generated from them. */
struct dr_addr_with_seg_len_pair_t struct dr_with_seg_len_pair_t
{ {
dr_addr_with_seg_len_pair_t (const dr_addr_with_seg_len& d1, dr_with_seg_len_pair_t (const dr_with_seg_len& d1,
const dr_addr_with_seg_len& d2) const dr_with_seg_len& d2)
: first (d1), second (d2) {} : first (d1), second (d2) {}
dr_addr_with_seg_len first; dr_with_seg_len first;
dr_addr_with_seg_len second; dr_with_seg_len second;
}; };
...@@ -306,7 +307,7 @@ typedef struct _loop_vec_info { ...@@ -306,7 +307,7 @@ typedef struct _loop_vec_info {
/* Data Dependence Relations defining address ranges together with segment /* Data Dependence Relations defining address ranges together with segment
lengths from which the run-time aliasing check is built. */ lengths from which the run-time aliasing check is built. */
vec<dr_addr_with_seg_len_pair_t> comp_alias_ddrs; vec<dr_with_seg_len_pair_t> comp_alias_ddrs;
/* Statements in the loop that have data references that are candidates for a /* Statements in the loop that have data references that are candidates for a
runtime (loop versioning) misalignment check. */ runtime (loop versioning) misalignment check. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment