diff options
author | dorit <dorit@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-23 19:43:11 +0000 |
---|---|---|
committer | dorit <dorit@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-23 19:43:11 +0000 |
commit | a9c3635d9c04c819cb3006e1ee672afe1f8ca8b7 (patch) | |
tree | 051fe6494f4f78b5942bb1c15cdd16e09cf571a5 /gcc/tree-vectorizer.c | |
parent | ccb8779353a864efed65d54a24c547757db7a4eb (diff) | |
download | gcc-a9c3635d9c04c819cb3006e1ee672afe1f8ca8b7.tar.gz |
* tree-vectorizer.c (vect_analyze_operations): Don't vectorize if
the vectorization factor is greater than the iteration count.
(vect_gen_niters_for_prolog_loop): No need to calculate min if the
iteration count is known.
(vect_build_symbol_bound): Removed. Its functionality moved to
vect_generate_tmps_on_preheader.
(vect_generate_tmps_on_preheader): Moved content of
vect_build_symbol_bound here instead of calling it. Changed some
variables names.
(vect_build_loop_niters): We don't expect a new_bb to be generated -
use gcc_assert.
(vect_gen_niters_for_prolog_loop): Likewise.
(vect_gen_niters_for_prolog_loo): Likewise.
(slpeel_make_loop_iterate_ntimes): Use buildN instead of build.
(slpeel_add_loop_guard): Likewise.
(slpeel_tree_peel_loop_to_edge): Likewise.
(vect_do_peeling_for_alignment): Likewise.
(vect_get_first_index): Missing space.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@91100 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vectorizer.c')
-rw-r--r-- | gcc/tree-vectorizer.c | 156 |
1 files changed, 65 insertions, 91 deletions
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index 6164036ab4e..8853e88da9c 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -244,7 +244,6 @@ static tree get_vectype_for_scalar_type (tree); static tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *); static tree vect_get_vec_def_for_operand (tree, tree); static tree vect_init_vector (tree, tree); -static tree vect_build_symbol_bound (tree, int, struct loop *); static void vect_finish_stmt_generation (tree stmt, tree vec_stmt, block_stmt_iterator *bsi); @@ -684,7 +683,7 @@ slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters) begin_label = build1 (GOTO_EXPR, void_type_node, begin_label); exit_label = build1 (GOTO_EXPR, void_type_node, exit_label); - cond_stmt = build (COND_EXPR, TREE_TYPE (orig_cond), cond, + cond_stmt = build3 (COND_EXPR, TREE_TYPE (orig_cond), cond, begin_label, exit_label); bsi_insert_before (&loop_exit_bsi, cond_stmt, BSI_SAME_STMT); @@ -835,7 +834,7 @@ slpeel_add_loop_guard (basic_block guard_bb, tree cond, basic_block exit_bb, tree_block_label (exit_bb)); else_label = build1 (GOTO_EXPR, void_type_node, tree_block_label (enter_e->dest)); - cond_stmt = build (COND_EXPR, void_type_node, cond, + cond_stmt = build3 (COND_EXPR, void_type_node, cond, then_label, else_label); bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT); /* Add new edge to connect entry block to the second loop. */ @@ -1044,7 +1043,7 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops, flow_loop_scan (second_loop, LOOP_ALL); pre_condition = - build (LE_EXPR, boolean_type_node, first_niters, integer_zero_node); + build2 (LE_EXPR, boolean_type_node, first_niters, integer_zero_node); skip_e = slpeel_add_loop_guard (bb_before_first_loop, pre_condition, bb_before_second_loop, bb_before_first_loop); slpeel_update_phi_nodes_for_guard (skip_e, first_loop, true /* entry-phis */, @@ -1084,7 +1083,7 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops, flow_loop_scan (first_loop, LOOP_ALL); flow_loop_scan (second_loop, LOOP_ALL); - pre_condition = build (EQ_EXPR, boolean_type_node, first_niters, niters); + pre_condition = build2 (EQ_EXPR, boolean_type_node, first_niters, niters); skip_e = slpeel_add_loop_guard (bb_between_loops, pre_condition, bb_after_second_loop, bb_before_first_loop); slpeel_update_phi_nodes_for_guard (skip_e, second_loop, false /* exit-phis */, @@ -2754,7 +2753,6 @@ vect_build_loop_niters (loop_vec_info loop_vinfo) { tree ni_name, stmt, var; edge pe; - basic_block new_bb = NULL; struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); tree ni = unshare_expr (LOOP_VINFO_NITERS (loop_vinfo)); @@ -2764,9 +2762,10 @@ vect_build_loop_niters (loop_vec_info loop_vinfo) pe = loop_preheader_edge (loop); if (stmt) - new_bb = bsi_insert_on_edge_immediate (pe, stmt); - if (new_bb) - add_bb_to_loop (new_bb, EDGE_PRED (new_bb, 0)->src->loop_father); + { + basic_block new_bb = bsi_insert_on_edge_immediate (pe, stmt); + gcc_assert (!new_bb); + } return ni_name; } @@ -2781,102 +2780,64 @@ vect_build_loop_niters (loop_vec_info loop_vinfo) and places them at the loop preheader edge. */ static void -vect_generate_tmps_on_preheader (loop_vec_info loop_vinfo, tree *ni_name_p, - tree *ratio_mult_vf_name_p, tree *ratio_p) +vect_generate_tmps_on_preheader (loop_vec_info loop_vinfo, + tree *ni_name_ptr, + tree *ratio_mult_vf_name_ptr, + tree *ratio_name_ptr) { edge pe; basic_block new_bb; tree stmt, ni_name; - tree ratio; - tree ratio_mult_vf_name, ratio_mult_vf; + tree var; + tree ratio_name; + tree ratio_mult_vf_name; struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); - tree ni = LOOP_VINFO_NITERS(loop_vinfo); - - int vf, i; + tree ni = LOOP_VINFO_NITERS (loop_vinfo); + int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); + tree log_vf = build_int_cst (unsigned_type_node, exact_log2 (vf)); + + pe = loop_preheader_edge (loop); /* Generate temporary variable that contains number of iterations loop executes. */ ni_name = vect_build_loop_niters (loop_vinfo); - /* ratio = ni / vf. - vf is power of 2; then if ratio = = n >> log2 (vf). */ - vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); - ratio = vect_build_symbol_bound (ni_name, vf, loop); - - /* Update initial conditions of loop copy. */ - - /* ratio_mult_vf = ratio * vf; - then if ratio_mult_vf = ratio << log2 (vf). */ + /* Create: ratio = ni >> log2(vf) */ - i = exact_log2 (vf); - ratio_mult_vf = create_tmp_var (TREE_TYPE (ni), "ratio_mult_vf"); - add_referenced_tmp_var (ratio_mult_vf); + var = create_tmp_var (TREE_TYPE (ni), "bnd"); + add_referenced_tmp_var (var); + ratio_name = make_ssa_name (var, NULL_TREE); + stmt = build2 (MODIFY_EXPR, void_type_node, ratio_name, + build2 (RSHIFT_EXPR, TREE_TYPE (ni_name), ni_name, log_vf)); + SSA_NAME_DEF_STMT (ratio_name) = stmt; - ratio_mult_vf_name = make_ssa_name (ratio_mult_vf, NULL_TREE); + pe = loop_preheader_edge (loop); + new_bb = bsi_insert_on_edge_immediate (pe, stmt); + gcc_assert (!new_bb); + + /* Create: ratio_mult_vf = ratio << log2 (vf). */ + var = create_tmp_var (TREE_TYPE (ni), "ratio_mult_vf"); + add_referenced_tmp_var (var); + ratio_mult_vf_name = make_ssa_name (var, NULL_TREE); stmt = build2 (MODIFY_EXPR, void_type_node, ratio_mult_vf_name, - build2 (LSHIFT_EXPR, TREE_TYPE (ratio), - ratio, build_int_cst (unsigned_type_node, - i))); - + build2 (LSHIFT_EXPR, TREE_TYPE (ratio_name), ratio_name, log_vf)); SSA_NAME_DEF_STMT (ratio_mult_vf_name) = stmt; pe = loop_preheader_edge (loop); new_bb = bsi_insert_on_edge_immediate (pe, stmt); - if (new_bb) - add_bb_to_loop (new_bb, EDGE_PRED (new_bb, 0)->src->loop_father); + gcc_assert (!new_bb); - *ni_name_p = ni_name; - *ratio_mult_vf_name_p = ratio_mult_vf_name; - *ratio_p = ratio; + *ni_name_ptr = ni_name; + *ratio_mult_vf_name_ptr = ratio_mult_vf_name; + *ratio_name_ptr = ratio_name; return; } -/* This function generates stmt - - tmp = n / vf; - - and attaches it to preheader of LOOP. */ - -static tree -vect_build_symbol_bound (tree n, int vf, struct loop * loop) -{ - tree var, stmt, var_name; - edge pe; - basic_block new_bb; - int i; - - /* create temporary variable */ - var = create_tmp_var (TREE_TYPE (n), "bnd"); - add_referenced_tmp_var (var); - - var_name = make_ssa_name (var, NULL_TREE); - - /* vf is power of 2; then n/vf = n >> log2 (vf). */ - - i = exact_log2 (vf); - stmt = build2 (MODIFY_EXPR, void_type_node, var_name, - build2 (RSHIFT_EXPR, TREE_TYPE (n), - n, build_int_cst (unsigned_type_node,i))); - - SSA_NAME_DEF_STMT (var_name) = stmt; - - pe = loop_preheader_edge (loop); - new_bb = bsi_insert_on_edge_immediate (pe, stmt); - if (new_bb) - add_bb_to_loop (new_bb, EDGE_PRED (new_bb, 0)->src->loop_father); - else - if (vect_debug_details (NULL)) - fprintf (dump_file, "New bb on preheader edge was not generated."); - - return var_name; -} - - /* Function vect_update_ivs_after_vectorizer. "Advance" the induction variables of LOOP to the value they should take @@ -3104,8 +3065,7 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters) pe = loop_preheader_edge (loop); new_bb = bsi_insert_on_edge_immediate (pe, new_stmts); - if (new_bb) - add_bb_to_loop (new_bb, EDGE_PRED (new_bb, 0)->src->loop_father); + gcc_assert (!new_bb); /* Create: byte_misalign = addr & (vectype_size - 1) */ byte_misalign = build2 (BIT_AND_EXPR, type, start_addr, vectype_size_minus_1); @@ -3118,9 +3078,14 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters) iters = build2 (MINUS_EXPR, unsigned_type_node, vf_tree, elem_misalign); iters = build2 (BIT_AND_EXPR, unsigned_type_node, iters, vf_minus_1); iters = fold_convert (niters_type, iters); - + /* Create: prolog_loop_niters = min (iters, loop_niters) */ - iters = build2 (MIN_EXPR, niters_type, iters, loop_niters); + /* If the loop bound is known at compile time we already verified that it is + greater than vf; since the misalignment ('iters') is at most vf, there's + no need to generate the MIN_EXPR in this case. */ + if (!host_integerp (loop_niters, 0)) + iters = build2 (MIN_EXPR, niters_type, iters, loop_niters); + var = create_tmp_var (niters_type, "prolog_loop_niters"); add_referenced_tmp_var (var); iters_name = force_gimple_operand (iters, &stmt, false, var); @@ -3128,9 +3093,10 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters) /* Insert stmt on loop preheader edge. */ pe = loop_preheader_edge (loop); if (stmt) - new_bb = bsi_insert_on_edge_immediate (pe, stmt); - if (new_bb) - add_bb_to_loop (new_bb, EDGE_PRED (new_bb, 0)->src->loop_father); + { + basic_block new_bb = bsi_insert_on_edge_immediate (pe, stmt); + gcc_assert (!new_bb); + } return iters_name; } @@ -3154,8 +3120,8 @@ vect_update_inits_of_dr (struct data_reference *dr, struct loop *loop, step = evolution_part_in_loop_num (access_fn, loop->num); init = initial_condition (access_fn); - init_new = build (PLUS_EXPR, TREE_TYPE (init), - build (MULT_EXPR, TREE_TYPE (niters), + init_new = build2 (PLUS_EXPR, TREE_TYPE (init), + build2 (MULT_EXPR, TREE_TYPE (niters), niters, step), init); DR_ACCESS_FN (dr, 0) = chrec_replace_initial_condition (access_fn, init_new); @@ -3441,7 +3407,7 @@ vect_analyze_operations (loop_vec_info loop_vinfo) basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo); int nbbs = loop->num_nodes; block_stmt_iterator si; - int vectorization_factor = 0; + unsigned int vectorization_factor = 0; int i; bool ok; tree scalar_type; @@ -3456,7 +3422,7 @@ vect_analyze_operations (loop_vec_info loop_vinfo) for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si)) { tree stmt = bsi_stmt (si); - int nunits; + unsigned int nunits; stmt_vec_info stmt_info = vinfo_for_stmt (stmt); tree vectype; @@ -3578,6 +3544,14 @@ vect_analyze_operations (loop_vec_info loop_vinfo) "vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC, vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo)); + if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) + && LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor) + { + if (vect_debug_stats (loop) || vect_debug_details (loop)) + fprintf (dump_file, "not vectorized: iteration count too small."); + return false; + } + if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) || LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0) { @@ -3935,7 +3909,7 @@ vect_get_first_index (tree ref, tree *array_first_index) else { array_start = array_ref_low_bound (ref); - if (!host_integerp (array_start,0)) + if (!host_integerp (array_start, 0)) { if (vect_debug_details (NULL)) { |