vect: Add a “very cheap” cost model
authorRichard Sandiford <richard.sandiford@arm.com>
Thu, 19 Nov 2020 16:49:37 +0000 (16:49 +0000)
committerRichard Sandiford <richard.sandiford@arm.com>
Thu, 19 Nov 2020 16:49:37 +0000 (16:49 +0000)
commit0b0061f4d83cd8eb181f7114a077237b95a0c144
treed1811c99a79cc35549621ad8542c892ed87ec107
parent5e6a43158d2e5b26616716c50badedd3400c6bea
vect: Add a “very cheap” cost model

Currently we have three vector cost models: cheap, dynamic and
unlimited.  -O2 -ftree-vectorize uses “cheap” by default, but that's
still relatively aggressive about peeling and aliasing checks,
and can lead to significant code size growth.

This patch adds an even more conservative choice, which for lack of
imagination I've called “very cheap”.  It only allows vectorisation
if the vector code entirely replaces the scalar code.  It also
requires one iteration of the vector loop to pay for itself,
regardless of how often the loop iterates.  (If the vector loop
needs multiple iterations to be beneficial then things are
probably too close to call, and the conservative thing would
be to stick with the scalar code.)

The idea is that this should be suitable for -O2, although the patch
doesn't change any defaults itself.

I tested this by building and running a bunch of workloads for SVE,
with three options:

  (1) -O2
  (2) -O2 -ftree-vectorize -fvect-cost-model=very-cheap
  (3) -O2 -ftree-vectorize [-fvect-cost-model=cheap]

All three builds used the default -msve-vector-bits=scalable and
ran with the minimum vector length of 128 bits, which should give
a worst-case bound for the performance impact.

The workloads included a mixture of microbenchmarks and full
applications.  Because it's quite an eclectic mix, there's not
much point giving exact figures.  The aim was more to get a general
impression.

Code size growth with (2) was much lower than with (3).  Only a
handful of tests increased by more than 5%, and all of them were
microbenchmarks.

In terms of performance, (2) was significantly faster than (1)
on microbenchmarks (as expected) but also on some full apps.
Again, performance only regressed on a handful of tests.

As expected, the performance of (3) vs. (1) and (3) vs. (2) is more
of a mixed bag.  There are several significant improvements with (3)
over (2), but also some (smaller) regressions.  That seems to be in
line with -O2 -ftree-vectorize being a kind of -O2.5.

The patch reorders vect_cost_model so that values are in order
of increasing aggressiveness, which makes it possible to use
range checks.  The value 0 still represents “unlimited”,
so “if (flag_vect_cost_model)” is still a meaningful check.

gcc/
* doc/invoke.texi (-fvect-cost-model): Add a very-cheap model.
* common.opt (fvect-cost-model=): Add very-cheap as a possible option.
(fsimd-cost-model=): Likewise.
(vect_cost_model): Add very-cheap.
* flag-types.h (vect_cost_model): Add VECT_COST_MODEL_VERY_CHEAP.
Put the values in order of increasing aggressiveness.
* tree-vect-data-refs.c (vect_enhance_data_refs_alignment): Use
range checks when comparing against VECT_COST_MODEL_CHEAP.
(vect_prune_runtime_alias_test_list): Do not allow any alias
checks for the very-cheap cost model.
* tree-vect-loop.c (vect_analyze_loop_costing): Do not allow
any peeling for the very-cheap cost model.  Also require one
iteration of the vector loop to pay for itself.

gcc/testsuite/
* gcc.dg/vect/vect-cost-model-1.c: New test.
* gcc.dg/vect/vect-cost-model-2.c: Likewise.
* gcc.dg/vect/vect-cost-model-3.c: Likewise.
* gcc.dg/vect/vect-cost-model-4.c: Likewise.
* gcc.dg/vect/vect-cost-model-5.c: Likewise.
* gcc.dg/vect/vect-cost-model-6.c: Likewise.
gcc/common.opt
gcc/doc/invoke.texi
gcc/flag-types.h
gcc/testsuite/gcc.dg/vect/vect-cost-model-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-cost-model-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-cost-model-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-cost-model-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-cost-model-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-cost-model-6.c [new file with mode: 0644]
gcc/tree-vect-data-refs.c
gcc/tree-vect-loop.c