[6/7] Explicitly classify vector loads and stores
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 6 Jul 2016 08:15:28 +0000 (08:15 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 6 Jul 2016 08:15:28 +0000 (08:15 +0000)
commit2de001eed013bb666f832694bc75b8f055ffdc76
tree3d3efc52fc8ace351e1981643b2b914a2edab7fe
parent4fb8ba9d357297206678a3e3eacf9292148eafb5
[6/7] Explicitly classify vector loads and stores

This is the main patch in the series.  It adds a new enum and routines
for classifying a vector load or store implementation.

Originally there were three motivations:

      (1) Reduce cut-&-paste

      (2) Make the chosen vectorisation strategy more obvious.  At the
          moment this is derived implicitly from various other bits of
          state (GROUPED, STRIDED, SLP, etc.)

      (3) Decouple the vectorisation strategy from those other bits of state,
          so that there can be a choice of implementation for a given scalar
          statement.  The specific problem here is that we class:

              for (...)
                {
                  ... = a[i * x];
                  ... = a[i * x + 1];
                }

          as "strided and grouped" but:

              for (...)
                {
                  ... = a[i * 7];
                  ... = a[i * 7 + 1];
                }

          as "non-strided and grouped".  Before the patch, "strided and
          grouped" loads would always try to use separate scalar loads
          while "non-strided and grouped" loads would always try to use
          load-and-permute.  But load-and-permute is never supported for
          a group size of 7, so the effect was that the first loop was
          vectorisable and the second wasn't.  It seemed odd that not
          knowing x (but accepting it could be 7) would allow more
          optimisation opportunities than knowing x is 7.

Unfortunately, it looks like we underestimate the cost of separate
scalar accesses on at least aarch64, so I've disabled (3) for now;
see the "if" statement at the end of get_load_store_type.  I think
the patch still does (1) and (2), so that's the justification for
it in its current form.  It also means that (3) is now simply a
case of removing the FIXME code, once the cost model problems have
been sorted out.  (I did wonder about adding a --param, but that
seems overkill.  I hope to get back to this during GCC 7 stage 1.)

Tested on aarch64-linux-gnu and x86_64-linux-gnu.

gcc/
* tree-vectorizer.h (vect_memory_access_type): New enum.
(_stmt_vec_info): Add a memory_access_type field.
(STMT_VINFO_MEMORY_ACCESS_TYPE): New macro.
(vect_model_store_cost): Take an access type instead of a boolean.
(vect_model_load_cost): Likewise.
* tree-vect-slp.c (vect_analyze_slp_cost_1): Update calls to
vect_model_store_cost and vect_model_load_cost.
* tree-vect-stmts.c (vec_load_store_type): New enum.
(vect_model_store_cost): Take an access type instead of a
store_lanes_p boolean.  Simplify tests.
(vect_model_load_cost): Likewise, but for load_lanes_p.
(get_group_load_store_type, get_load_store_type): New functions.
(vectorizable_store): Use get_load_store_type.  Record the access
type in STMT_VINFO_MEMORY_ACCESS_TYPE.
(vectorizable_load): Likewise.
(vectorizable_mask_load_store): Likewise.  Replace is_store
variable with vls_type.

From-SVN: r238038
gcc/ChangeLog
gcc/tree-vect-slp.c
gcc/tree-vect-stmts.c
gcc/tree-vectorizer.h