diff options
author | Richard Biener <rguenther@suse.de> | 2017-08-02 06:57:12 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2017-08-02 06:57:12 +0000 |
commit | 04199738b48867d8c1d60e98578340047e3237da (patch) | |
tree | 905d24700ac5b7cbe04f6293de16e1be29143565 /gcc | |
parent | 232b2c6e1df5b174e1b73db29e71ddccb15ad5e1 (diff) | |
download | gcc-04199738b48867d8c1d60e98578340047e3237da.zip gcc-04199738b48867d8c1d60e98578340047e3237da.tar.gz gcc-04199738b48867d8c1d60e98578340047e3237da.tar.bz2 |
tree-vect-stmts.c (vectorizable_store): Perform vector extracts via vectors if supported...
2017-08-02 Richard Biener <rguenther@suse.de>
* tree-vect-stmts.c (vectorizable_store): Perform vector extracts
via vectors if supported, integer extracts via punning if supported
or otherwise vector extracts.
From-SVN: r250813
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 52 |
2 files changed, 57 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 46d3397..faacba2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2017-08-02 Richard Biener <rguenther@suse.de> + * tree-vect-stmts.c (vectorizable_store): Perform vector extracts + via vectors if supported, integer extracts via punning if supported + or otherwise vector extracts. + +2017-08-02 Richard Biener <rguenther@suse.de> + * tree-ssa-pre.c (bitmap_insert_into_set_1): Remove and inline into ... (bitmap_insert_into_set): ... this. diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index eecc1a4..ee32c56 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -6002,6 +6002,7 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, unsigned nstores = nunits; unsigned lnel = 1; tree ltype = elem_type; + tree lvectype = vectype; if (slp) { if (group_size < nunits @@ -6010,6 +6011,45 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, nstores = nunits / group_size; lnel = group_size; ltype = build_vector_type (elem_type, group_size); + lvectype = vectype; + + /* First check if vec_extract optab doesn't support extraction + of vector elts directly. */ + machine_mode elmode = TYPE_MODE (elem_type); + machine_mode vmode = mode_for_vector (elmode, group_size); + if (! VECTOR_MODE_P (vmode) + || (convert_optab_handler (vec_extract_optab, + TYPE_MODE (vectype), vmode) + == CODE_FOR_nothing)) + { + /* Try to avoid emitting an extract of vector elements + by performing the extracts using an integer type of the + same size, extracting from a vector of those and then + re-interpreting it as the original vector type if + supported. */ + unsigned lsize + = group_size * GET_MODE_BITSIZE (elmode); + elmode = mode_for_size (lsize, MODE_INT, 0); + vmode = mode_for_vector (elmode, nunits / group_size); + /* If we can't construct such a vector fall back to + element extracts from the original vector type and + element size stores. */ + if (VECTOR_MODE_P (vmode) + && (convert_optab_handler (vec_extract_optab, + vmode, elmode) + != CODE_FOR_nothing)) + { + nstores = nunits / group_size; + lnel = group_size; + ltype = build_nonstandard_integer_type (lsize, 1); + lvectype = build_vector_type (ltype, nstores); + } + /* Else fall back to vector extraction anyway. + Fewer stores are more important than avoiding spilling + of the vector we extract from. Compared to the + construction case in vectorizable_load no store-forwarding + issue exists here for reasonable archs. */ + } } else if (group_size >= nunits && group_size % nunits == 0) @@ -6017,6 +6057,7 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, nstores = 1; lnel = nunits; ltype = vectype; + lvectype = vectype; } ltype = build_aligned_type (ltype, TYPE_ALIGN (elem_type)); ncopies = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); @@ -6087,7 +6128,16 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, vec_oprnd); } } - + /* Pun the vector to extract from if necessary. */ + if (lvectype != vectype) + { + tree tem = make_ssa_name (lvectype); + gimple *pun + = gimple_build_assign (tem, build1 (VIEW_CONVERT_EXPR, + lvectype, vec_oprnd)); + vect_finish_stmt_generation (stmt, pun, gsi); + vec_oprnd = tem; + } for (i = 0; i < nstores; i++) { tree newref, newoff; |