mirror of
https://github.com/Stichting-MINIX-Research-Foundation/pkgsrc-ng.git
synced 2025-09-29 23:13:54 -04:00
121 lines
4.3 KiB
C
121 lines
4.3 KiB
C
$NetBSD$
|
|
|
|
--- gcc/tree-vect-loop-manip.c.orig Tue Jan 19 16:05:57 2010
|
|
+++ gcc/tree-vect-loop-manip.c
|
|
@@ -1516,7 +1516,7 @@ vect_generate_tmps_on_preheader (loop_vec_info loop_vi
|
|
edge pe;
|
|
basic_block new_bb;
|
|
gimple_seq stmts;
|
|
- tree ni_name;
|
|
+ tree ni_name, ni_minus_gap_name;
|
|
tree var;
|
|
tree ratio_name;
|
|
tree ratio_mult_vf_name;
|
|
@@ -1533,9 +1533,39 @@ vect_generate_tmps_on_preheader (loop_vec_info loop_vi
|
|
ni_name = vect_build_loop_niters (loop_vinfo, cond_expr_stmt_list);
|
|
log_vf = build_int_cst (TREE_TYPE (ni), exact_log2 (vf));
|
|
|
|
+ /* If epilogue loop is required because of data accesses with gaps, we
|
|
+ subtract one iteration from the total number of iterations here for
|
|
+ correct calculation of RATIO. */
|
|
+ if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo))
|
|
+ {
|
|
+ ni_minus_gap_name = fold_build2 (MINUS_EXPR, TREE_TYPE (ni_name),
|
|
+ ni_name,
|
|
+ build_one_cst (TREE_TYPE (ni_name)));
|
|
+ if (!is_gimple_val (ni_minus_gap_name))
|
|
+ {
|
|
+ var = create_tmp_var (TREE_TYPE (ni), "ni_gap");
|
|
+ add_referenced_var (var);
|
|
+
|
|
+ stmts = NULL;
|
|
+ ni_minus_gap_name = force_gimple_operand (ni_minus_gap_name, &stmts,
|
|
+ true, var);
|
|
+ if (cond_expr_stmt_list)
|
|
+ gimple_seq_add_seq (&cond_expr_stmt_list, stmts);
|
|
+ else
|
|
+ {
|
|
+ pe = loop_preheader_edge (loop);
|
|
+ new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
|
|
+ gcc_assert (!new_bb);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ ni_minus_gap_name = ni_name;
|
|
+
|
|
/* Create: ratio = ni >> log2(vf) */
|
|
|
|
- ratio_name = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ni_name), ni_name, log_vf);
|
|
+ ratio_name = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ni_minus_gap_name),
|
|
+ ni_minus_gap_name, log_vf);
|
|
if (!is_gimple_val (ratio_name))
|
|
{
|
|
var = create_tmp_var (TREE_TYPE (ni), "bnd");
|
|
@@ -2312,26 +2342,26 @@ vect_create_cond_for_align_checks (loop_vec_info loop_
|
|
|
|
Input:
|
|
DR: The data reference.
|
|
- VECT_FACTOR: vectorization factor.
|
|
+ LENGTH_FACTOR: segment length to consider.
|
|
|
|
Return an expression whose value is the size of segment which will be
|
|
accessed by DR. */
|
|
|
|
static tree
|
|
-vect_vfa_segment_size (struct data_reference *dr, tree vect_factor)
|
|
+vect_vfa_segment_size (struct data_reference *dr, tree length_factor)
|
|
{
|
|
- tree segment_length = fold_build2 (MULT_EXPR, integer_type_node,
|
|
- DR_STEP (dr), vect_factor);
|
|
-
|
|
+ tree segment_length;
|
|
+ segment_length = size_binop (MULT_EXPR,
|
|
+ fold_convert (sizetype, DR_STEP (dr)),
|
|
+ fold_convert (sizetype, length_factor));
|
|
if (vect_supportable_dr_alignment (dr) == dr_explicit_realign_optimized)
|
|
{
|
|
tree vector_size = TYPE_SIZE_UNIT
|
|
(STMT_VINFO_VECTYPE (vinfo_for_stmt (DR_STMT (dr))));
|
|
|
|
- segment_length = fold_build2 (PLUS_EXPR, integer_type_node,
|
|
- segment_length, vector_size);
|
|
+ segment_length = size_binop (PLUS_EXPR, segment_length, vector_size);
|
|
}
|
|
- return fold_convert (sizetype, segment_length);
|
|
+ return segment_length;
|
|
}
|
|
|
|
|
|
@@ -2365,12 +2395,12 @@ vect_create_cond_for_alias_checks (loop_vec_info loop_
|
|
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
|
|
VEC (ddr_p, heap) * may_alias_ddrs =
|
|
LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo);
|
|
- tree vect_factor =
|
|
- build_int_cst (integer_type_node, LOOP_VINFO_VECT_FACTOR (loop_vinfo));
|
|
+ int vect_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
|
|
+ tree scalar_loop_iters = LOOP_VINFO_NITERS (loop_vinfo);
|
|
|
|
ddr_p ddr;
|
|
unsigned int i;
|
|
- tree part_cond_expr;
|
|
+ tree part_cond_expr, length_factor;
|
|
|
|
/* Create expression
|
|
((store_ptr_0 + store_segment_length_0) < load_ptr_0)
|
|
@@ -2417,8 +2447,12 @@ vect_create_cond_for_alias_checks (loop_vec_info loop_
|
|
vect_create_addr_base_for_vector_ref (stmt_b, cond_expr_stmt_list,
|
|
NULL_TREE, loop);
|
|
|
|
- segment_length_a = vect_vfa_segment_size (dr_a, vect_factor);
|
|
- segment_length_b = vect_vfa_segment_size (dr_b, vect_factor);
|
|
+ if (!operand_equal_p (DR_STEP (dr_a), DR_STEP (dr_b), 0))
|
|
+ length_factor = scalar_loop_iters;
|
|
+ else
|
|
+ length_factor = size_int (vect_factor);
|
|
+ segment_length_a = vect_vfa_segment_size (dr_a, length_factor);
|
|
+ segment_length_b = vect_vfa_segment_size (dr_b, length_factor);
|
|
|
|
if (vect_print_dump_info (REPORT_DR_DETAILS))
|
|
{
|