}
-/* 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
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;
}
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))));
{
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);
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);
/* 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)
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;
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
/* This struct is used to store the information of a data reference,
- including the data ref itself, its basic address, the access offset
- and the segment length for aliasing checks. This is used to generate
- alias checks. */
+ including the data ref itself, the access offset (calculated by summing its
+ offset and init) and the segment length for aliasing 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 (d), basic_addr (addr), offset (off), seg_len (len) {}
+ dr_with_seg_len (data_reference_p d, tree len)
+ : dr (d),
+ offset (size_binop (PLUS_EXPR, DR_OFFSET (d), DR_INIT (d))),
+ seg_len (len) {}
- data_reference *dr;
- tree basic_addr;
+ data_reference_p dr;
tree offset;
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. */
-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,
- const dr_addr_with_seg_len& d2)
+ dr_with_seg_len_pair_t (const dr_with_seg_len& d1,
+ const dr_with_seg_len& d2)
: first (d1), second (d2) {}
- dr_addr_with_seg_len first;
- dr_addr_with_seg_len second;
+ dr_with_seg_len first;
+ dr_with_seg_len second;
};
/* Data Dependence Relations defining address ranges together with segment
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
runtime (loop versioning) misalignment check. */