From b939ea86b96fcff3f4fe61ad794858ddae553563 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 13 Oct 2015 08:39:41 +0000 Subject: [PATCH] tree-vect-data-refs.c (vect_analyze_data_ref_dependences): Allocate the data dependence vector. 2015-10-13 Richard Biener * tree-vect-data-refs.c (vect_analyze_data_ref_dependences): Allocate the data dependence vector. (vect_peeling_hash_insert): Get the peeling hash table as argument. (vect_peeling_hash_get_lowest_cost): Likewise. (vect_enhance_data_refs_alignment): Adjust. (struct _vect_peel_info, struct _vect_peel_extended_info, struct peel_info_hasher): Move from ... * tree-vectorizer.h: ... here. (LOOP_VINFO_COST_MODEL_MIN_ITERS): Remove. (LOOP_VINFO_PEELING_HTAB): Likewise. (struct _loop_vec_info): Remove min_profitable_iters and peeling_htab members. * tree-vect-loop.c (new_loop_vec_info): Do not allocate vectors here. (destroy_loop_vec_info): Adjust. (vect_analyze_loop_2): Do not set LOOP_VINFO_COST_MODEL_MIN_ITERS. (vect_estimate_min_profitable_iters): Use LOOP_VINFO_COMP_ALIAS_DDRS to estimate alias versioning cost. * tree-vect-slp.c (vect_analyze_slp_cost): Dump header. From-SVN: r228751 --- gcc/ChangeLog | 22 +++++++++++++++ gcc/tree-vect-data-refs.c | 72 ++++++++++++++++++++++++++++++++++++----------- gcc/tree-vect-loop.c | 27 +++++++----------- gcc/tree-vect-slp.c | 4 +++ gcc/tree-vectorizer.h | 47 ------------------------------- 5 files changed, 91 insertions(+), 81 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9fcea29..e5ede0b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2015-10-13 Richard Biener + + * tree-vect-data-refs.c (vect_analyze_data_ref_dependences): Allocate + the data dependence vector. + (vect_peeling_hash_insert): Get the peeling hash table as argument. + (vect_peeling_hash_get_lowest_cost): Likewise. + (vect_enhance_data_refs_alignment): Adjust. + (struct _vect_peel_info, struct _vect_peel_extended_info, + struct peel_info_hasher): Move from ... + * tree-vectorizer.h: ... here. + (LOOP_VINFO_COST_MODEL_MIN_ITERS): Remove. + (LOOP_VINFO_PEELING_HTAB): Likewise. + (struct _loop_vec_info): Remove min_profitable_iters and + peeling_htab members. + * tree-vect-loop.c (new_loop_vec_info): Do not allocate vectors + here. + (destroy_loop_vec_info): Adjust. + (vect_analyze_loop_2): Do not set LOOP_VINFO_COST_MODEL_MIN_ITERS. + (vect_estimate_min_profitable_iters): Use LOOP_VINFO_COMP_ALIAS_DDRS + to estimate alias versioning cost. + * tree-vect-slp.c (vect_analyze_slp_cost): Dump header. + 2015-10-13 Richard Sandiford * real.h (real_isinteger): Declare. diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index e653c68..8a4d489 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -468,6 +468,9 @@ vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo, int *max_vf) dump_printf_loc (MSG_NOTE, vect_location, "=== vect_analyze_data_ref_dependences ===\n"); + LOOP_VINFO_DDRS (loop_vinfo) + .create (LOOP_VINFO_DATAREFS (loop_vinfo).length () + * LOOP_VINFO_DATAREFS (loop_vinfo).length ()); LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) = true; if (!compute_all_dependences (LOOP_VINFO_DATAREFS (loop_vinfo), &LOOP_VINFO_DDRS (loop_vinfo), @@ -1039,10 +1042,48 @@ vect_get_data_access_cost (struct data_reference *dr, } +typedef struct _vect_peel_info +{ + int npeel; + struct data_reference *dr; + unsigned int count; +} *vect_peel_info; + +typedef struct _vect_peel_extended_info +{ + struct _vect_peel_info peel_info; + unsigned int inside_cost; + unsigned int outside_cost; + stmt_vector_for_cost body_cost_vec; +} *vect_peel_extended_info; + + +/* Peeling hashtable helpers. */ + +struct peel_info_hasher : free_ptr_hash <_vect_peel_info> +{ + static inline hashval_t hash (const _vect_peel_info *); + static inline bool equal (const _vect_peel_info *, const _vect_peel_info *); +}; + +inline hashval_t +peel_info_hasher::hash (const _vect_peel_info *peel_info) +{ + return (hashval_t) peel_info->npeel; +} + +inline bool +peel_info_hasher::equal (const _vect_peel_info *a, const _vect_peel_info *b) +{ + return (a->npeel == b->npeel); +} + + /* Insert DR into peeling hash table with NPEEL as key. */ static void -vect_peeling_hash_insert (loop_vec_info loop_vinfo, struct data_reference *dr, +vect_peeling_hash_insert (hash_table *peeling_htab, + loop_vec_info loop_vinfo, struct data_reference *dr, int npeel) { struct _vect_peel_info elem, *slot; @@ -1050,7 +1091,7 @@ vect_peeling_hash_insert (loop_vec_info loop_vinfo, struct data_reference *dr, bool supportable_dr_alignment = vect_supportable_dr_alignment (dr, true); elem.npeel = npeel; - slot = LOOP_VINFO_PEELING_HTAB (loop_vinfo)->find (&elem); + slot = peeling_htab->find (&elem); if (slot) slot->count++; else @@ -1059,8 +1100,7 @@ vect_peeling_hash_insert (loop_vec_info loop_vinfo, struct data_reference *dr, slot->npeel = npeel; slot->dr = dr; slot->count = 1; - new_slot - = LOOP_VINFO_PEELING_HTAB (loop_vinfo)->find_slot (slot, INSERT); + new_slot = peeling_htab->find_slot (slot, INSERT); *new_slot = slot; } @@ -1164,7 +1204,8 @@ vect_peeling_hash_get_lowest_cost (_vect_peel_info **slot, option that aligns as many accesses as possible. */ static struct data_reference * -vect_peeling_hash_choose_best_peeling (loop_vec_info loop_vinfo, +vect_peeling_hash_choose_best_peeling (hash_table *peeling_htab, + loop_vec_info loop_vinfo, unsigned int *npeel, stmt_vector_for_cost *body_cost_vec) { @@ -1177,16 +1218,14 @@ vect_peeling_hash_choose_best_peeling (loop_vec_info loop_vinfo, { res.inside_cost = INT_MAX; res.outside_cost = INT_MAX; - LOOP_VINFO_PEELING_HTAB (loop_vinfo) - ->traverse <_vect_peel_extended_info *, - vect_peeling_hash_get_lowest_cost> (&res); + peeling_htab->traverse <_vect_peel_extended_info *, + vect_peeling_hash_get_lowest_cost> (&res); } else { res.peel_info.count = 0; - LOOP_VINFO_PEELING_HTAB (loop_vinfo) - ->traverse <_vect_peel_extended_info *, - vect_peeling_hash_get_most_frequent> (&res); + peeling_htab->traverse <_vect_peel_extended_info *, + vect_peeling_hash_get_most_frequent> (&res); } *npeel = res.peel_info.npeel; @@ -1307,6 +1346,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) tree vectype; unsigned int nelements, mis, same_align_drs_max = 0; stmt_vector_for_cost body_cost_vec = stmt_vector_for_cost (); + hash_table peeling_htab (1); if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, @@ -1379,10 +1419,6 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) size_zero_node) < 0; /* Save info about DR in the hash table. */ - if (!LOOP_VINFO_PEELING_HTAB (loop_vinfo)) - LOOP_VINFO_PEELING_HTAB (loop_vinfo) - = new hash_table (1); - vectype = STMT_VINFO_VECTYPE (stmt_info); nelements = TYPE_VECTOR_SUBPARTS (vectype); mis = DR_MISALIGNMENT (dr) / GET_MODE_SIZE (TYPE_MODE ( @@ -1424,7 +1460,8 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) for (j = 0; j < possible_npeel_number; j++) { - vect_peeling_hash_insert (loop_vinfo, dr, npeel_tmp); + vect_peeling_hash_insert (&peeling_htab, loop_vinfo, + dr, npeel_tmp); npeel_tmp += nelements; } @@ -1590,7 +1627,8 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) gcc_assert (!all_misalignments_unknown); /* Choose the best peeling from the hash table. */ - dr0 = vect_peeling_hash_choose_best_peeling (loop_vinfo, &npeel, + dr0 = vect_peeling_hash_choose_best_peeling (&peeling_htab, + loop_vinfo, &npeel, &body_cost_vec); if (!dr0 || !npeel) do_peeling = false; diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 6b37238..6840535 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -937,23 +937,20 @@ new_loop_vec_info (struct loop *loop) LOOP_VINFO_NITERSM1 (res) = NULL; LOOP_VINFO_NITERS (res) = NULL; LOOP_VINFO_NITERS_UNCHANGED (res) = NULL; - LOOP_VINFO_COST_MODEL_MIN_ITERS (res) = 0; LOOP_VINFO_COST_MODEL_THRESHOLD (res) = 0; LOOP_VINFO_VECTORIZABLE_P (res) = 0; LOOP_VINFO_PEELING_FOR_ALIGNMENT (res) = 0; LOOP_VINFO_VECT_FACTOR (res) = 0; - LOOP_VINFO_LOOP_NEST (res).create (3); - LOOP_VINFO_DATAREFS (res).create (10); - LOOP_VINFO_DDRS (res).create (10 * 10); + LOOP_VINFO_LOOP_NEST (res) = vNULL; + LOOP_VINFO_DATAREFS (res) = vNULL; + LOOP_VINFO_DDRS (res) = vNULL; LOOP_VINFO_UNALIGNED_DR (res) = NULL; - LOOP_VINFO_MAY_MISALIGN_STMTS (res).create ( - PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS)); - LOOP_VINFO_MAY_ALIAS_DDRS (res).create ( - PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS)); - LOOP_VINFO_GROUPED_STORES (res).create (10); - LOOP_VINFO_REDUCTIONS (res).create (10); - LOOP_VINFO_REDUCTION_CHAINS (res).create (10); - LOOP_VINFO_SLP_INSTANCES (res).create (10); + LOOP_VINFO_MAY_MISALIGN_STMTS (res) = vNULL; + LOOP_VINFO_MAY_ALIAS_DDRS (res) = vNULL; + LOOP_VINFO_GROUPED_STORES (res) = vNULL; + LOOP_VINFO_REDUCTIONS (res) = vNULL; + LOOP_VINFO_REDUCTION_CHAINS (res) = vNULL; + LOOP_VINFO_SLP_INSTANCES (res) = vNULL; LOOP_VINFO_SLP_UNROLLING_FACTOR (res) = 1; LOOP_VINFO_TARGET_COST_DATA (res) = init_cost (loop); LOOP_VINFO_PEELING_FOR_GAPS (res) = false; @@ -1036,9 +1033,6 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts) LOOP_VINFO_REDUCTIONS (loop_vinfo).release (); LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo).release (); - delete LOOP_VINFO_PEELING_HTAB (loop_vinfo); - LOOP_VINFO_PEELING_HTAB (loop_vinfo) = NULL; - destroy_cost_data (LOOP_VINFO_TARGET_COST_DATA (loop_vinfo)); loop_vinfo->scalar_cost_vec.release (); @@ -1786,7 +1780,6 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) int min_profitable_estimate, min_profitable_iters; vect_estimate_min_profitable_iters (loop_vinfo, &min_profitable_iters, &min_profitable_estimate); - LOOP_VINFO_COST_MODEL_MIN_ITERS (loop_vinfo) = min_profitable_iters; if (min_profitable_iters < 0) { @@ -2810,7 +2803,7 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo)) { /* FIXME: Make cost depend on complexity of individual check. */ - unsigned len = LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo).length (); + unsigned len = LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo).length (); (void) add_stmt_cost (target_cost_data, len, vector_stmt, NULL, 0, vect_prologue); dump_printf (MSG_NOTE, diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 11ffb64..7e6ac52 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -1569,6 +1569,10 @@ vect_analyze_slp_cost (slp_instance instance, void *data) stmt_info_for_cost *si; unsigned i; + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "=== vect_analyze_slp_cost ===\n"); + /* Calculate the number of vector stmts to create based on the unrolling factor (number of vectors is 1 if NUNITS >= GROUP_SIZE, and is GROUP_SIZE / NUNITS otherwise. */ diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 39f9272..ebe38b7 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -194,41 +194,6 @@ struct dr_with_seg_len_pair_t }; -typedef struct _vect_peel_info -{ - int npeel; - struct data_reference *dr; - unsigned int count; -} *vect_peel_info; - -typedef struct _vect_peel_extended_info -{ - struct _vect_peel_info peel_info; - unsigned int inside_cost; - unsigned int outside_cost; - stmt_vector_for_cost body_cost_vec; -} *vect_peel_extended_info; - - -/* Peeling hashtable helpers. */ - -struct peel_info_hasher : free_ptr_hash <_vect_peel_info> -{ - static inline hashval_t hash (const _vect_peel_info *); - static inline bool equal (const _vect_peel_info *, const _vect_peel_info *); -}; - -inline hashval_t -peel_info_hasher::hash (const _vect_peel_info *peel_info) -{ - return (hashval_t) peel_info->npeel; -} - -inline bool -peel_info_hasher::equal (const _vect_peel_info *a, const _vect_peel_info *b) -{ - return (a->npeel == b->npeel); -} /* Vectorizer state common between loop and basic-block vectorization. */ struct vec_info { @@ -289,13 +254,6 @@ typedef struct _loop_vec_info : public vec_info { /* Number of iterations of the original loop. */ tree num_iters_unchanged; - /* Minimum number of iterations below which vectorization is expected to - not be profitable (as estimated by the cost model). - -1 indicates that vectorization will not be profitable. - FORNOW: This field is an int. Will be a tree in the future, to represent - values unknown at compile time. */ - int min_profitable_iters; - /* Threshold of number of iterations below which vectorzation will not be performed. It is calculated from MIN_PROFITABLE_ITERS and PARAM_MIN_VECT_LOOP_BOUND. */ @@ -349,9 +307,6 @@ typedef struct _loop_vec_info : public vec_info { stmt in the chain. */ vec reduction_chains; - /* Hash table used to choose the best peeling option. */ - hash_table *peeling_htab; - /* Cost vector for a single scalar iteration. */ vec scalar_cost_vec; @@ -407,7 +362,6 @@ typedef struct _loop_vec_info : public vec_info { prologue peeling retain total unchanged scalar loop iterations for cost model. */ #define LOOP_VINFO_NITERS_UNCHANGED(L) (L)->num_iters_unchanged -#define LOOP_VINFO_COST_MODEL_MIN_ITERS(L) (L)->min_profitable_iters #define LOOP_VINFO_COST_MODEL_THRESHOLD(L) (L)->th #define LOOP_VINFO_VECTORIZABLE_P(L) (L)->vectorizable #define LOOP_VINFO_VECT_FACTOR(L) (L)->vectorization_factor @@ -426,7 +380,6 @@ typedef struct _loop_vec_info : public vec_info { #define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor #define LOOP_VINFO_REDUCTIONS(L) (L)->reductions #define LOOP_VINFO_REDUCTION_CHAINS(L) (L)->reduction_chains -#define LOOP_VINFO_PEELING_HTAB(L) (L)->peeling_htab #define LOOP_VINFO_TARGET_COST_DATA(L) (L)->target_cost_data #define LOOP_VINFO_PEELING_FOR_GAPS(L) (L)->peeling_for_gaps #define LOOP_VINFO_OPERANDS_SWAPPED(L) (L)->operands_swapped -- 2.7.4