The following is a collection of TLC sitting in my local tree, mostly resulting in less obscure IL after vectorization.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2013-03-18 Richard Biener <rguent...@suse.de> * tree-vect-loop-manip.c (vect_create_cond_for_alias_checks): Remove cond_expr_stmt_list argument and do not gimplify the built expression. (vect_loop_versioning): Adjust. * tree-vect-data-refs.c (vect_create_addr_base_for_vector_ref): Cleanup to use less temporaries. (vect_create_data_ref_ptr): Cleanup. Index: gcc/tree-vect-loop-manip.c =================================================================== *** gcc/tree-vect-loop-manip.c.orig 2013-02-20 11:05:04.000000000 +0100 --- gcc/tree-vect-loop-manip.c 2013-03-18 11:38:46.633554021 +0100 *************** vect_vfa_segment_size (struct data_refer *** 2271,2290 **** Output: COND_EXPR - conditional expression. - COND_EXPR_STMT_LIST - statements needed to construct the conditional - expression. - The returned value is the conditional expression to be used in the if statement that controls which version of the loop gets executed at runtime. */ static void ! vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo, ! tree * cond_expr, ! gimple_seq * cond_expr_stmt_list) { - struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); vec<ddr_p> may_alias_ddrs = LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo); int vect_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo); --- 2271,2284 ---- Output: COND_EXPR - conditional expression. The returned value is the conditional expression to be used in the if statement that controls which version of the loop gets executed at runtime. */ static void ! vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo, tree * cond_expr) { vec<ddr_p> may_alias_ddrs = LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo); int vect_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo); *************** vect_create_cond_for_alias_checks (loop_ *** 2333,2344 **** dr_b = STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt_b)); } ! addr_base_a = ! vect_create_addr_base_for_vector_ref (stmt_a, cond_expr_stmt_list, ! NULL_TREE, loop); ! addr_base_b = ! vect_create_addr_base_for_vector_ref (stmt_b, cond_expr_stmt_list, ! NULL_TREE, loop); if (!operand_equal_p (DR_STEP (dr_a), DR_STEP (dr_b), 0)) length_factor = scalar_loop_iters; --- 2327,2340 ---- dr_b = STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt_b)); } ! addr_base_a ! = fold_build_pointer_plus (DR_BASE_ADDRESS (dr_a), ! size_binop (PLUS_EXPR, DR_OFFSET (dr_a), ! DR_INIT (dr_a))); ! addr_base_b ! = fold_build_pointer_plus (DR_BASE_ADDRESS (dr_b), ! size_binop (PLUS_EXPR, DR_OFFSET (dr_b), ! DR_INIT (dr_b))); if (!operand_equal_p (DR_STEP (dr_a), DR_STEP (dr_b), 0)) length_factor = scalar_loop_iters; *************** vect_loop_versioning (loop_vec_info loop *** 2435,2442 **** &cond_expr_stmt_list); if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo)) ! vect_create_cond_for_alias_checks (loop_vinfo, &cond_expr, ! &cond_expr_stmt_list); cond_expr = force_gimple_operand_1 (cond_expr, &gimplify_stmt_list, is_gimple_condexpr, NULL_TREE); --- 2431,2437 ---- &cond_expr_stmt_list); if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo)) ! vect_create_cond_for_alias_checks (loop_vinfo, &cond_expr); cond_expr = force_gimple_operand_1 (cond_expr, &gimplify_stmt_list, is_gimple_condexpr, NULL_TREE); Index: gcc/tree-vect-data-refs.c =================================================================== *** gcc/tree-vect-data-refs.c.orig 2013-03-05 16:50:25.000000000 +0100 --- gcc/tree-vect-data-refs.c 2013-03-18 11:37:47.391898625 +0100 *************** vect_create_addr_base_for_vector_ref (gi *** 3556,3574 **** { stmt_vec_info stmt_info = vinfo_for_stmt (stmt); struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); ! tree data_ref_base = unshare_expr (DR_BASE_ADDRESS (dr)); const char *base_name; ! tree data_ref_base_var; ! tree vec_stmt; ! tree addr_base, addr_expr; tree dest; gimple_seq seq = NULL; ! tree base_offset = unshare_expr (DR_OFFSET (dr)); ! tree init = unshare_expr (DR_INIT (dr)); tree vect_ptr_type; tree step = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr))); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); - tree base; if (loop_vinfo && loop && loop != (gimple_bb (stmt))->loop_father) { --- 3556,3571 ---- { stmt_vec_info stmt_info = vinfo_for_stmt (stmt); struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); ! tree data_ref_base; const char *base_name; ! tree addr_base; tree dest; gimple_seq seq = NULL; ! tree base_offset; ! tree init; tree vect_ptr_type; tree step = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr))); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); if (loop_vinfo && loop && loop != (gimple_bb (stmt))->loop_father) { *************** vect_create_addr_base_for_vector_ref (gi *** 3580,3585 **** --- 3577,3588 ---- base_offset = unshare_expr (STMT_VINFO_DR_OFFSET (stmt_info)); init = unshare_expr (STMT_VINFO_DR_INIT (stmt_info)); } + else + { + data_ref_base = unshare_expr (DR_BASE_ADDRESS (dr)); + base_offset = unshare_expr (DR_OFFSET (dr)); + init = unshare_expr (DR_INIT (dr)); + } if (loop_vinfo) base_name = get_name (data_ref_base); *************** vect_create_addr_base_for_vector_ref (gi *** 3590,3618 **** base_name = get_name (DR_REF (dr)); } - data_ref_base_var = create_tmp_var (TREE_TYPE (data_ref_base), "batmp"); - data_ref_base = force_gimple_operand (data_ref_base, &seq, true, - data_ref_base_var); - gimple_seq_add_seq (new_stmt_list, seq); - /* Create base_offset */ base_offset = size_binop (PLUS_EXPR, fold_convert (sizetype, base_offset), fold_convert (sizetype, init)); - dest = create_tmp_var (sizetype, "base_off"); - base_offset = force_gimple_operand (base_offset, &seq, true, dest); - gimple_seq_add_seq (new_stmt_list, seq); if (offset) { - tree tmp = create_tmp_var (sizetype, "offset"); - offset = fold_build2 (MULT_EXPR, sizetype, fold_convert (sizetype, offset), step); base_offset = fold_build2 (PLUS_EXPR, sizetype, base_offset, offset); - base_offset = force_gimple_operand (base_offset, &seq, false, tmp); - gimple_seq_add_seq (new_stmt_list, seq); } /* base + base_offset */ --- 3593,3609 ---- *************** vect_create_addr_base_for_vector_ref (gi *** 3626,3659 **** } vect_ptr_type = build_pointer_type (STMT_VINFO_VECTYPE (stmt_info)); ! base = get_base_address (DR_REF (dr)); ! if (base ! && TREE_CODE (base) == MEM_REF) ! vect_ptr_type ! = build_qualified_type (vect_ptr_type, ! TYPE_QUALS (TREE_TYPE (TREE_OPERAND (base, 0)))); ! ! vec_stmt = fold_convert (vect_ptr_type, addr_base); ! addr_expr = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var, ! base_name); ! vec_stmt = force_gimple_operand (vec_stmt, &seq, false, addr_expr); gimple_seq_add_seq (new_stmt_list, seq); if (DR_PTR_INFO (dr) ! && TREE_CODE (vec_stmt) == SSA_NAME) { ! duplicate_ssa_name_ptr_info (vec_stmt, DR_PTR_INFO (dr)); if (offset) ! mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (vec_stmt)); } if (dump_enabled_p ()) { dump_printf_loc (MSG_NOTE, vect_location, "created "); ! dump_generic_expr (MSG_NOTE, TDF_SLIM, vec_stmt); } ! return vec_stmt; } --- 3617,3642 ---- } vect_ptr_type = build_pointer_type (STMT_VINFO_VECTYPE (stmt_info)); ! addr_base = fold_convert (vect_ptr_type, addr_base); ! dest = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var, base_name); ! addr_base = force_gimple_operand (addr_base, &seq, false, dest); gimple_seq_add_seq (new_stmt_list, seq); if (DR_PTR_INFO (dr) ! && TREE_CODE (addr_base) == SSA_NAME) { ! duplicate_ssa_name_ptr_info (addr_base, DR_PTR_INFO (dr)); if (offset) ! mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (addr_base)); } if (dump_enabled_p ()) { dump_printf_loc (MSG_NOTE, vect_location, "created "); ! dump_generic_expr (MSG_NOTE, TDF_SLIM, addr_base); } ! return addr_base; } *************** vect_create_data_ref_ptr (gimple stmt, t *** 3733,3739 **** gimple incr; tree step; bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info); - tree base; gcc_assert (TREE_CODE (aggr_type) == ARRAY_TYPE || TREE_CODE (aggr_type) == VECTOR_TYPE); --- 3716,3721 ---- *************** vect_create_data_ref_ptr (gimple stmt, t *** 3785,3837 **** dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_BASE_OBJECT (dr)); } ! /* (1) Create the new aggregate-pointer variable. */ ! aggr_ptr_type = build_pointer_type (aggr_type); ! base = get_base_address (DR_REF (dr)); ! if (base ! && TREE_CODE (base) == MEM_REF) ! aggr_ptr_type ! = build_qualified_type (aggr_ptr_type, ! TYPE_QUALS (TREE_TYPE (TREE_OPERAND (base, 0)))); ! aggr_ptr = vect_get_new_vect_var (aggr_ptr_type, vect_pointer_var, base_name); ! ! /* Vector and array types inherit the alias set of their component type by default so we need to use a ref-all pointer if the data reference does not conflict with the created aggregated data reference because it is not addressable. */ ! if (!alias_sets_conflict_p (get_deref_alias_set (aggr_ptr), get_alias_set (DR_REF (dr)))) ! { ! aggr_ptr_type ! = build_pointer_type_for_mode (aggr_type, ! TYPE_MODE (aggr_ptr_type), true); ! aggr_ptr = vect_get_new_vect_var (aggr_ptr_type, vect_pointer_var, ! base_name); ! } ! /* Likewise for any of the data references in the stmt group. */ else if (STMT_VINFO_GROUP_SIZE (stmt_info) > 1) { gimple orig_stmt = STMT_VINFO_GROUP_FIRST_ELEMENT (stmt_info); do { ! tree lhs = gimple_assign_lhs (orig_stmt); ! if (!alias_sets_conflict_p (get_deref_alias_set (aggr_ptr), ! get_alias_set (lhs))) { ! aggr_ptr_type ! = build_pointer_type_for_mode (aggr_type, ! TYPE_MODE (aggr_ptr_type), true); ! aggr_ptr ! = vect_get_new_vect_var (aggr_ptr_type, vect_pointer_var, ! base_name); break; } ! ! orig_stmt = STMT_VINFO_GROUP_NEXT_ELEMENT (vinfo_for_stmt (orig_stmt)); } while (orig_stmt); } /* Note: If the dataref is in an inner-loop nested in LOOP, and we are vectorizing LOOP (i.e., outer-loop vectorization), we need to create two --- 3767,3803 ---- dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_BASE_OBJECT (dr)); } ! /* (1) Create the new aggregate-pointer variable. ! Vector and array types inherit the alias set of their component type by default so we need to use a ref-all pointer if the data reference does not conflict with the created aggregated data reference because it is not addressable. */ ! bool need_ref_all = false; ! if (!alias_sets_conflict_p (get_alias_set (aggr_type), get_alias_set (DR_REF (dr)))) ! need_ref_all = true; /* Likewise for any of the data references in the stmt group. */ else if (STMT_VINFO_GROUP_SIZE (stmt_info) > 1) { gimple orig_stmt = STMT_VINFO_GROUP_FIRST_ELEMENT (stmt_info); do { ! stmt_vec_info sinfo = vinfo_for_stmt (orig_stmt); ! struct data_reference *sdr = STMT_VINFO_DATA_REF (sinfo); ! if (!alias_sets_conflict_p (get_alias_set (aggr_type), ! get_alias_set (DR_REF (sdr)))) { ! need_ref_all = true; break; } ! orig_stmt = STMT_VINFO_GROUP_NEXT_ELEMENT (sinfo); } while (orig_stmt); } + aggr_ptr_type = build_pointer_type_for_mode (aggr_type, ptr_mode, + need_ref_all); + aggr_ptr = vect_get_new_vect_var (aggr_ptr_type, vect_pointer_var, base_name); + /* Note: If the dataref is in an inner-loop nested in LOOP, and we are vectorizing LOOP (i.e., outer-loop vectorization), we need to create two