* [PATCH] More vectorizer TLC
@ 2015-10-13 8:38 Richard Biener
0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2015-10-13 8:38 UTC (permalink / raw)
To: gcc-patches
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard.
2015-10-13 Richard Biener <rguenther@suse.de>
* 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.
Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c (revision 228709)
--- gcc/tree-vect-data-refs.c (working copy)
*************** vect_analyze_data_ref_dependences (loop_
*** 468,473 ****
--- 468,476 ----
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),
*************** vect_get_data_access_cost (struct data_r
*** 1039,1048 ****
}
/* 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,
int npeel)
{
struct _vect_peel_info elem, *slot;
--- 1042,1089 ----
}
+ 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 (hash_table<peel_info_hasher> *peeling_htab,
! loop_vec_info loop_vinfo, struct data_reference *dr,
int npeel)
{
struct _vect_peel_info elem, *slot;
*************** vect_peeling_hash_insert (loop_vec_info
*** 1050,1056 ****
bool supportable_dr_alignment = vect_supportable_dr_alignment (dr, true);
elem.npeel = npeel;
! slot = LOOP_VINFO_PEELING_HTAB (loop_vinfo)->find (&elem);
if (slot)
slot->count++;
else
--- 1091,1097 ----
bool supportable_dr_alignment = vect_supportable_dr_alignment (dr, true);
elem.npeel = npeel;
! slot = peeling_htab->find (&elem);
if (slot)
slot->count++;
else
*************** vect_peeling_hash_insert (loop_vec_info
*** 1059,1066 ****
slot->npeel = npeel;
slot->dr = dr;
slot->count = 1;
! new_slot
! = LOOP_VINFO_PEELING_HTAB (loop_vinfo)->find_slot (slot, INSERT);
*new_slot = slot;
}
--- 1100,1106 ----
slot->npeel = npeel;
slot->dr = dr;
slot->count = 1;
! new_slot = peeling_htab->find_slot (slot, INSERT);
*new_slot = slot;
}
*************** vect_peeling_hash_get_lowest_cost (_vect
*** 1164,1170 ****
option that aligns as many accesses as possible. */
static struct data_reference *
! vect_peeling_hash_choose_best_peeling (loop_vec_info loop_vinfo,
unsigned int *npeel,
stmt_vector_for_cost *body_cost_vec)
{
--- 1204,1211 ----
option that aligns as many accesses as possible. */
static struct data_reference *
! vect_peeling_hash_choose_best_peeling (hash_table<peel_info_hasher> *peeling_htab,
! loop_vec_info loop_vinfo,
unsigned int *npeel,
stmt_vector_for_cost *body_cost_vec)
{
*************** vect_peeling_hash_choose_best_peeling (l
*** 1177,1192 ****
{
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);
}
else
{
res.peel_info.count = 0;
! LOOP_VINFO_PEELING_HTAB (loop_vinfo)
! ->traverse <_vect_peel_extended_info *,
! vect_peeling_hash_get_most_frequent> (&res);
}
*npeel = res.peel_info.npeel;
--- 1218,1231 ----
{
res.inside_cost = INT_MAX;
res.outside_cost = INT_MAX;
! peeling_htab->traverse <_vect_peel_extended_info *,
! vect_peeling_hash_get_lowest_cost> (&res);
}
else
{
res.peel_info.count = 0;
! peeling_htab->traverse <_vect_peel_extended_info *,
! vect_peeling_hash_get_most_frequent> (&res);
}
*npeel = res.peel_info.npeel;
*************** vect_enhance_data_refs_alignment (loop_v
*** 1307,1312 ****
--- 1346,1352 ----
tree vectype;
unsigned int nelements, mis, same_align_drs_max = 0;
stmt_vector_for_cost body_cost_vec = stmt_vector_for_cost ();
+ hash_table<peel_info_hasher> peeling_htab (1);
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
*************** vect_enhance_data_refs_alignment (loop_v
*** 1379,1388 ****
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<peel_info_hasher> (1);
-
vectype = STMT_VINFO_VECTYPE (stmt_info);
nelements = TYPE_VECTOR_SUBPARTS (vectype);
mis = DR_MISALIGNMENT (dr) / GET_MODE_SIZE (TYPE_MODE (
--- 1419,1424 ----
*************** vect_enhance_data_refs_alignment (loop_v
*** 1424,1430 ****
for (j = 0; j < possible_npeel_number; j++)
{
! vect_peeling_hash_insert (loop_vinfo, dr, npeel_tmp);
npeel_tmp += nelements;
}
--- 1460,1467 ----
for (j = 0; j < possible_npeel_number; j++)
{
! vect_peeling_hash_insert (&peeling_htab, loop_vinfo,
! dr, npeel_tmp);
npeel_tmp += nelements;
}
*************** vect_enhance_data_refs_alignment (loop_v
*** 1590,1596 ****
gcc_assert (!all_misalignments_unknown);
/* Choose the best peeling from the hash table. */
! dr0 = vect_peeling_hash_choose_best_peeling (loop_vinfo, &npeel,
&body_cost_vec);
if (!dr0 || !npeel)
do_peeling = false;
--- 1627,1634 ----
gcc_assert (!all_misalignments_unknown);
/* Choose the best peeling from the hash table. */
! dr0 = vect_peeling_hash_choose_best_peeling (&peeling_htab,
! loop_vinfo, &npeel,
&body_cost_vec);
if (!dr0 || !npeel)
do_peeling = false;
Index: gcc/tree-vect-loop.c
===================================================================
*** gcc/tree-vect-loop.c (revision 228709)
--- gcc/tree-vect-loop.c (working copy)
*************** new_loop_vec_info (struct loop *loop)
*** 937,959 ****
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_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_SLP_UNROLLING_FACTOR (res) = 1;
LOOP_VINFO_TARGET_COST_DATA (res) = init_cost (loop);
LOOP_VINFO_PEELING_FOR_GAPS (res) = false;
--- 937,956 ----
LOOP_VINFO_NITERSM1 (res) = NULL;
LOOP_VINFO_NITERS (res) = NULL;
LOOP_VINFO_NITERS_UNCHANGED (res) = NULL;
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) = vNULL;
! LOOP_VINFO_DATAREFS (res) = vNULL;
! LOOP_VINFO_DDRS (res) = vNULL;
LOOP_VINFO_UNALIGNED_DR (res) = NULL;
! 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;
*************** destroy_loop_vec_info (loop_vec_info loo
*** 1036,1044 ****
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 ();
--- 1033,1038 ----
*************** vect_analyze_loop_2 (loop_vec_info loop_
*** 1786,1792 ****
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)
{
--- 1780,1785 ----
*************** vect_estimate_min_profitable_iters (loop
*** 2810,2816 ****
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 ();
(void) add_stmt_cost (target_cost_data, len, vector_stmt, NULL, 0,
vect_prologue);
dump_printf (MSG_NOTE,
--- 2803,2809 ----
if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
{
/* FIXME: Make cost depend on complexity of individual check. */
! 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,
Index: gcc/tree-vect-slp.c
===================================================================
*** gcc/tree-vect-slp.c (revision 228709)
--- gcc/tree-vect-slp.c (working copy)
*************** vect_analyze_slp_cost (slp_instance inst
*** 1569,1574 ****
--- 1569,1578 ----
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. */
Index: gcc/tree-vectorizer.h
===================================================================
*** gcc/tree-vectorizer.h (revision 228709)
--- gcc/tree-vectorizer.h (working copy)
*************** struct dr_with_seg_len_pair_t
*** 194,234 ****
};
- 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 {
--- 194,199 ----
*************** typedef struct _loop_vec_info : public v
*** 289,301 ****
/* 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. */
--- 254,259 ----
*************** typedef struct _loop_vec_info : public v
*** 349,357 ****
stmt in the chain. */
vec<gimple *> reduction_chains;
- /* Hash table used to choose the best peeling option. */
- hash_table<peel_info_hasher> *peeling_htab;
-
/* Cost vector for a single scalar iteration. */
vec<stmt_info_for_cost> scalar_cost_vec;
--- 307,312 ----
*************** typedef struct _loop_vec_info : public v
*** 407,413 ****
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
--- 362,367 ----
*************** typedef struct _loop_vec_info : public v
*** 426,432 ****
#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
--- 380,385 ----
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] More vectorizer TLC
2015-10-15 11:37 Richard Biener
@ 2015-10-15 12:15 ` Richard Biener
0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2015-10-15 12:15 UTC (permalink / raw)
To: gcc-patches
On Thu, 15 Oct 2015, Richard Biener wrote:
>
> Get rid of some of the ancient way of building stmts and SSA names.
>
> Bootstrapped & tested on x86_64-unknown-linux-gnu, applied.
Committed an old patch, fixed now.
2015-10-15 Richard Biener <rguenther@suse.de>
* tree-vect-stmts.c (vect_init_vector): Remove unused vars.
Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c (revision 228841)
+++ gcc/tree-vect-stmts.c (working copy)
@@ -1296,9 +1296,7 @@ vect_init_vector_1 (gimple *stmt, gimple
tree
vect_init_vector (gimple *stmt, tree val, tree type, gimple_stmt_iterator
*gsi)
{
- tree new_var;
gimple *init_stmt;
- tree vec_oprnd;
tree new_temp;
if (TREE_CODE (type) == VECTOR_TYPE
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] More vectorizer TLC
@ 2015-10-15 11:37 Richard Biener
2015-10-15 12:15 ` Richard Biener
0 siblings, 1 reply; 8+ messages in thread
From: Richard Biener @ 2015-10-15 11:37 UTC (permalink / raw)
To: gcc-patches
Get rid of some of the ancient way of building stmts and SSA names.
Bootstrapped & tested on x86_64-unknown-linux-gnu, applied.
Richard.
2015-10-15 Richard Biener <rguenther@suse.de>
* tree-vectorizer.h (vect_get_new_ssa_name): Declare.
* tree-vect-data-refs.c (vect_get_new_ssa_name): New helper.
* tree-vect-loop.c (get_initial_def_for_induction): Drop
use of force_gimple_operand in favor of gimple_build.
Use vect_get_new_ssa_name.
* tree-vect-stmts.c (vect_init_vector): Use vect_get_new_ssa_name.
(vectorizable_mask_load_store): Likewise.
(vectorizable_call): Likewise.
(vectorizable_store): Likewise.
(vectorizable_load): Likewise.
(vect_get_vec_def_for_stmt_copy): Remove redundant stmt.
Index: gcc/tree-vect-data-refs.c
===================================================================
--- gcc/tree-vect-data-refs.c (revision 228811)
+++ gcc/tree-vect-data-refs.c (working copy)
@@ -3896,6 +3937,41 @@ vect_get_new_vect_var (tree type, enum v
return new_vect_var;
}
+
+/* Like vect_get_new_vect_var but return an SSA name. */
+
+tree
+vect_get_new_ssa_name (tree type, enum vect_var_kind var_kind, const char *name)
+{
+ const char *prefix;
+ tree new_vect_var;
+
+ switch (var_kind)
+ {
+ case vect_simple_var:
+ prefix = "vect";
+ break;
+ case vect_scalar_var:
+ prefix = "stmp";
+ break;
+ case vect_pointer_var:
+ prefix = "vectp";
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (name)
+ {
+ char* tmp = concat (prefix, "_", name, NULL);
+ new_vect_var = make_temp_ssa_name (type, NULL, tmp);
+ free (tmp);
+ }
+ else
+ new_vect_var = make_temp_ssa_name (type, NULL, prefix);
+
+ return new_vect_var;
+}
/* Duplicate ptr info and set alignment/misaligment on NAME from DR. */
Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c (revision 228811)
+++ gcc/tree-vect-loop.c (working copy)
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.
#include "tree-scalar-evolution.h"
#include "tree-vectorizer.h"
#include "target.h"
+#include "gimple-fold.h"
/* Loop Vectorization Pass.
@@ -3341,9 +3388,8 @@ get_initial_def_for_induction (gimple *i
struct loop *iv_loop;
basic_block new_bb;
tree new_vec, vec_init, vec_step, t;
- tree new_var;
tree new_name;
- gimple *init_stmt, *new_stmt;
+ gimple *new_stmt;
gphi *induction_phi;
tree induc_def, vec_def, vec_dest;
tree init_expr, step_expr;
@@ -3353,7 +3399,7 @@ get_initial_def_for_induction (gimple *i
tree expr;
stmt_vec_info phi_info = vinfo_for_stmt (iv_phi);
bool nested_in_vect_loop = false;
- gimple_seq stmts = NULL;
+ gimple_seq stmts;
imm_use_iterator imm_iter;
use_operand_p use_p;
gimple *exit_phi;
@@ -3394,9 +3440,8 @@ get_initial_def_for_induction (gimple *i
gcc_assert (ncopies >= 1);
/* Convert the step to the desired type. */
- step_expr = force_gimple_operand (fold_convert (TREE_TYPE (vectype),
- step_expr),
- &stmts, true, NULL_TREE);
+ stmts = NULL;
+ step_expr = gimple_convert (&stmts, TREE_TYPE (vectype), step_expr);
if (stmts)
{
new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
@@ -3417,14 +3462,13 @@ get_initial_def_for_induction (gimple *i
if (!useless_type_conversion_p (vectype, TREE_TYPE (vec_init)))
{
new_stmt
- = gimple_build_assign (vect_get_new_vect_var (vectype,
+ = gimple_build_assign (vect_get_new_ssa_name (vectype,
vect_simple_var,
"vec_iv_"),
VIEW_CONVERT_EXPR,
build1 (VIEW_CONVERT_EXPR, vectype,
vec_init));
- vec_init = make_ssa_name (gimple_assign_lhs (new_stmt), new_stmt);
- gimple_assign_set_lhs (new_stmt, vec_init);
+ vec_init = gimple_assign_lhs (new_stmt);
new_bb = gsi_insert_on_edge_immediate (loop_preheader_edge (iv_loop),
new_stmt);
gcc_assert (!new_bb);
@@ -3438,16 +3482,8 @@ get_initial_def_for_induction (gimple *i
/* iv_loop is the loop to be vectorized. Create:
vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr) */
- new_var = vect_get_new_vect_var (TREE_TYPE (vectype),
- vect_scalar_var, "var_");
- new_name = force_gimple_operand (fold_convert (TREE_TYPE (vectype),
- init_expr),
- &stmts, false, new_var);
- if (stmts)
- {
- new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
- gcc_assert (!new_bb);
- }
+ stmts = NULL;
+ new_name = gimple_convert (&stmts, TREE_TYPE (vectype), init_expr);
vec_alloc (v, nunits);
bool constant_p = is_gimple_min_invariant (new_name);
@@ -3455,26 +3491,18 @@ get_initial_def_for_induction (gimple *i
for (i = 1; i < nunits; i++)
{
/* Create: new_name_i = new_name + step_expr */
- new_name = fold_build2 (PLUS_EXPR, TREE_TYPE (new_name),
- new_name, step_expr);
+ new_name = gimple_build (&stmts, PLUS_EXPR, TREE_TYPE (new_name),
+ new_name, step_expr);
if (!is_gimple_min_invariant (new_name))
- {
- init_stmt = gimple_build_assign (new_var, new_name);
- new_name = make_ssa_name (new_var, init_stmt);
- gimple_assign_set_lhs (init_stmt, new_name);
- new_bb = gsi_insert_on_edge_immediate (pe, init_stmt);
- gcc_assert (!new_bb);
- if (dump_enabled_p ())
- {
- dump_printf_loc (MSG_NOTE, vect_location,
- "created new init_stmt: ");
- dump_gimple_stmt (MSG_NOTE, TDF_SLIM, init_stmt, 0);
- dump_printf (MSG_NOTE, "\n");
- }
- constant_p = false;
- }
+ constant_p = false;
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, new_name);
}
+ if (stmts)
+ {
+ new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
+ gcc_assert (!new_bb);
+ }
+
/* Create a vector from [new_name_0, new_name_1, ..., new_name_nunits-1] */
if (constant_p)
new_vec = build_vector_from_ctor (vectype, v);
Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c (revision 228811)
+++ gcc/tree-vect-stmts.c (working copy)
@@ -1319,13 +1319,10 @@ vect_init_vector (gimple *stmt, tree val
val = build_vector_from_val (type, val);
}
- new_var = vect_get_new_vect_var (type, vect_simple_var, "cst_");
- init_stmt = gimple_build_assign (new_var, val);
- new_temp = make_ssa_name (new_var, init_stmt);
- gimple_assign_set_lhs (init_stmt, new_temp);
+ new_temp = vect_get_new_ssa_name (type, vect_simple_var, "cst_");
+ init_stmt = gimple_build_assign (new_temp, val);
vect_init_vector_1 (stmt, init_stmt, gsi);
- vec_oprnd = gimple_assign_lhs (init_stmt);
- return vec_oprnd;
+ return new_temp;
}
@@ -1509,7 +1506,6 @@ vect_get_vec_def_for_stmt_copy (enum vec
gcc_assert (def_stmt_info);
vec_stmt_for_operand = STMT_VINFO_RELATED_STMT (def_stmt_info);
gcc_assert (vec_stmt_for_operand);
- vec_oprnd = gimple_get_lhs (vec_stmt_for_operand);
if (gimple_code (vec_stmt_for_operand) == GIMPLE_PHI)
vec_oprnd = PHI_RESULT (vec_stmt_for_operand);
else
@@ -1888,8 +1884,7 @@ vectorizable_mask_load_store (gimple *st
{
gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op))
== TYPE_VECTOR_SUBPARTS (idxtype));
- var = vect_get_new_vect_var (idxtype, vect_simple_var, NULL);
- var = make_ssa_name (var);
+ var = vect_get_new_ssa_name (idxtype, vect_simple_var);
op = build1 (VIEW_CONVERT_EXPR, idxtype, op);
new_stmt
= gimple_build_assign (var, VIEW_CONVERT_EXPR, op);
@@ -1915,9 +1910,7 @@ vectorizable_mask_load_store (gimple *st
{
gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask_op))
== TYPE_VECTOR_SUBPARTS (masktype));
- var = vect_get_new_vect_var (masktype, vect_simple_var,
- NULL);
- var = make_ssa_name (var);
+ var = vect_get_new_ssa_name (masktype, vect_simple_var);
mask_op = build1 (VIEW_CONVERT_EXPR, masktype, mask_op);
new_stmt
= gimple_build_assign (var, VIEW_CONVERT_EXPR, mask_op);
@@ -1934,8 +1927,7 @@ vectorizable_mask_load_store (gimple *st
{
gcc_assert (TYPE_VECTOR_SUBPARTS (vectype)
== TYPE_VECTOR_SUBPARTS (rettype));
- var = vect_get_new_vect_var (rettype, vect_simple_var, NULL);
- op = make_ssa_name (var, new_stmt);
+ op = vect_get_new_ssa_name (rettype, vect_simple_var);
gimple_call_set_lhs (new_stmt, op);
vect_finish_stmt_generation (stmt, new_stmt, gsi);
var = make_ssa_name (vec_dest);
@@ -2379,14 +2371,11 @@ vectorizable_call (gimple *gs, gimple_st
v[k] = build_int_cst (unsigned_type_node, j * nunits_out + k);
tree cst = build_vector (vectype_out, v);
tree new_var
- = vect_get_new_vect_var (vectype_out, vect_simple_var, "cst_");
+ = vect_get_new_ssa_name (vectype_out, vect_simple_var, "cst_");
gimple *init_stmt = gimple_build_assign (new_var, cst);
- new_temp = make_ssa_name (new_var, init_stmt);
- gimple_assign_set_lhs (init_stmt, new_temp);
vect_init_vector_1 (stmt, init_stmt, NULL);
new_temp = make_ssa_name (vec_dest);
- new_stmt = gimple_build_assign (new_temp,
- gimple_assign_lhs (init_stmt));
+ new_stmt = gimple_build_assign (new_temp, new_var);
}
else
{
@@ -5350,8 +5400,7 @@ vectorizable_store (gimple *stmt, gimple
{
gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (src))
== TYPE_VECTOR_SUBPARTS (srctype));
- var = vect_get_new_vect_var (srctype, vect_simple_var, NULL);
- var = make_ssa_name (var);
+ var = vect_get_new_ssa_name (srctype, vect_simple_var);
src = build1 (VIEW_CONVERT_EXPR, srctype, src);
new_stmt = gimple_build_assign (var, VIEW_CONVERT_EXPR, src);
vect_finish_stmt_generation (stmt, new_stmt, gsi);
@@ -5362,8 +5411,7 @@ vectorizable_store (gimple *stmt, gimple
{
gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op))
== TYPE_VECTOR_SUBPARTS (idxtype));
- var = vect_get_new_vect_var (idxtype, vect_simple_var, NULL);
- var = make_ssa_name (var);
+ var = vect_get_new_ssa_name (idxtype, vect_simple_var);
op = build1 (VIEW_CONVERT_EXPR, idxtype, op);
new_stmt = gimple_build_assign (var, VIEW_CONVERT_EXPR, op);
vect_finish_stmt_generation (stmt, new_stmt, gsi);
@@ -6408,8 +6456,7 @@ vectorizable_load (gimple *stmt, gimple_
{
gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op))
== TYPE_VECTOR_SUBPARTS (idxtype));
- var = vect_get_new_vect_var (idxtype, vect_simple_var, NULL);
- var = make_ssa_name (var);
+ var = vect_get_new_ssa_name (idxtype, vect_simple_var);
op = build1 (VIEW_CONVERT_EXPR, idxtype, op);
new_stmt
= gimple_build_assign (var, VIEW_CONVERT_EXPR, op);
@@ -6424,8 +6471,7 @@ vectorizable_load (gimple *stmt, gimple_
{
gcc_assert (TYPE_VECTOR_SUBPARTS (vectype)
== TYPE_VECTOR_SUBPARTS (rettype));
- var = vect_get_new_vect_var (rettype, vect_simple_var, NULL);
- op = make_ssa_name (var, new_stmt);
+ op = vect_get_new_ssa_name (rettype, vect_simple_var);
gimple_call_set_lhs (new_stmt, op);
vect_finish_stmt_generation (stmt, new_stmt, gsi);
var = make_ssa_name (vec_dest);
Index: gcc/tree-vectorizer.h
===================================================================
--- gcc/tree-vectorizer.h (revision 228811)
+++ gcc/tree-vectorizer.h (working copy)
@@ -1020,6 +1020,8 @@ extern void vect_transform_grouped_load
gimple_stmt_iterator *);
extern void vect_record_grouped_load_vectors (gimple *, vec<tree> );
extern tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *);
+extern tree vect_get_new_ssa_name (tree, enum vect_var_kind,
+ const char * = NULL);
extern tree vect_create_addr_base_for_vector_ref (gimple *, gimple_seq *,
tree, struct loop *,
tree = NULL_TREE);
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] More vectorizer TLC
@ 2015-10-14 13:56 Richard Biener
0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2015-10-14 13:56 UTC (permalink / raw)
To: gcc-patches
This removes superfluous parameters from some analysis helpers.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard.
2015-10-14 Richard Biener <rguenther@suse.de>
* tree-vectorizer.h (vect_is_simple_use): Remove unused parameters.
(vect_is_simple_use_1): Likewise. Make overload of vect_is_simple_use.
(vect_get_vec_def_for_operand): Remove unused parameter.
* tree-vect-loop.c (get_initial_def_for_induction): Adjust.
(vect_create_epilog_for_reduction): Likewise.
(vectorizable_reduction): Likewise.
(vectorizable_live_operation): Likewise.
* tree-vect-patterns.c (type_conversion_p): Likewise.
(vect_recog_vector_vector_shift_pattern): Likewise.
(check_bool_pattern): Likewise.
* tree-vect-slp.c (vect_get_and_check_slp_defs): Likewise.
(vect_analyze_slp_cost_1): Likewise.
* tree-vect-stmts.c (process_use): Likewise.
(vect_get_vec_def_for_operand): Do not handle reductions.
(vect_get_vec_defs): Adjust.
(vectorizable_mask_load_store): Likewise.
(vectorizable_call): Likewise.
(vectorizable_simd_clone_call): Likewise.
(vect_get_loop_based_defs): Likewise.
(vectorizable_conversion): Likewise.
(vectorizable_assignment): Likewise.
(vectorizable_shift): Likewise.
(vectorizable_operation): Likewise.
(vectorizable_store): Likewise.
(vectorizable_load): Likewise.
(vect_is_simple_cond): Likewise.
(vectorizable_condition): Likewise.
(vect_is_simple_use): Remove unused parameters.
(vect_is_simple_use_1): Adjust and rename.
Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c (revision 228806)
+++ gcc/tree-vect-loop.c (working copy)
@@ -3412,7 +3412,7 @@ get_initial_def_for_induction (gimple *i
/* iv_loop is nested in the loop to be vectorized. init_expr had already
been created during vectorization of previous stmts. We obtain it
from the STMT_VINFO_VEC_STMT of the defining stmt. */
- vec_init = vect_get_vec_def_for_operand (init_expr, iv_phi, NULL);
+ vec_init = vect_get_vec_def_for_operand (init_expr, iv_phi);
/* If the initial value is not of proper type, convert it. */
if (!useless_type_conversion_p (vectype, TREE_TYPE (vec_init)))
{
@@ -3798,8 +3798,7 @@ get_initial_def_for_reduction (gimple *s
if (adjustment_def)
{
if (nested_in_vect_loop)
- *adjustment_def = vect_get_vec_def_for_operand (init_val, stmt,
- NULL);
+ *adjustment_def = vect_get_vec_def_for_operand (init_val, stmt);
else
*adjustment_def = init_val;
}
@@ -3853,7 +3852,7 @@ get_initial_def_for_reduction (gimple *s
if (adjustment_def)
{
*adjustment_def = NULL_TREE;
- init_def = vect_get_vec_def_for_operand (init_val, stmt, NULL);
+ init_def = vect_get_vec_def_for_operand (init_val, stmt);
break;
}
@@ -4012,12 +4011,13 @@ vect_create_epilog_for_reduction (vec<tr
NULL, slp_node, reduc_index);
else
{
+ /* Get at the scalar def before the loop, that defines the initial value
+ of the reduction variable. */
+ gimple *def_stmt = SSA_NAME_DEF_STMT (reduction_op);
+ tree op = PHI_ARG_DEF_FROM_EDGE (def_stmt, loop_preheader_edge (loop));
vec_initial_defs.create (1);
- /* For the case of reduction, vect_get_vec_def_for_operand returns
- the scalar def before the loop, that defines the initial value
- of the reduction variable. */
- vec_initial_def = vect_get_vec_def_for_operand (reduction_op, stmt,
- &adjustment_def);
+ vec_initial_def = get_initial_def_for_reduction (stmt, op,
+ &adjustment_def);
vec_initial_defs.quick_push (vec_initial_def);
}
@@ -4800,7 +4800,6 @@ vectorizable_reduction (gimple *stmt, gi
int op_type;
optab optab, reduc_optab;
tree new_temp = NULL_TREE;
- tree def;
gimple *def_stmt;
enum vect_def_type dt;
gphi *new_phi = NULL;
@@ -4956,8 +4955,8 @@ vectorizable_reduction (gimple *stmt, gi
if (i == 0 && code == COND_EXPR)
continue;
- is_simple_use = vect_is_simple_use_1 (ops[i], stmt, loop_vinfo,
- &def_stmt, &def, &dt, &tem);
+ is_simple_use = vect_is_simple_use (ops[i], loop_vinfo,
+ &def_stmt, &dt, &tem);
if (!vectype_in)
vectype_in = tem;
gcc_assert (is_simple_use);
@@ -4977,8 +4976,7 @@ vectorizable_reduction (gimple *stmt, gi
}
}
- is_simple_use = vect_is_simple_use_1 (ops[i], stmt, loop_vinfo,
- &def_stmt, &def, &dt, &tem);
+ is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, &def_stmt, &dt, &tem);
if (!vectype_in)
vectype_in = tem;
gcc_assert (is_simple_use);
@@ -5340,12 +5338,11 @@ vectorizable_reduction (gimple *stmt, gi
else
{
loop_vec_def0 = vect_get_vec_def_for_operand (ops[!reduc_index],
- stmt, NULL);
+ stmt);
vec_oprnds0.quick_push (loop_vec_def0);
if (op_type == ternary_op)
{
- loop_vec_def1 = vect_get_vec_def_for_operand (op1, stmt,
- NULL);
+ loop_vec_def1 = vect_get_vec_def_for_operand (op1, stmt);
vec_oprnds1.quick_push (loop_vec_def1);
}
}
@@ -5356,17 +5353,15 @@ vectorizable_reduction (gimple *stmt, gi
{
enum vect_def_type dt;
gimple *dummy_stmt;
- tree dummy;
- vect_is_simple_use (ops[!reduc_index], stmt, loop_vinfo,
- &dummy_stmt, &dummy, &dt);
+ vect_is_simple_use (ops[!reduc_index], loop_vinfo,
+ &dummy_stmt, &dt);
loop_vec_def0 = vect_get_vec_def_for_stmt_copy (dt,
loop_vec_def0);
vec_oprnds0[0] = loop_vec_def0;
if (op_type == ternary_op)
{
- vect_is_simple_use (op1, stmt, loop_vinfo, &dummy_stmt,
- &dummy, &dt);
+ vect_is_simple_use (op1, loop_vinfo, &dummy_stmt, &dt);
loop_vec_def1 = vect_get_vec_def_for_stmt_copy (dt,
loop_vec_def1);
vec_oprnds1[0] = loop_vec_def1;
@@ -5595,7 +5590,6 @@ vectorizable_live_operation (gimple *stm
int i;
int op_type;
tree op;
- tree def;
gimple *def_stmt;
enum vect_def_type dt;
enum tree_code code;
@@ -5667,7 +5661,7 @@ vectorizable_live_operation (gimple *stm
else
op = gimple_op (stmt, i + 1);
if (op
- && !vect_is_simple_use (op, stmt, loop_vinfo, &def_stmt, &def, &dt))
+ && !vect_is_simple_use (op, loop_vinfo, &def_stmt, &dt))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
Index: gcc/tree-vect-patterns.c
===================================================================
--- gcc/tree-vect-patterns.c (revision 228806)
+++ gcc/tree-vect-patterns.c (working copy)
@@ -169,17 +169,14 @@ static bool
type_conversion_p (tree name, gimple *use_stmt, bool check_sign,
tree *orig_type, gimple **def_stmt, bool *promotion)
{
- tree dummy;
gimple *dummy_gimple;
stmt_vec_info stmt_vinfo;
tree type = TREE_TYPE (name);
tree oprnd0;
enum vect_def_type dt;
- tree def;
stmt_vinfo = vinfo_for_stmt (use_stmt);
- if (!vect_is_simple_use (name, use_stmt, stmt_vinfo->vinfo, def_stmt,
- &def, &dt))
+ if (!vect_is_simple_use (name, stmt_vinfo->vinfo, def_stmt, &dt))
return false;
if (dt != vect_internal_def
@@ -207,8 +204,7 @@ type_conversion_p (tree name, gimple *us
else
*promotion = false;
- if (!vect_is_simple_use (oprnd0, *def_stmt, stmt_vinfo->vinfo,
- &dummy_gimple, &dummy, &dt))
+ if (!vect_is_simple_use (oprnd0, stmt_vinfo->vinfo, &dummy_gimple, &dt))
return false;
return true;
@@ -1830,7 +1826,7 @@ vect_recog_rotate_pattern (vec<gimple *>
|| !TYPE_UNSIGNED (type))
return NULL;
- if (!vect_is_simple_use (oprnd1, last_stmt, vinfo, &def_stmt, &def, &dt))
+ if (!vect_is_simple_use (oprnd1, vinfo, &def_stmt, &dt))
return NULL;
if (dt != vect_internal_def
@@ -2058,7 +2054,6 @@ vect_recog_vector_vector_shift_pattern (
stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
vec_info *vinfo = stmt_vinfo->vinfo;
enum vect_def_type dt;
- tree def;
if (!is_gimple_assign (last_stmt))
return NULL;
@@ -2090,8 +2085,7 @@ vect_recog_vector_vector_shift_pattern (
!= TYPE_PRECISION (TREE_TYPE (oprnd0)))
return NULL;
- if (!vect_is_simple_use (oprnd1, last_stmt, vinfo, &def_stmt,
- &def, &dt))
+ if (!vect_is_simple_use (oprnd1, vinfo, &def_stmt, &dt))
return NULL;
if (dt != vect_internal_def)
@@ -2102,7 +2096,7 @@ vect_recog_vector_vector_shift_pattern (
if (*type_in == NULL_TREE)
return NULL;
- def = NULL_TREE;
+ tree def = NULL_TREE;
if (gimple_assign_cast_p (def_stmt))
{
tree rhs1 = gimple_assign_rhs1 (def_stmt);
@@ -2892,11 +2886,10 @@ check_bool_pattern (tree var, vec_info *
{
gimple *def_stmt;
enum vect_def_type dt;
- tree def, rhs1;
+ tree rhs1;
enum tree_code rhs_code;
- if (!vect_is_simple_use (var, NULL, vinfo, &def_stmt, &def,
- &dt))
+ if (!vect_is_simple_use (var, vinfo, &def_stmt, &dt))
return false;
if (dt != vect_internal_def)
@@ -2905,7 +2898,7 @@ check_bool_pattern (tree var, vec_info *
if (!is_gimple_assign (def_stmt))
return false;
- if (!has_single_use (def))
+ if (!has_single_use (var))
return false;
rhs1 = gimple_assign_rhs1 (def_stmt);
Index: gcc/tree-vect-slp.c
===================================================================
--- gcc/tree-vect-slp.c (revision 228806)
+++ gcc/tree-vect-slp.c (working copy)
@@ -234,7 +234,6 @@ vect_get_and_check_slp_defs (vec_info *v
{
tree oprnd;
unsigned int i, number_of_oprnds;
- tree def;
gimple *def_stmt;
enum vect_def_type dt = vect_uninitialized_def;
struct loop *loop = NULL;
@@ -287,8 +286,7 @@ again:
oprnd_info = (*oprnds_info)[i];
- if (!vect_is_simple_use (oprnd, NULL, vinfo, &def_stmt,
- &def, &dt))
+ if (!vect_is_simple_use (oprnd, vinfo, &def_stmt, &dt))
{
if (dump_enabled_p ())
{
@@ -355,19 +353,15 @@ again:
switch (gimple_code (def_stmt))
{
- case GIMPLE_PHI:
- def = gimple_phi_result (def_stmt);
- break;
-
- case GIMPLE_ASSIGN:
- def = gimple_assign_lhs (def_stmt);
- break;
-
- default:
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "unsupported defining stmt:\n");
- return -1;
+ case GIMPLE_PHI:
+ case GIMPLE_ASSIGN:
+ break;
+
+ default:
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "unsupported defining stmt:\n");
+ return -1;
}
}
@@ -432,7 +426,7 @@ again:
{
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"Build SLP failed: illegal type of def ");
- dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, def);
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, oprnd);
dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
}
@@ -1555,12 +1549,12 @@ vect_analyze_slp_cost_1 (slp_instance in
lhs = gimple_get_lhs (stmt);
for (i = 0; i < gimple_num_ops (stmt); ++i)
{
- tree def, op = gimple_op (stmt, i);
+ tree op = gimple_op (stmt, i);
gimple *def_stmt;
enum vect_def_type dt;
if (!op || op == lhs)
continue;
- if (vect_is_simple_use (op, NULL, stmt_info->vinfo, &def_stmt, &def, &dt))
+ if (vect_is_simple_use (op, stmt_info->vinfo, &def_stmt, &dt))
{
/* Without looking at the actual initializer a vector of
constants can be implemented as load from the constant pool.
Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c (revision 228806)
+++ gcc/tree-vect-stmts.c (working copy)
@@ -450,7 +450,6 @@ process_use (gimple *stmt, tree use, loo
stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
stmt_vec_info dstmt_vinfo;
basic_block bb, def_bb;
- tree def;
gimple *def_stmt;
enum vect_def_type dt;
@@ -459,7 +458,7 @@ process_use (gimple *stmt, tree use, loo
if (!force && !exist_non_indexing_operands_for_use_p (use, stmt))
return true;
- if (!vect_is_simple_use (use, stmt, loop_vinfo, &def_stmt, &def, &dt))
+ if (!vect_is_simple_use (use, loop_vinfo, &def_stmt, &dt))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -1342,16 +1341,14 @@ vect_init_vector (gimple *stmt, tree val
needs to be introduced. */
tree
-vect_get_vec_def_for_operand (tree op, gimple *stmt, tree *scalar_def)
+vect_get_vec_def_for_operand (tree op, gimple *stmt)
{
tree vec_oprnd;
gimple *vec_stmt;
gimple *def_stmt;
stmt_vec_info def_stmt_info = NULL;
stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
- unsigned int nunits;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
- tree def;
enum vect_def_type dt;
bool is_simple_use;
tree vector_type;
@@ -1364,19 +1361,11 @@ vect_get_vec_def_for_operand (tree op, g
dump_printf (MSG_NOTE, "\n");
}
- is_simple_use = vect_is_simple_use (op, stmt, loop_vinfo,
- &def_stmt, &def, &dt);
+ is_simple_use = vect_is_simple_use (op, loop_vinfo, &def_stmt, &dt);
gcc_assert (is_simple_use);
if (dump_enabled_p ())
{
int loc_printed = 0;
- if (def)
- {
- dump_printf_loc (MSG_NOTE, vect_location, "def = ");
- loc_printed = 1;
- dump_generic_expr (MSG_NOTE, TDF_SLIM, def);
- dump_printf (MSG_NOTE, "\n");
- }
if (def_stmt)
{
if (loc_printed)
@@ -1389,46 +1378,18 @@ vect_get_vec_def_for_operand (tree op, g
switch (dt)
{
- /* Case 1: operand is a constant. */
+ /* operand is a constant or a loop invariant. */
case vect_constant_def:
+ case vect_external_def:
{
vector_type = get_vectype_for_scalar_type (TREE_TYPE (op));
gcc_assert (vector_type);
- nunits = TYPE_VECTOR_SUBPARTS (vector_type);
-
- if (scalar_def)
- *scalar_def = op;
-
- /* Create 'vect_cst_ = {cst,cst,...,cst}' */
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "Create vector_cst. nunits = %d\n", nunits);
-
return vect_init_vector (stmt, op, vector_type, NULL);
}
- /* Case 2: operand is defined outside the loop - loop invariant. */
- case vect_external_def:
- {
- vector_type = get_vectype_for_scalar_type (TREE_TYPE (def));
- gcc_assert (vector_type);
-
- if (scalar_def)
- *scalar_def = def;
-
- /* Create 'vec_inv = {inv,inv,..,inv}' */
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location, "Create vector_inv.\n");
-
- return vect_init_vector (stmt, def, vector_type, NULL);
- }
-
- /* Case 3: operand is defined inside the loop. */
+ /* operand is defined inside the loop. */
case vect_internal_def:
{
- if (scalar_def)
- *scalar_def = NULL/* FIXME tuples: def_stmt*/;
-
/* Get the def from the vectorized stmt. */
def_stmt_info = vinfo_for_stmt (def_stmt);
@@ -1449,22 +1410,14 @@ vect_get_vec_def_for_operand (tree op, g
return vec_oprnd;
}
- /* Case 4: operand is defined by a loop header phi - reduction */
+ /* operand is defined by a loop header phi - reduction */
case vect_reduction_def:
case vect_double_reduction_def:
case vect_nested_cycle:
- {
- struct loop *loop;
-
- gcc_assert (gimple_code (def_stmt) == GIMPLE_PHI);
- loop = (gimple_bb (def_stmt))->loop_father;
-
- /* Get the def before the loop */
- op = PHI_ARG_DEF_FROM_EDGE (def_stmt, loop_preheader_edge (loop));
- return get_initial_def_for_reduction (stmt, op, scalar_def);
- }
+ /* Code should use get_initial_def_for_reduction. */
+ gcc_unreachable ();
- /* Case 5: operand is defined by loop-header phi - induction. */
+ /* operand is defined by loop-header phi - induction. */
case vect_induction_def:
{
gcc_assert (gimple_code (def_stmt) == GIMPLE_PHI);
@@ -1618,13 +1571,13 @@ vect_get_vec_defs (tree op0, tree op1, g
tree vec_oprnd;
vec_oprnds0->create (1);
- vec_oprnd = vect_get_vec_def_for_operand (op0, stmt, NULL);
+ vec_oprnd = vect_get_vec_def_for_operand (op0, stmt);
vec_oprnds0->quick_push (vec_oprnd);
if (op1)
{
vec_oprnds1->create (1);
- vec_oprnd = vect_get_vec_def_for_operand (op1, stmt, NULL);
+ vec_oprnd = vect_get_vec_def_for_operand (op1, stmt);
vec_oprnds1->quick_push (vec_oprnd);
}
}
@@ -1753,7 +1706,6 @@ vectorizable_mask_load_store (gimple *st
bool is_store;
tree mask;
gimple *def_stmt;
- tree def;
enum vect_def_type dt;
if (slp_node != NULL)
@@ -1797,13 +1749,11 @@ vectorizable_mask_load_store (gimple *st
if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
{
gimple *def_stmt;
- tree def;
gather_decl = vect_check_gather_scatter (stmt, loop_vinfo, &gather_base,
&gather_off, &gather_scale);
gcc_assert (gather_decl);
- if (!vect_is_simple_use_1 (gather_off, NULL, loop_vinfo,
- &def_stmt, &def, &gather_dt,
- &gather_off_vectype))
+ if (!vect_is_simple_use (gather_off, loop_vinfo, &def_stmt, &gather_dt,
+ &gather_off_vectype))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -1833,15 +1783,13 @@ vectorizable_mask_load_store (gimple *st
if (TREE_CODE (mask) != SSA_NAME)
return false;
- if (!vect_is_simple_use (mask, stmt, loop_vinfo,
- &def_stmt, &def, &dt))
+ if (!vect_is_simple_use (mask, loop_vinfo, &def_stmt, &dt))
return false;
if (is_store)
{
tree rhs = gimple_call_arg (stmt, 3);
- if (!vect_is_simple_use (rhs, stmt, loop_vinfo,
- &def_stmt, &def, &dt))
+ if (!vect_is_simple_use (rhs, loop_vinfo, &def_stmt, &dt))
return false;
}
@@ -1931,7 +1879,7 @@ vectorizable_mask_load_store (gimple *st
perm_mask, stmt, gsi);
else if (j == 0)
op = vec_oprnd0
- = vect_get_vec_def_for_operand (gather_off, stmt, NULL);
+ = vect_get_vec_def_for_operand (gather_off, stmt);
else
op = vec_oprnd0
= vect_get_vec_def_for_stmt_copy (gather_dt, vec_oprnd0);
@@ -1955,11 +1903,10 @@ vectorizable_mask_load_store (gimple *st
else
{
if (j == 0)
- vec_mask = vect_get_vec_def_for_operand (mask, stmt, NULL);
+ vec_mask = vect_get_vec_def_for_operand (mask, stmt);
else
{
- vect_is_simple_use (vec_mask, NULL, loop_vinfo,
- &def_stmt, &def, &dt);
+ vect_is_simple_use (vec_mask, loop_vinfo, &def_stmt, &dt);
vec_mask = vect_get_vec_def_for_stmt_copy (dt, vec_mask);
}
@@ -2043,8 +1990,8 @@ vectorizable_mask_load_store (gimple *st
if (i == 0)
{
tree rhs = gimple_call_arg (stmt, 3);
- vec_rhs = vect_get_vec_def_for_operand (rhs, stmt, NULL);
- vec_mask = vect_get_vec_def_for_operand (mask, stmt, NULL);
+ vec_rhs = vect_get_vec_def_for_operand (rhs, stmt);
+ vec_mask = vect_get_vec_def_for_operand (mask, stmt);
/* We should have catched mismatched types earlier. */
gcc_assert (useless_type_conversion_p (vectype,
TREE_TYPE (vec_rhs)));
@@ -2055,11 +2002,9 @@ vectorizable_mask_load_store (gimple *st
}
else
{
- vect_is_simple_use (vec_rhs, NULL, loop_vinfo, &def_stmt,
- &def, &dt);
+ vect_is_simple_use (vec_rhs, loop_vinfo, &def_stmt, &dt);
vec_rhs = vect_get_vec_def_for_stmt_copy (dt, vec_rhs);
- vect_is_simple_use (vec_mask, NULL, loop_vinfo, &def_stmt,
- &def, &dt);
+ vect_is_simple_use (vec_mask, loop_vinfo, &def_stmt, &dt);
vec_mask = vect_get_vec_def_for_stmt_copy (dt, vec_mask);
dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
TYPE_SIZE_UNIT (vectype));
@@ -2100,7 +2045,7 @@ vectorizable_mask_load_store (gimple *st
if (i == 0)
{
- vec_mask = vect_get_vec_def_for_operand (mask, stmt, NULL);
+ vec_mask = vect_get_vec_def_for_operand (mask, stmt);
dataref_ptr = vect_create_data_ref_ptr (stmt, vectype, NULL,
NULL_TREE, &dummy, gsi,
&ptr_incr, false, &inv_p);
@@ -2108,8 +2053,7 @@ vectorizable_mask_load_store (gimple *st
}
else
{
- vect_is_simple_use (vec_mask, NULL, loop_vinfo, &def_stmt,
- &def, &dt);
+ vect_is_simple_use (vec_mask, loop_vinfo, &def_stmt, &dt);
vec_mask = vect_get_vec_def_for_stmt_copy (dt, vec_mask);
dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
TYPE_SIZE_UNIT (vectype));
@@ -2180,7 +2124,7 @@ vectorizable_call (gimple *gs, gimple_st
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
vec_info *vinfo = stmt_info->vinfo;
- tree fndecl, new_temp, def, rhs_type;
+ tree fndecl, new_temp, rhs_type;
gimple *def_stmt;
enum vect_def_type dt[3]
= {vect_unknown_def_type, vect_unknown_def_type, vect_unknown_def_type};
@@ -2253,8 +2197,7 @@ vectorizable_call (gimple *gs, gimple_st
if (!rhs_type)
rhs_type = TREE_TYPE (op);
- if (!vect_is_simple_use_1 (op, stmt, vinfo,
- &def_stmt, &def, &dt[i], &opvectype))
+ if (!vect_is_simple_use (op, vinfo, &def_stmt, &dt[i], &opvectype))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -2416,7 +2359,7 @@ vectorizable_call (gimple *gs, gimple_st
op = gimple_call_arg (stmt, i);
if (j == 0)
vec_oprnd0
- = vect_get_vec_def_for_operand (op, stmt, NULL);
+ = vect_get_vec_def_for_operand (op, stmt);
else
{
vec_oprnd0 = gimple_call_arg (new_stmt, i);
@@ -2514,7 +2457,7 @@ vectorizable_call (gimple *gs, gimple_st
if (j == 0)
{
vec_oprnd0
- = vect_get_vec_def_for_operand (op, stmt, NULL);
+ = vect_get_vec_def_for_operand (op, stmt);
vec_oprnd1
= vect_get_vec_def_for_stmt_copy (dt[i], vec_oprnd0);
}
@@ -2705,7 +2648,7 @@ vectorizable_simd_clone_call (gimple *st
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
vec_info *vinfo = stmt_info->vinfo;
struct loop *loop = loop_vinfo ? LOOP_VINFO_LOOP (loop_vinfo) : NULL;
- tree fndecl, new_temp, def;
+ tree fndecl, new_temp;
gimple *def_stmt;
gimple *new_stmt = NULL;
int ncopies, j;
@@ -2768,9 +2711,8 @@ vectorizable_simd_clone_call (gimple *st
thisarginfo.simd_lane_linear = false;
op = gimple_call_arg (stmt, i);
- if (!vect_is_simple_use_1 (op, stmt, vinfo,
- &def_stmt, &def, &thisarginfo.dt,
- &thisarginfo.vectype)
+ if (!vect_is_simple_use (op, vinfo, &def_stmt, &thisarginfo.dt,
+ &thisarginfo.vectype)
|| thisarginfo.dt == vect_uninitialized_def)
{
if (dump_enabled_p ())
@@ -3047,7 +2989,7 @@ vectorizable_simd_clone_call (gimple *st
gcc_assert ((k & (k - 1)) == 0);
if (m == 0)
vec_oprnd0
- = vect_get_vec_def_for_operand (op, stmt, NULL);
+ = vect_get_vec_def_for_operand (op, stmt);
else
{
vec_oprnd0 = arginfo[i].op;
@@ -3081,7 +3023,7 @@ vectorizable_simd_clone_call (gimple *st
{
if (m == 0 && l == 0)
vec_oprnd0
- = vect_get_vec_def_for_operand (op, stmt, NULL);
+ = vect_get_vec_def_for_operand (op, stmt);
else
vec_oprnd0
= vect_get_vec_def_for_stmt_copy (arginfo[i].dt,
@@ -3395,7 +3337,7 @@ vect_get_loop_based_defs (tree *oprnd, g
/* All the vector operands except the very first one (that is scalar oprnd)
are stmt copies. */
if (TREE_CODE (TREE_TYPE (*oprnd)) != VECTOR_TYPE)
- vec_oprnd = vect_get_vec_def_for_operand (*oprnd, stmt, NULL);
+ vec_oprnd = vect_get_vec_def_for_operand (*oprnd, stmt);
else
vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, *oprnd);
@@ -3555,7 +3497,6 @@ vectorizable_conversion (gimple *stmt, g
enum tree_code codecvt1 = ERROR_MARK, codecvt2 = ERROR_MARK;
tree decl1 = NULL_TREE, decl2 = NULL_TREE;
tree new_temp;
- tree def;
gimple *def_stmt;
enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
gimple *new_stmt = NULL;
@@ -3633,8 +3574,7 @@ vectorizable_conversion (gimple *stmt, g
}
/* Check the operands of the operation. */
- if (!vect_is_simple_use_1 (op0, stmt, vinfo,
- &def_stmt, &def, &dt[0], &vectype_in))
+ if (!vect_is_simple_use (op0, vinfo, &def_stmt, &dt[0], &vectype_in))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -3650,11 +3590,9 @@ vectorizable_conversion (gimple *stmt, g
/* For WIDEN_MULT_EXPR, if OP0 is a constant, use the type of
OP1. */
if (CONSTANT_CLASS_P (op0))
- ok = vect_is_simple_use_1 (op1, stmt, vinfo,
- &def_stmt, &def, &dt[1], &vectype_in);
+ ok = vect_is_simple_use (op1, vinfo, &def_stmt, &dt[1], &vectype_in);
else
- ok = vect_is_simple_use (op1, stmt, vinfo, &def_stmt,
- &def, &dt[1]);
+ ok = vect_is_simple_use (op1, vinfo, &def_stmt, &dt[1]);
if (!ok)
{
@@ -3971,15 +3909,14 @@ vectorizable_conversion (gimple *stmt, g
}
else
{
- vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt, NULL);
+ vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt);
vec_oprnds0.quick_push (vec_oprnd0);
if (op_type == binary_op)
{
if (code == WIDEN_LSHIFT_EXPR)
vec_oprnd1 = op1;
else
- vec_oprnd1 = vect_get_vec_def_for_operand (op1, stmt,
- NULL);
+ vec_oprnd1 = vect_get_vec_def_for_operand (op1, stmt);
vec_oprnds1.quick_push (vec_oprnd1);
}
}
@@ -4133,7 +4070,6 @@ vectorizable_assignment (gimple *stmt, g
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
tree new_temp;
- tree def;
gimple *def_stmt;
enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
int ncopies;
@@ -4185,8 +4121,7 @@ vectorizable_assignment (gimple *stmt, g
gcc_assert (ncopies >= 1);
- if (!vect_is_simple_use_1 (op, stmt, vinfo,
- &def_stmt, &def, &dt[0], &vectype_in))
+ if (!vect_is_simple_use (op, vinfo, &def_stmt, &dt[0], &vectype_in))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -4340,7 +4275,6 @@ vectorizable_shift (gimple *stmt, gimple
optab optab;
int icode;
machine_mode optab_op2_mode;
- tree def;
gimple *def_stmt;
enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
gimple *new_stmt = NULL;
@@ -4391,8 +4325,7 @@ vectorizable_shift (gimple *stmt, gimple
}
op0 = gimple_assign_rhs1 (stmt);
- if (!vect_is_simple_use_1 (op0, stmt, vinfo,
- &def_stmt, &def, &dt[0], &vectype))
+ if (!vect_is_simple_use (op0, vinfo, &def_stmt, &dt[0], &vectype))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -4419,8 +4352,7 @@ vectorizable_shift (gimple *stmt, gimple
return false;
op1 = gimple_assign_rhs2 (stmt);
- if (!vect_is_simple_use_1 (op1, stmt, vinfo, &def_stmt,
- &def, &dt[1], &op1_vectype))
+ if (!vect_is_simple_use (op1, vinfo, &def_stmt, &dt[1], &op1_vectype))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -4705,7 +4637,6 @@ vectorizable_operation (gimple *stmt, gi
int op_type;
optab optab;
bool target_support_p;
- tree def;
gimple *def_stmt;
enum vect_def_type dt[3]
= {vect_unknown_def_type, vect_unknown_def_type, vect_unknown_def_type};
@@ -4774,8 +4705,7 @@ vectorizable_operation (gimple *stmt, gi
}
op0 = gimple_assign_rhs1 (stmt);
- if (!vect_is_simple_use_1 (op0, stmt, vinfo,
- &def_stmt, &def, &dt[0], &vectype))
+ if (!vect_is_simple_use (op0, vinfo, &def_stmt, &dt[0], &vectype))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -4810,8 +4740,7 @@ vectorizable_operation (gimple *stmt, gi
if (op_type == binary_op || op_type == ternary_op)
{
op1 = gimple_assign_rhs2 (stmt);
- if (!vect_is_simple_use (op1, stmt, vinfo, &def_stmt,
- &def, &dt[1]))
+ if (!vect_is_simple_use (op1, vinfo, &def_stmt, &dt[1]))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -4822,8 +4751,7 @@ vectorizable_operation (gimple *stmt, gi
if (op_type == ternary_op)
{
op2 = gimple_assign_rhs3 (stmt);
- if (!vect_is_simple_use (op2, stmt, vinfo, &def_stmt,
- &def, &dt[2]))
+ if (!vect_is_simple_use (op2, vinfo, &def_stmt, &dt[2]))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -4984,8 +4912,7 @@ vectorizable_operation (gimple *stmt, gi
{
vec_oprnds2.create (1);
vec_oprnds2.quick_push (vect_get_vec_def_for_operand (op2,
- stmt,
- NULL));
+ stmt));
}
}
else
@@ -5102,7 +5029,6 @@ vectorizable_store (gimple *stmt, gimple
machine_mode vec_mode;
tree dummy;
enum dr_alignment_support alignment_support_scheme;
- tree def;
gimple *def_stmt;
enum vect_def_type dt;
stmt_vec_info prev_stmt_info = NULL;
@@ -5186,8 +5112,7 @@ vectorizable_store (gimple *stmt, gimple
}
op = gimple_assign_rhs1 (stmt);
- if (!vect_is_simple_use (op, stmt, vinfo, &def_stmt,
- &def, &dt))
+ if (!vect_is_simple_use (op, vinfo, &def_stmt, &dt))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -5277,8 +5202,7 @@ vectorizable_store (gimple *stmt, gimple
{
gcc_assert (gimple_assign_single_p (next_stmt));
op = gimple_assign_rhs1 (next_stmt);
- if (!vect_is_simple_use (op, next_stmt, vinfo,
- &def_stmt, &def, &dt))
+ if (!vect_is_simple_use (op, vinfo, &def_stmt, &dt))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -5293,13 +5217,11 @@ vectorizable_store (gimple *stmt, gimple
if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
{
gimple *def_stmt;
- tree def;
scatter_decl = vect_check_gather_scatter (stmt, loop_vinfo, &scatter_base,
&scatter_off, &scatter_scale);
gcc_assert (scatter_decl);
- if (!vect_is_simple_use_1 (scatter_off, NULL, vinfo,
- &def_stmt, &def, &scatter_idx_dt,
- &scatter_off_vectype))
+ if (!vect_is_simple_use (scatter_off, vinfo, &def_stmt, &scatter_idx_dt,
+ &scatter_off_vectype))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -5393,9 +5315,9 @@ vectorizable_store (gimple *stmt, gimple
if (j == 0)
{
src = vec_oprnd1
- = vect_get_vec_def_for_operand (gimple_assign_rhs1 (stmt), stmt, NULL);
+ = vect_get_vec_def_for_operand (gimple_assign_rhs1 (stmt), stmt);
op = vec_oprnd0
- = vect_get_vec_def_for_operand (scatter_off, stmt, NULL);
+ = vect_get_vec_def_for_operand (scatter_off, stmt);
}
else if (modifier != NONE && (j & 1))
{
@@ -5613,8 +5535,7 @@ vectorizable_store (gimple *stmt, gimple
{
gcc_assert (gimple_assign_single_p (next_stmt));
op = gimple_assign_rhs1 (next_stmt);
- vec_oprnd = vect_get_vec_def_for_operand (op, next_stmt,
- NULL);
+ vec_oprnd = vect_get_vec_def_for_operand (op, next_stmt);
}
}
else
@@ -5623,8 +5544,7 @@ vectorizable_store (gimple *stmt, gimple
vec_oprnd = vec_oprnds[j];
else
{
- vect_is_simple_use (vec_oprnd, NULL, vinfo,
- &def_stmt, &def, &dt);
+ vect_is_simple_use (vec_oprnd, vinfo, &def_stmt, &dt);
vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, vec_oprnd);
}
}
@@ -5767,8 +5687,7 @@ vectorizable_store (gimple *stmt, gimple
&& gimple_assign_single_p (next_stmt));
op = gimple_assign_rhs1 (next_stmt);
- vec_oprnd = vect_get_vec_def_for_operand (op, next_stmt,
- NULL);
+ vec_oprnd = vect_get_vec_def_for_operand (op, next_stmt);
dr_chain.quick_push (vec_oprnd);
oprnds.quick_push (vec_oprnd);
next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
@@ -5813,8 +5732,7 @@ vectorizable_store (gimple *stmt, gimple
for (i = 0; i < group_size; i++)
{
op = oprnds[i];
- vect_is_simple_use (op, NULL, vinfo, &def_stmt,
- &def, &dt);
+ vect_is_simple_use (op, vinfo, &def_stmt, &dt);
vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, op);
dr_chain[i] = vec_oprnd;
oprnds[i] = vec_oprnd;
@@ -6288,13 +6206,11 @@ vectorizable_load (gimple *stmt, gimple_
if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
{
gimple *def_stmt;
- tree def;
gather_decl = vect_check_gather_scatter (stmt, loop_vinfo, &gather_base,
&gather_off, &gather_scale);
gcc_assert (gather_decl);
- if (!vect_is_simple_use_1 (gather_off, NULL, vinfo,
- &def_stmt, &def, &gather_dt,
- &gather_off_vectype))
+ if (!vect_is_simple_use (gather_off, vinfo, &def_stmt, &gather_dt,
+ &gather_off_vectype))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -6483,7 +6399,7 @@ vectorizable_load (gimple *stmt, gimple_
perm_mask, stmt, gsi);
else if (j == 0)
op = vec_oprnd0
- = vect_get_vec_def_for_operand (gather_off, stmt, NULL);
+ = vect_get_vec_def_for_operand (gather_off, stmt);
else
op = vec_oprnd0
= vect_get_vec_def_for_stmt_copy (gather_dt, vec_oprnd0);
@@ -7224,11 +7140,9 @@ vectorizable_load (gimple *stmt, gimple_
condition operands are supportable using vec_is_simple_use. */
static bool
-vect_is_simple_cond (tree cond, gimple *stmt, vec_info *vinfo,
- tree *comp_vectype)
+vect_is_simple_cond (tree cond, vec_info *vinfo, tree *comp_vectype)
{
tree lhs, rhs;
- tree def;
enum vect_def_type dt;
tree vectype1 = NULL_TREE, vectype2 = NULL_TREE;
@@ -7241,8 +7155,7 @@ vect_is_simple_cond (tree cond, gimple *
if (TREE_CODE (lhs) == SSA_NAME)
{
gimple *lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
- if (!vect_is_simple_use_1 (lhs, stmt, vinfo,
- &lhs_def_stmt, &def, &dt, &vectype1))
+ if (!vect_is_simple_use (lhs, vinfo, &lhs_def_stmt, &dt, &vectype1))
return false;
}
else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST
@@ -7252,8 +7165,7 @@ vect_is_simple_cond (tree cond, gimple *
if (TREE_CODE (rhs) == SSA_NAME)
{
gimple *rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
- if (!vect_is_simple_use_1 (rhs, stmt, vinfo,
- &rhs_def_stmt, &def, &dt, &vectype2))
+ if (!vect_is_simple_use (rhs, vinfo, &rhs_def_stmt, &dt, &vectype2))
return false;
}
else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) != REAL_CST
@@ -7292,7 +7204,6 @@ vectorizable_condition (gimple *stmt, gi
tree vec_compare, vec_cond_expr;
tree new_temp;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- tree def;
enum vect_def_type dt, dts[4];
int ncopies;
enum tree_code code;
@@ -7350,32 +7261,14 @@ vectorizable_condition (gimple *stmt, gi
then_clause = gimple_assign_rhs2 (stmt);
else_clause = gimple_assign_rhs3 (stmt);
- if (!vect_is_simple_cond (cond_expr, stmt, stmt_info->vinfo, &comp_vectype)
+ if (!vect_is_simple_cond (cond_expr, stmt_info->vinfo, &comp_vectype)
|| !comp_vectype)
return false;
- if (TREE_CODE (then_clause) == SSA_NAME)
- {
- gimple *then_def_stmt = SSA_NAME_DEF_STMT (then_clause);
- if (!vect_is_simple_use (then_clause, stmt, stmt_info->vinfo,
- &then_def_stmt, &def, &dt))
- return false;
- }
- else if (TREE_CODE (then_clause) != INTEGER_CST
- && TREE_CODE (then_clause) != REAL_CST
- && TREE_CODE (then_clause) != FIXED_CST)
+ gimple *def_stmt;
+ if (!vect_is_simple_use (then_clause, stmt_info->vinfo, &def_stmt, &dt))
return false;
-
- if (TREE_CODE (else_clause) == SSA_NAME)
- {
- gimple *else_def_stmt = SSA_NAME_DEF_STMT (else_clause);
- if (!vect_is_simple_use (else_clause, stmt, stmt_info->vinfo,
- &else_def_stmt, &def, &dt))
- return false;
- }
- else if (TREE_CODE (else_clause) != INTEGER_CST
- && TREE_CODE (else_clause) != REAL_CST
- && TREE_CODE (else_clause) != FIXED_CST)
+ if (!vect_is_simple_use (else_clause, stmt_info->vinfo, &def_stmt, &dt))
return false;
unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vectype)));
@@ -7433,33 +7326,31 @@ vectorizable_condition (gimple *stmt, gi
{
gimple *gtemp;
vec_cond_lhs =
- vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0),
- stmt, NULL);
- vect_is_simple_use (TREE_OPERAND (cond_expr, 0), stmt,
- loop_vinfo, >emp, &def, &dts[0]);
+ vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), stmt);
+ vect_is_simple_use (TREE_OPERAND (cond_expr, 0),
+ loop_vinfo, >emp, &dts[0]);
vec_cond_rhs =
vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1),
- stmt, NULL);
- vect_is_simple_use (TREE_OPERAND (cond_expr, 1), stmt,
- loop_vinfo, >emp, &def, &dts[1]);
+ stmt);
+ vect_is_simple_use (TREE_OPERAND (cond_expr, 1),
+ loop_vinfo, >emp, &dts[1]);
if (reduc_index == 1)
vec_then_clause = reduc_def;
else
{
vec_then_clause = vect_get_vec_def_for_operand (then_clause,
- stmt, NULL);
- vect_is_simple_use (then_clause, stmt, loop_vinfo,
- >emp, &def, &dts[2]);
+ stmt);
+ vect_is_simple_use (then_clause, loop_vinfo,
+ >emp, &dts[2]);
}
if (reduc_index == 2)
vec_else_clause = reduc_def;
else
{
vec_else_clause = vect_get_vec_def_for_operand (else_clause,
- stmt, NULL);
- vect_is_simple_use (else_clause, stmt, loop_vinfo,
- >emp, &def, &dts[3]);
+ stmt);
+ vect_is_simple_use (else_clause, loop_vinfo, >emp, &dts[3]);
}
}
}
@@ -8200,10 +8091,11 @@ get_same_sized_vectype (tree scalar_type
/* Function vect_is_simple_use.
Input:
- LOOP_VINFO - the vect info of the loop that is being vectorized.
- BB_VINFO - the vect info of the basic block that is being vectorized.
- OPERAND - operand of STMT in the loop or bb.
- DEF - the defining stmt in case OPERAND is an SSA_NAME.
+ VINFO - the vect info of the loop or basic block that is being vectorized.
+ OPERAND - operand in the loop or bb.
+ Output:
+ DEF_STMT - the defining stmt in case OPERAND is an SSA_NAME.
+ DT - the type of definition
Returns whether a stmt with OPERAND can be vectorized.
For loops, supportable operands are constants, loop invariants, and operands
@@ -8214,11 +8106,10 @@ get_same_sized_vectype (tree scalar_type
For now, operands defined outside the basic block are not supported. */
bool
-vect_is_simple_use (tree operand, gimple *stmt, vec_info *vinfo,
- gimple **def_stmt, tree *def, enum vect_def_type *dt)
+vect_is_simple_use (tree operand, vec_info *vinfo,
+ gimple **def_stmt, enum vect_def_type *dt)
{
*def_stmt = NULL;
- *def = NULL_TREE;
*dt = vect_unknown_def_type;
if (dump_enabled_p ())
@@ -8237,7 +8128,6 @@ vect_is_simple_use (tree operand, gimple
if (is_gimple_min_invariant (operand))
{
- *def = operand;
*dt = vect_external_def;
return true;
}
@@ -8252,7 +8142,6 @@ vect_is_simple_use (tree operand, gimple
if (SSA_NAME_IS_DEFAULT_DEF (operand))
{
- *def = operand;
*dt = vect_external_def;
return true;
}
@@ -8315,10 +8204,7 @@ vect_is_simple_use (tree operand, gimple
}
}
- if (*dt == vect_unknown_def_type
- || (stmt
- && *dt == vect_double_reduction_def
- && gimple_code (stmt) != GIMPLE_PHI))
+ if (*dt == vect_unknown_def_type)
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -8329,18 +8215,9 @@ vect_is_simple_use (tree operand, gimple
switch (gimple_code (*def_stmt))
{
case GIMPLE_PHI:
- *def = gimple_phi_result (*def_stmt);
- break;
-
case GIMPLE_ASSIGN:
- *def = gimple_assign_lhs (*def_stmt);
- break;
-
case GIMPLE_CALL:
- *def = gimple_call_lhs (*def_stmt);
- if (*def != NULL)
- break;
- /* FALLTHRU */
+ break;
default:
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -8351,9 +8228,9 @@ vect_is_simple_use (tree operand, gimple
return true;
}
-/* Function vect_is_simple_use_1.
+/* Function vect_is_simple_use.
- Same as vect_is_simple_use_1 but also determines the vector operand
+ Same as vect_is_simple_use but also determines the vector operand
type of OPERAND and stores it to *VECTYPE. If the definition of
OPERAND is vect_uninitialized_def, vect_constant_def or
vect_external_def *VECTYPE will be set to NULL_TREE and the caller
@@ -8361,11 +8238,10 @@ vect_is_simple_use (tree operand, gimple
scalar operand. */
bool
-vect_is_simple_use_1 (tree operand, gimple *stmt, vec_info *vinfo,
- gimple **def_stmt,
- tree *def, enum vect_def_type *dt, tree *vectype)
+vect_is_simple_use (tree operand, vec_info *vinfo,
+ gimple **def_stmt, enum vect_def_type *dt, tree *vectype)
{
- if (!vect_is_simple_use (operand, stmt, vinfo, def_stmt, def, dt))
+ if (!vect_is_simple_use (operand, vinfo, def_stmt, dt))
return false;
/* Now get a vector type if the def is internal, otherwise supply
@@ -8506,6 +8382,16 @@ supportable_widening_operation (enum tre
c2 = VEC_WIDEN_MULT_HI_EXPR;
break;
+ case DOT_PROD_EXPR:
+ c1 = DOT_PROD_EXPR;
+ c2 = DOT_PROD_EXPR;
+ break;
+
+ case SAD_EXPR:
+ c1 = SAD_EXPR;
+ c2 = SAD_EXPR;
+ break;
+
case VEC_WIDEN_MULT_EVEN_EXPR:
/* Support the recursion induced just above. */
c1 = VEC_WIDEN_MULT_EVEN_EXPR;
Index: gcc/tree-vectorizer.h
===================================================================
--- gcc/tree-vectorizer.h (revision 228806)
+++ gcc/tree-vectorizer.h (working copy)
@@ -932,10 +932,10 @@ extern bool vect_can_advance_ivs_p (loop
extern unsigned int current_vector_size;
extern tree get_vectype_for_scalar_type (tree);
extern tree get_same_sized_vectype (tree, tree);
-extern bool vect_is_simple_use (tree, gimple *, vec_info *, gimple **,
- tree *, enum vect_def_type *);
-extern bool vect_is_simple_use_1 (tree, gimple *, vec_info *, gimple **,
- tree *, enum vect_def_type *, tree *);
+extern bool vect_is_simple_use (tree, vec_info *, gimple **,
+ enum vect_def_type *);
+extern bool vect_is_simple_use (tree, vec_info *, gimple **,
+ enum vect_def_type *, tree *);
extern bool supportable_widening_operation (enum tree_code, gimple *, tree,
tree, enum tree_code *,
enum tree_code *, int *,
@@ -962,7 +962,7 @@ extern unsigned record_stmt_cost (stmt_v
extern void vect_finish_stmt_generation (gimple *, gimple *,
gimple_stmt_iterator *);
extern bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
-extern tree vect_get_vec_def_for_operand (tree, gimple *, tree *);
+extern tree vect_get_vec_def_for_operand (tree, gimple *);
extern tree vect_init_vector (gimple *, tree, tree,
gimple_stmt_iterator *);
extern tree vect_get_vec_def_for_stmt_copy (enum vect_def_type, tree);
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] More vectorizer TLC
@ 2015-10-14 8:32 Richard Biener
0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2015-10-14 8:32 UTC (permalink / raw)
To: gcc-patches
Bootstrapped / tested on x86_64-unknown-linux-gnu, applied.
Richard.
2015-10-14 Richard Biener <rguenther@suse.de>
* tree-vect-data-refs.c (vect_enhance_data_refs_alignment):
Reset info at start.
(vect_analyze_group_access_1): Add debug print.
* tree-vect-loop.c (vect_get_single_scalar_iteration_cost): Rename ...
(vect_compute_single_scalar_iteration_cost): ... to this.
(vect_analyze_loop_2): Adjust.
* tree-vect-slp.c (struct _slp_oprnd_info): Move from ...
* tree-vectorizer.h: ... here.
(add_stmt_info_to_vec): Remove.
* tree-vect-stmts.c (record_stmt_cost): Inline add_stmt_info_to_vec.
Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c (revision 228759)
--- gcc/tree-vect-data-refs.c (working copy)
*************** vect_enhance_data_refs_alignment (loop_v
*** 1352,1357 ****
--- 1352,1361 ----
dump_printf_loc (MSG_NOTE, vect_location,
"=== vect_enhance_data_refs_alignment ===\n");
+ /* Reset data so we can safely be called multiple times. */
+ LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo).truncate (0);
+ LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) = 0;
+
/* While cost model enhancements are expected in the future, the high level
view of the code at this time is as follows:
*************** vect_analyze_group_access_1 (struct data
*** 2151,2156 ****
--- 2155,2164 ----
return false;
}
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Two or more load stmts share the same dr.\n");
+
/* For load use the same data-ref load. */
GROUP_SAME_DR_STMT (vinfo_for_stmt (next)) = prev;
Index: gcc/tree-vect-loop.c
===================================================================
*** gcc/tree-vect-loop.c (revision 228759)
--- gcc/tree-vect-loop.c (working copy)
*************** destroy_loop_vec_info (loop_vec_info loo
*** 1043,1049 ****
/* Calculate the cost of one scalar iteration of the loop. */
static void
! vect_get_single_scalar_iteration_cost (loop_vec_info loop_vinfo)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
--- 1043,1049 ----
/* Calculate the cost of one scalar iteration of the loop. */
static void
! vect_compute_single_scalar_iteration_cost (loop_vec_info loop_vinfo)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
*************** vect_analyze_loop_2 (loop_vec_info loop_
*** 1739,1745 ****
}
/* Compute the scalar iteration cost. */
! vect_get_single_scalar_iteration_cost (loop_vinfo);
/* This pass will decide on using loop versioning and/or loop peeling in
order to enhance the alignment of data references in the loop. */
--- 1739,1745 ----
}
/* Compute the scalar iteration cost. */
! vect_compute_single_scalar_iteration_cost (loop_vinfo);
/* This pass will decide on using loop versioning and/or loop peeling in
order to enhance the alignment of data references in the loop. */
Index: gcc/tree-vect-slp.c
===================================================================
*** gcc/tree-vect-slp.c (revision 228759)
--- gcc/tree-vect-slp.c (working copy)
*************** vect_create_new_slp_node (vec<gimple *>
*** 135,140 ****
--- 135,157 ----
}
+ /* This structure is used in creation of an SLP tree. Each instance
+ corresponds to the same operand in a group of scalar stmts in an SLP
+ node. */
+ typedef struct _slp_oprnd_info
+ {
+ /* Def-stmts for the operands. */
+ vec<gimple *> def_stmts;
+ /* Information about the first statement, its vector def-type, type, the
+ operand itself in case it's constant, and an indication if it's a pattern
+ stmt. */
+ enum vect_def_type first_dt;
+ tree first_op_type;
+ bool first_pattern;
+ bool second_pattern;
+ } *slp_oprnd_info;
+
+
/* Allocate operands info for NOPS operands, and GROUP_SIZE def-stmts for each
operand. */
static vec<slp_oprnd_info>
Index: gcc/tree-vect-stmts.c
===================================================================
*** gcc/tree-vect-stmts.c (revision 228759)
--- gcc/tree-vect-stmts.c (working copy)
*************** record_stmt_cost (stmt_vector_for_cost *
*** 94,105 ****
if (body_cost_vec)
{
tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE;
! add_stmt_info_to_vec (body_cost_vec, count, kind,
! stmt_info ? STMT_VINFO_STMT (stmt_info) : NULL,
! misalign);
return (unsigned)
(builtin_vectorization_cost (kind, vectype, misalign) * count);
-
}
else
return add_stmt_cost (stmt_info->vinfo->target_cost_data,
--- 94,105 ----
if (body_cost_vec)
{
tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE;
! stmt_info_for_cost si = { count, kind,
! stmt_info ? STMT_VINFO_STMT (stmt_info) : NULL,
! misalign };
! body_cost_vec->safe_push (si);
return (unsigned)
(builtin_vectorization_cost (kind, vectype, misalign) * count);
}
else
return add_stmt_cost (stmt_info->vinfo->target_cost_data,
Index: gcc/tree-vectorizer.h
===================================================================
*** gcc/tree-vectorizer.h (revision 228759)
--- gcc/tree-vectorizer.h (working copy)
*************** struct stmt_info_for_cost {
*** 73,93 ****
int misalign;
};
-
typedef vec<stmt_info_for_cost> stmt_vector_for_cost;
- static inline void
- add_stmt_info_to_vec (stmt_vector_for_cost *stmt_cost_vec, int count,
- enum vect_cost_for_stmt kind, gimple *stmt, int misalign)
- {
- stmt_info_for_cost si;
- si.count = count;
- si.kind = kind;
- si.stmt = stmt;
- si.misalign = misalign;
- stmt_cost_vec->safe_push (si);
- }
-
/************************************************************************
SLP
************************************************************************/
--- 73,80 ----
*************** typedef struct _slp_instance {
*** 145,166 ****
#define SLP_TREE_LOAD_PERMUTATION(S) (S)->load_permutation
#define SLP_TREE_TWO_OPERATORS(S) (S)->two_operators
- /* This structure is used in creation of an SLP tree. Each instance
- corresponds to the same operand in a group of scalar stmts in an SLP
- node. */
- typedef struct _slp_oprnd_info
- {
- /* Def-stmts for the operands. */
- vec<gimple *> def_stmts;
- /* Information about the first statement, its vector def-type, type, the
- operand itself in case it's constant, and an indication if it's a pattern
- stmt. */
- enum vect_def_type first_dt;
- tree first_op_type;
- bool first_pattern;
- bool second_pattern;
- } *slp_oprnd_info;
-
/* This struct is used to store the information of a data reference,
--- 132,137 ----
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] More vectorizer TLC
@ 2015-10-12 8:30 Richard Biener
0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2015-10-12 8:30 UTC (permalink / raw)
To: gcc-patches
Bootstrapped & tested on x86_64-unknown-linux-gnu, applied.
Richard.
2015-10-12 Richard Biener <rguenther@suse.de>
* tree-vect-loop.c (vect_analyze_loop_operations): Move cost
related code ...
(vect_analyze_loop_2): ... here.
Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c (revision 228644)
+++ gcc/tree-vect-loop.c (working copy)
@@ -1430,17 +1430,10 @@ vect_analyze_loop_operations (loop_vec_i
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
int nbbs = loop->num_nodes;
- unsigned int vectorization_factor;
int i;
stmt_vec_info stmt_info;
bool need_to_vectorize = false;
- int min_profitable_iters;
- int min_scalar_loop_bound;
- unsigned int th;
bool ok;
- HOST_WIDE_INT max_niter;
- HOST_WIDE_INT estimated_niter;
- int min_profitable_estimate;
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
@@ -1585,94 +1578,6 @@ vect_analyze_loop_operations (loop_vec_i
return false;
}
- vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
- gcc_assert (vectorization_factor != 0);
-
- if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) && dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "vectorization_factor = %d, niters = "
- HOST_WIDE_INT_PRINT_DEC "\n", vectorization_factor,
- LOOP_VINFO_INT_NITERS (loop_vinfo));
-
- if ((LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
- && (LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor))
- || ((max_niter = max_stmt_executions_int (loop)) != -1
- && (unsigned HOST_WIDE_INT) max_niter < vectorization_factor))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "not vectorized: iteration count too small.\n");
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "not vectorized: iteration count smaller than "
- "vectorization factor.\n");
- return false;
- }
-
- /* Analyze cost. Decide if worth while to vectorize. */
-
- 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)
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "not vectorized: vectorization not profitable.\n");
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "not vectorized: vector version will never be "
- "profitable.\n");
- return false;
- }
-
- min_scalar_loop_bound = ((PARAM_VALUE (PARAM_MIN_VECT_LOOP_BOUND)
- * vectorization_factor) - 1);
-
-
- /* Use the cost model only if it is more conservative than user specified
- threshold. */
-
- th = (unsigned) min_scalar_loop_bound;
- if (min_profitable_iters
- && (!min_scalar_loop_bound
- || min_profitable_iters > min_scalar_loop_bound))
- th = (unsigned) min_profitable_iters;
-
- LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo) = th;
-
- if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
- && LOOP_VINFO_INT_NITERS (loop_vinfo) <= th)
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "not vectorized: vectorization not profitable.\n");
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "not vectorized: iteration count smaller than user "
- "specified loop bound parameter or minimum profitable "
- "iterations (whichever is more conservative).\n");
- return false;
- }
-
- if ((estimated_niter = estimated_stmt_executions_int (loop)) != -1
- && ((unsigned HOST_WIDE_INT) estimated_niter
- <= MAX (th, (unsigned)min_profitable_estimate)))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "not vectorized: estimated iteration count too "
- "small.\n");
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "not vectorized: estimated iteration count smaller "
- "than specified loop bound parameter or minimum "
- "profitable iterations (whichever is more "
- "conservative).\n");
- return false;
- }
-
return true;
}
@@ -1688,7 +1593,6 @@ vect_analyze_loop_2 (loop_vec_info loop_
bool ok;
int max_vf = MAX_VECTORIZATION_FACTOR;
int min_vf = 2;
- unsigned int th;
unsigned int n_stmts = 0;
/* Find all data references in the loop (which correspond to vdefs/vuses)
@@ -1786,6 +1690,33 @@ vect_analyze_loop_2 (loop_vec_info loop_
vect_update_vf_for_slp (loop_vinfo);
}
+ /* Now the vectorization factor is final. */
+ unsigned vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+ gcc_assert (vectorization_factor != 0);
+
+ if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) && dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vectorization_factor = %d, niters = "
+ HOST_WIDE_INT_PRINT_DEC "\n", vectorization_factor,
+ LOOP_VINFO_INT_NITERS (loop_vinfo));
+
+ HOST_WIDE_INT max_niter
+ = max_stmt_executions_int (LOOP_VINFO_LOOP (loop_vinfo));
+ if ((LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
+ && (LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor))
+ || (max_niter != -1
+ && (unsigned HOST_WIDE_INT) max_niter < vectorization_factor))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: iteration count too small.\n");
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: iteration count smaller than "
+ "vectorization factor.\n");
+ return false;
+ }
+
/* Analyze the alignment of the data-refs in the loop.
Fail if a data reference is found that cannot be vectorized. */
@@ -1851,6 +1782,70 @@ vect_analyze_loop_2 (loop_vec_info loop_
return false;
}
+ /* Analyze cost. Decide if worth while to vectorize. */
+ 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)
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: vectorization not profitable.\n");
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: vector version will never be "
+ "profitable.\n");
+ return false;
+ }
+
+ int min_scalar_loop_bound = ((PARAM_VALUE (PARAM_MIN_VECT_LOOP_BOUND)
+ * vectorization_factor) - 1);
+
+ /* Use the cost model only if it is more conservative than user specified
+ threshold. */
+ unsigned th = (unsigned) min_scalar_loop_bound;
+ if (min_profitable_iters
+ && (!min_scalar_loop_bound
+ || min_profitable_iters > min_scalar_loop_bound))
+ th = (unsigned) min_profitable_iters;
+
+ LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo) = th;
+
+ if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
+ && LOOP_VINFO_INT_NITERS (loop_vinfo) <= th)
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: vectorization not profitable.\n");
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "not vectorized: iteration count smaller than user "
+ "specified loop bound parameter or minimum profitable "
+ "iterations (whichever is more conservative).\n");
+ return false;
+ }
+
+ HOST_WIDE_INT estimated_niter
+ = estimated_stmt_executions_int (LOOP_VINFO_LOOP (loop_vinfo));
+ if (estimated_niter != -1
+ && ((unsigned HOST_WIDE_INT) estimated_niter
+ <= MAX (th, (unsigned)min_profitable_estimate)))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: estimated iteration count too "
+ "small.\n");
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "not vectorized: estimated iteration count smaller "
+ "than specified loop bound parameter or minimum "
+ "profitable iterations (whichever is more "
+ "conservative).\n");
+ return false;
+ }
+
/* Decide whether we need to create an epilogue loop to handle
remaining scalar iterations. */
th = ((LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo) + 1)
@@ -1873,8 +1868,7 @@ vect_analyze_loop_2 (loop_vec_info loop_
the epilogue is unnecessary. */
&& ((!LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo)
&& !LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo))
- || (unsigned HOST_WIDE_INT)max_stmt_executions_int
- (LOOP_VINFO_LOOP (loop_vinfo)) > th)))
+ || (unsigned HOST_WIDE_INT) max_niter > th)))
LOOP_VINFO_PEELING_FOR_NITER (loop_vinfo) = true;
/* If an epilogue loop is required make sure we can create one. */
@@ -1896,6 +1890,9 @@ vect_analyze_loop_2 (loop_vec_info loop_
}
}
+ gcc_assert (vectorization_factor
+ == (unsigned)LOOP_VINFO_VECT_FACTOR (loop_vinfo));
+
return true;
}
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] More vectorizer TLC
@ 2013-04-18 14:16 Richard Biener
0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2013-04-18 14:16 UTC (permalink / raw)
To: gcc-patches
While trying to remove some restrictions I came along more TLC
opportunities.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard.
2013-04-18 Richard Biener <rguenther@suse.de>
* tree-vect-data-refs.c (vect_analyze_group_access): Properly
handle negative step. Remove redundant checks.
(vect_create_data_ref_ptr): Avoid ICEs with non-constant steps.
* tree-vect-stmts.c (vectorizable_load): Instead of asserting
for negative step and grouped loads fail to vectorize.
Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c.orig 2013-04-18 12:17:03.000000000 +0200
--- gcc/tree-vect-data-refs.c 2013-04-18 12:17:14.430103903 +0200
*************** vect_analyze_group_access (struct data_r
*** 2024,2030 ****
/* For interleaving, GROUPSIZE is STEP counted in elements, i.e., the
size of the interleaving group (including gaps). */
! groupsize = dr_step / type_size;
/* Not consecutive access is possible only if it is a part of interleaving. */
if (!GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)))
--- 2024,2030 ----
/* For interleaving, GROUPSIZE is STEP counted in elements, i.e., the
size of the interleaving group (including gaps). */
! groupsize = absu_hwi (dr_step) / type_size;
/* Not consecutive access is possible only if it is a part of interleaving. */
if (!GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)))
*************** vect_analyze_group_access (struct data_r
*** 2094,2103 ****
gimple next = GROUP_NEXT_ELEMENT (vinfo_for_stmt (stmt));
struct data_reference *data_ref = dr;
unsigned int count = 1;
- tree next_step;
tree prev_init = DR_INIT (data_ref);
gimple prev = stmt;
! HOST_WIDE_INT diff, count_in_bytes, gaps = 0;
while (next)
{
--- 2094,2103 ----
gimple next = GROUP_NEXT_ELEMENT (vinfo_for_stmt (stmt));
struct data_reference *data_ref = dr;
unsigned int count = 1;
tree prev_init = DR_INIT (data_ref);
gimple prev = stmt;
! HOST_WIDE_INT diff, gaps = 0;
! unsigned HOST_WIDE_INT count_in_bytes;
while (next)
{
*************** vect_analyze_group_access (struct data_r
*** 2126,2143 ****
}
prev = next;
! /* Check that all the accesses have the same STEP. */
! next_step = DR_STEP (STMT_VINFO_DATA_REF (vinfo_for_stmt (next)));
! if (tree_int_cst_compare (step, next_step))
! {
! if (dump_enabled_p ())
! dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
! "not consecutive access in interleaving");
! return false;
! }
- data_ref = STMT_VINFO_DATA_REF (vinfo_for_stmt (next));
/* Check that the distance between two accesses is equal to the type
size. Otherwise, we have gaps. */
diff = (TREE_INT_CST_LOW (DR_INIT (data_ref))
--- 2126,2136 ----
}
prev = next;
+ data_ref = STMT_VINFO_DATA_REF (vinfo_for_stmt (next));
! /* All group members have the same STEP by construction. */
! gcc_checking_assert (operand_equal_p (DR_STEP (data_ref), step, 0));
/* Check that the distance between two accesses is equal to the type
size. Otherwise, we have gaps. */
diff = (TREE_INT_CST_LOW (DR_INIT (data_ref))
*************** vect_analyze_group_access (struct data_r
*** 2175,2181 ****
/* Check that the size of the interleaving (including gaps) is not
greater than STEP. */
! if (dr_step && dr_step < count_in_bytes + gaps * type_size)
{
if (dump_enabled_p ())
{
--- 2168,2175 ----
/* Check that the size of the interleaving (including gaps) is not
greater than STEP. */
! if (dr_step != 0
! && absu_hwi (dr_step) < count_in_bytes + gaps * type_size)
{
if (dump_enabled_p ())
{
*************** vect_analyze_group_access (struct data_r
*** 2188,2194 ****
/* Check that the size of the interleaving is equal to STEP for stores,
i.e., that there are no gaps. */
! if (dr_step && dr_step != count_in_bytes)
{
if (DR_IS_READ (dr))
{
--- 2182,2189 ----
/* Check that the size of the interleaving is equal to STEP for stores,
i.e., that there are no gaps. */
! if (dr_step != 0
! && absu_hwi (dr_step) != count_in_bytes)
{
if (DR_IS_READ (dr))
{
*************** vect_analyze_group_access (struct data_r
*** 2208,2214 ****
}
/* Check that STEP is a multiple of type size. */
! if (dr_step && (dr_step % type_size) != 0)
{
if (dump_enabled_p ())
{
--- 2203,2210 ----
}
/* Check that STEP is a multiple of type size. */
! if (dr_step != 0
! && (dr_step % type_size) != 0)
{
if (dump_enabled_p ())
{
*************** vect_create_data_ref_ptr (gimple stmt, t
*** 3520,3526 ****
tree aptr;
gimple_stmt_iterator incr_gsi;
bool insert_after;
- bool negative;
tree indx_before_incr, indx_after_incr;
gimple incr;
tree step;
--- 3520,3525 ----
*************** vect_create_data_ref_ptr (gimple stmt, t
*** 3550,3560 ****
else
step = DR_STEP (STMT_VINFO_DATA_REF (stmt_info));
! if (tree_int_cst_compare (step, size_zero_node) == 0)
*inv_p = true;
else
*inv_p = false;
- negative = tree_int_cst_compare (step, size_zero_node) < 0;
/* Create an expression for the first address accessed by this load
in LOOP. */
--- 3549,3558 ----
else
step = DR_STEP (STMT_VINFO_DATA_REF (stmt_info));
! if (integer_zerop (step))
*inv_p = true;
else
*inv_p = false;
/* Create an expression for the first address accessed by this load
in LOOP. */
*************** vect_create_data_ref_ptr (gimple stmt, t
*** 3693,3710 ****
else
{
/* The step of the aggregate pointer is the type size. */
! tree step = TYPE_SIZE_UNIT (aggr_type);
/* One exception to the above is when the scalar step of the load in
LOOP is zero. In this case the step here is also zero. */
if (*inv_p)
! step = size_zero_node;
! else if (negative)
! step = fold_build1 (NEGATE_EXPR, TREE_TYPE (step), step);
standard_iv_increment_position (loop, &incr_gsi, &insert_after);
create_iv (aggr_ptr_init,
! fold_convert (aggr_ptr_type, step),
aggr_ptr, loop, &incr_gsi, insert_after,
&indx_before_incr, &indx_after_incr);
incr = gsi_stmt (incr_gsi);
--- 3691,3708 ----
else
{
/* The step of the aggregate pointer is the type size. */
! tree iv_step = TYPE_SIZE_UNIT (aggr_type);
/* One exception to the above is when the scalar step of the load in
LOOP is zero. In this case the step here is also zero. */
if (*inv_p)
! iv_step = size_zero_node;
! else if (tree_int_cst_sgn (step) == -1)
! iv_step = fold_build1 (NEGATE_EXPR, TREE_TYPE (iv_step), iv_step);
standard_iv_increment_position (loop, &incr_gsi, &insert_after);
create_iv (aggr_ptr_init,
! fold_convert (aggr_ptr_type, iv_step),
aggr_ptr, loop, &incr_gsi, insert_after,
&indx_before_incr, &indx_after_incr);
incr = gsi_stmt (incr_gsi);
Index: gcc/tree-vect-stmts.c
===================================================================
*** gcc/tree-vect-stmts.c.orig 2013-04-18 12:17:03.000000000 +0200
--- gcc/tree-vect-stmts.c 2013-04-18 12:18:47.745157947 +0200
*************** vectorizable_load (gimple stmt, gimple_s
*** 4465,4471 ****
if (negative)
{
! gcc_assert (!grouped_load);
alignment_support_scheme = vect_supportable_dr_alignment (dr, false);
if (alignment_support_scheme != dr_aligned
&& alignment_support_scheme != dr_unaligned_supported)
--- 4479,4491 ----
if (negative)
{
! if (grouped_load)
! {
! if (dump_enabled_p ())
! dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
! "negative step for group load not supported");
! return false;
! }
alignment_support_scheme = vect_supportable_dr_alignment (dr, false);
if (alignment_support_scheme != dr_aligned
&& alignment_support_scheme != dr_unaligned_supported)
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] More vectorizer TLC
@ 2013-04-09 14:53 Richard Biener
0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2013-04-09 14:53 UTC (permalink / raw)
To: gcc-patches
This gets rid of slp_void_p and moves vect_get_place_in_interleaving_chain
next to its only user.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard.
2013-04-09 Richard Biener <rguenther@suse.de>
* tree-vectorizer.h (slp_void_p): Remove.
(slp_tree): Typedef before _slp_tree declaration.
(struct _slp_tree): Use a vector of slp_tree as children.
(vect_get_place_in_interleaving_chain): Remove.
* tree-vect-data-refs.c (vect_get_place_in_interleaving_chain):
Move ...
* tree-vect-slp.c (vect_get_place_in_interleaving_chain): ... here
and make static.
(vect_free_slp_tree, vect_print_slp_tree, vect_mark_slp_stmts,
vect_mark_slp_stmts_relevant, vect_slp_rearrange_stmts,
vect_detect_hybrid_slp_stmts, vect_slp_analyze_node_operations,
vect_schedule_slp_instance, vect_remove_slp_scalar_calls):
Use slp_node instead of slp_void_p and adjust.
Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c (revision 197621)
--- gcc/tree-vect-data-refs.c (working copy)
*************** vect_get_smallest_scalar_type (gimple st
*** 129,159 ****
}
- /* Find the place of the data-ref in STMT in the interleaving chain that starts
- from FIRST_STMT. Return -1 if the data-ref is not a part of the chain. */
-
- int
- vect_get_place_in_interleaving_chain (gimple stmt, gimple first_stmt)
- {
- gimple next_stmt = first_stmt;
- int result = 0;
-
- if (first_stmt != GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)))
- return -1;
-
- while (next_stmt && next_stmt != stmt)
- {
- result++;
- next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
- }
-
- if (next_stmt)
- return result;
- else
- return -1;
- }
-
-
/* Check if data references pointed by DR_I and DR_J are same or
belong to same interleaving group. Return FALSE if drs are
different, otherwise return TRUE. */
--- 129,134 ----
Index: gcc/tree-vect-slp.c
===================================================================
*** gcc/tree-vect-slp.c (revision 197621)
--- gcc/tree-vect-slp.c (working copy)
*************** static void
*** 67,79 ****
vect_free_slp_tree (slp_tree node)
{
int i;
! slp_void_p child;
if (!node)
return;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_free_slp_tree ((slp_tree) child);
SLP_TREE_CHILDREN (node).release ();
SLP_TREE_SCALAR_STMTS (node).release ();
--- 67,79 ----
vect_free_slp_tree (slp_tree node)
{
int i;
! slp_tree child;
if (!node)
return;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_free_slp_tree (child);
SLP_TREE_CHILDREN (node).release ();
SLP_TREE_SCALAR_STMTS (node).release ();
*************** vect_free_oprnd_info (vec<slp_oprnd_info
*** 168,173 ****
--- 168,198 ----
}
+ /* Find the place of the data-ref in STMT in the interleaving chain that starts
+ from FIRST_STMT. Return -1 if the data-ref is not a part of the chain. */
+
+ static int
+ vect_get_place_in_interleaving_chain (gimple stmt, gimple first_stmt)
+ {
+ gimple next_stmt = first_stmt;
+ int result = 0;
+
+ if (first_stmt != GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)))
+ return -1;
+
+ do
+ {
+ if (next_stmt == stmt)
+ return result;
+ result++;
+ next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
+ }
+ while (next_stmt);
+
+ return -1;
+ }
+
+
/* Get the defs for the rhs of STMT (collect them in OPRNDS_INFO), check that
they are of a valid type and that they match the defs of the first stmt of
the SLP group (stored in OPRNDS_INFO). */
*************** vect_print_slp_tree (int dump_kind, slp_
*** 991,997 ****
{
int i;
gimple stmt;
! slp_void_p child;
if (!node)
return;
--- 1016,1022 ----
{
int i;
gimple stmt;
! slp_tree child;
if (!node)
return;
*************** vect_print_slp_tree (int dump_kind, slp_
*** 1005,1011 ****
dump_printf (dump_kind, "\n");
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_print_slp_tree (dump_kind, (slp_tree) child);
}
--- 1030,1036 ----
dump_printf (dump_kind, "\n");
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_print_slp_tree (dump_kind, child);
}
*************** vect_mark_slp_stmts (slp_tree node, enum
*** 1019,1025 ****
{
int i;
gimple stmt;
! slp_void_p child;
if (!node)
return;
--- 1044,1050 ----
{
int i;
gimple stmt;
! slp_tree child;
if (!node)
return;
*************** vect_mark_slp_stmts (slp_tree node, enum
*** 1029,1035 ****
STMT_SLP_TYPE (vinfo_for_stmt (stmt)) = mark;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_mark_slp_stmts ((slp_tree) child, mark, j);
}
--- 1054,1060 ----
STMT_SLP_TYPE (vinfo_for_stmt (stmt)) = mark;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_mark_slp_stmts (child, mark, j);
}
*************** vect_mark_slp_stmts_relevant (slp_tree n
*** 1041,1047 ****
int i;
gimple stmt;
stmt_vec_info stmt_info;
! slp_void_p child;
if (!node)
return;
--- 1066,1072 ----
int i;
gimple stmt;
stmt_vec_info stmt_info;
! slp_tree child;
if (!node)
return;
*************** vect_mark_slp_stmts_relevant (slp_tree n
*** 1055,1061 ****
}
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_mark_slp_stmts_relevant ((slp_tree) child);
}
--- 1080,1086 ----
}
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_mark_slp_stmts_relevant (child);
}
*************** vect_slp_rearrange_stmts (slp_tree node,
*** 1129,1154 ****
{
gimple stmt;
vec<gimple> tmp_stmts;
! unsigned int index, i;
! slp_void_p child;
!
! if (!node)
! return;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_slp_rearrange_stmts ((slp_tree) child, group_size, permutation);
gcc_assert (group_size == SLP_TREE_SCALAR_STMTS (node).length ());
tmp_stmts.create (group_size);
!
! for (i = 0; i < group_size; i++)
! tmp_stmts.safe_push (NULL);
FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
! {
! index = permutation[i];
! tmp_stmts[index] = stmt;
! }
SLP_TREE_SCALAR_STMTS (node).release ();
SLP_TREE_SCALAR_STMTS (node) = tmp_stmts;
--- 1154,1171 ----
{
gimple stmt;
vec<gimple> tmp_stmts;
! unsigned int i;
! slp_tree child;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_slp_rearrange_stmts (child, group_size, permutation);
gcc_assert (group_size == SLP_TREE_SCALAR_STMTS (node).length ());
tmp_stmts.create (group_size);
! tmp_stmts.quick_grow_cleared (group_size);
FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
! tmp_stmts[permutation[i]] = stmt;
SLP_TREE_SCALAR_STMTS (node).release ();
SLP_TREE_SCALAR_STMTS (node) = tmp_stmts;
*************** vect_detect_hybrid_slp_stmts (slp_tree n
*** 1824,1830 ****
imm_use_iterator imm_iter;
gimple use_stmt;
stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
! slp_void_p child;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
struct loop *loop = NULL;
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
--- 1841,1847 ----
imm_use_iterator imm_iter;
gimple use_stmt;
stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
! slp_tree child;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
struct loop *loop = NULL;
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
*************** vect_detect_hybrid_slp_stmts (slp_tree n
*** 1855,1861 ****
vect_mark_slp_stmts (node, hybrid, i);
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_detect_hybrid_slp_stmts ((slp_tree) child);
}
--- 1872,1878 ----
vect_mark_slp_stmts (node, hybrid, i);
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_detect_hybrid_slp_stmts (child);
}
*************** vect_slp_analyze_node_operations (bb_vec
*** 1953,1965 ****
bool dummy;
int i;
gimple stmt;
! slp_void_p child;
if (!node)
return true;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! if (!vect_slp_analyze_node_operations (bb_vinfo, (slp_tree) child))
return false;
FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
--- 1970,1982 ----
bool dummy;
int i;
gimple stmt;
! slp_tree child;
if (!node)
return true;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! if (!vect_slp_analyze_node_operations (bb_vinfo, child))
return false;
FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
*************** vect_schedule_slp_instance (slp_tree nod
*** 3014,3027 ****
tree vectype;
int i;
slp_tree loads_node;
! slp_void_p child;
if (!node)
return false;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_schedule_slp_instance ((slp_tree) child, instance,
! vectorization_factor);
stmt = SLP_TREE_SCALAR_STMTS (node)[0];
stmt_info = vinfo_for_stmt (stmt);
--- 3031,3043 ----
tree vectype;
int i;
slp_tree loads_node;
! slp_tree child;
if (!node)
return false;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_schedule_slp_instance (child, instance, vectorization_factor);
stmt = SLP_TREE_SCALAR_STMTS (node)[0];
stmt_info = vinfo_for_stmt (stmt);
*************** vect_remove_slp_scalar_calls (slp_tree n
*** 3111,3117 ****
gimple stmt, new_stmt;
gimple_stmt_iterator gsi;
int i;
! slp_void_p child;
tree lhs;
stmt_vec_info stmt_info;
--- 3127,3133 ----
gimple stmt, new_stmt;
gimple_stmt_iterator gsi;
int i;
! slp_tree child;
tree lhs;
stmt_vec_info stmt_info;
*************** vect_remove_slp_scalar_calls (slp_tree n
*** 3119,3125 ****
return;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_remove_slp_scalar_calls ((slp_tree) child);
FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
{
--- 3135,3141 ----
return;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
! vect_remove_slp_scalar_calls (child);
FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
{
Index: gcc/tree-vectorizer.h
===================================================================
*** gcc/tree-vectorizer.h (revision 197621)
--- gcc/tree-vectorizer.h (working copy)
*************** add_stmt_info_to_vec (stmt_vector_for_co
*** 97,109 ****
/************************************************************************
SLP
************************************************************************/
! typedef void *slp_void_p;
/* A computation tree of an SLP instance. Each node corresponds to a group of
stmts to be packed in a SIMD stmt. */
! typedef struct _slp_tree {
/* Nodes that contain def-stmts of this node statements operands. */
! vec<slp_void_p> children;
/* A group of scalar stmts to be vectorized together. */
vec<gimple> stmts;
/* Vectorized stmt/s. */
--- 97,109 ----
/************************************************************************
SLP
************************************************************************/
! typedef struct _slp_tree *slp_tree;
/* A computation tree of an SLP instance. Each node corresponds to a group of
stmts to be packed in a SIMD stmt. */
! struct _slp_tree {
/* Nodes that contain def-stmts of this node statements operands. */
! vec<slp_tree> children;
/* A group of scalar stmts to be vectorized together. */
vec<gimple> stmts;
/* Vectorized stmt/s. */
*************** typedef struct _slp_tree {
*** 113,119 ****
scalar elements in one scalar iteration (GROUP_SIZE) multiplied by VF
divided by vector size. */
unsigned int vec_stmts_size;
! } *slp_tree;
/* SLP instance is a sequence of stmts in a loop that can be packed into
--- 113,119 ----
scalar elements in one scalar iteration (GROUP_SIZE) multiplied by VF
divided by vector size. */
unsigned int vec_stmts_size;
! };
/* SLP instance is a sequence of stmts in a loop that can be packed into
*************** extern tree vect_setup_realignment (gimp
*** 941,947 ****
extern void vect_transform_grouped_load (gimple, vec<tree> , int,
gimple_stmt_iterator *);
extern void vect_record_grouped_load_vectors (gimple, vec<tree> );
- extern int vect_get_place_in_interleaving_chain (gimple, gimple);
extern tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *);
extern tree vect_create_addr_base_for_vector_ref (gimple, gimple_seq *,
tree, struct loop *);
--- 941,946 ----
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-10-15 12:15 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-13 8:38 [PATCH] More vectorizer TLC Richard Biener
-- strict thread matches above, loose matches on Subject: below --
2015-10-15 11:37 Richard Biener
2015-10-15 12:15 ` Richard Biener
2015-10-14 13:56 Richard Biener
2015-10-14 8:32 Richard Biener
2015-10-12 8:30 Richard Biener
2013-04-18 14:16 Richard Biener
2013-04-09 14:53 Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).