rs6000: Suggest unroll factor for loop vectorization
authorKewen Lin <linkw@linux.ibm.com>
Tue, 13 Sep 2022 09:13:10 +0000 (04:13 -0500)
committerKewen Lin <linkw@linux.ibm.com>
Tue, 13 Sep 2022 10:39:04 +0000 (05:39 -0500)
commit0ee1548d96884d2689482054d925967a9a21d697
treebeafe3ac792e2ae39b4788765ab215d09c4b3d0c
parent2c867232df70d3de304714906b4198ecb262eb32
rs6000: Suggest unroll factor for loop vectorization

Commit r12-6679-g7ca1582ca60dc8 made vectorizer accept one
unroll factor to be applied to vectorization factor when
vectorizing the main loop, it would be suggested by target
when doing costing.

This patch introduces function determine_suggested_unroll_factor
for rs6000 port, to make it be able to suggest the unroll factor
for a given loop being vectorized.  Referring to aarch64 port
and basing on the analysis on SPEC2017 performance evaluation
results, it mainly considers these aspects:
  1) unroll option and pragma which can disable unrolling for the
     given loop;
  2) simple hardware resource model with issued non memory access
     vector insn per cycle;
  3) aggressive heuristics when iteration count is unknown:
     - reduction case to break cross iteration dependency;
     - emulated gather load;
  4) estimated iteration count when iteration count is unknown;

With this patch, SPEC2017 performance evaluation results on
Power8/9/10 are listed below (speedup pct.):

  * Power10
    - O2: all are neutral (excluding some noises);
    - Ofast: 510.parest_r +6.67%, the others are neutral
             (use ... for the followings);
    - Ofast + unroll: 510.parest_r +5.91%, ...
    - Ofast + LTO + PGO: 510.parest_r +3.00%, ...
    - Ofast + cheap vect cost: 510.parest_r +6.23%, ...
    - Ofast + very-cheap vect cost: all are neutral;

  * Power9
    - Ofast: 510.parest_r +8.73%, 538.imagick_r +11.18%
             (likely noise), 500.perlbench_r +1.84%, ...

  * Power8
    - Ofast: 510.parest_r +5.43%, ...;

This patch also introduces one documented parameter
rs6000-vect-unroll-limit= similar to what aarch64 proposes,
by evaluating on P8/P9/P10, the default value 4 is slightly
better than the other choices like 2 and 8.

It also parameterizes two other values as undocumented
parameters for future tweaking.  One parameter is
rs6000-vect-unroll-issue, it's to simply model hardware
resource for non memory access vector instructions to avoid
excessive unrolling, initially I tried to use the value in
the hook rs6000_issue_rate, but the evaluation showed it's
bad, so I evaluated different values 2/4/6/8 on P8/P9/P10 at
Ofast, the results showed the default value 4 is good enough
on these different architectures.  For a record, choice 8
could make 510.parest_r's gain become smaller or gone on
P8/P9/P10; choice 6 could make 503.bwaves_r degrade by more
than 1% on P8/P10; and choice 2 could make 538.imagick_r
degrade by 3.8%.  The other parameter is
rs6000-vect-unroll-reduc-threshold.  It's mainly inspired by
510.parest_r and tweaked as it, evaluating with different
values 0/1/2/3 for the threshold, it showed value 1 is the
best choice.  For a record, choice 0 could make 525.x264_r
degrade by 2% and 527.cam4_r degrade by 2.95% on P10,
548.exchange2_r degrade by 1.41% and 527.cam4_r degrade by
2.54% on P8; choice 2 and bigger values could make
510.parest_r's gain become smaller.

gcc/ChangeLog:

* config/rs6000/rs6000.cc (class rs6000_cost_data): Add new members
m_nstores, m_reduc_factor, m_gather_load and member function
determine_suggested_unroll_factor.
(rs6000_cost_data::update_target_cost_per_stmt): Update for m_nstores,
m_reduc_factor and m_gather_load.
(rs6000_cost_data::determine_suggested_unroll_factor): New function.
(rs6000_cost_data::finish_cost): Use determine_suggested_unroll_factor.
* config/rs6000/rs6000.opt (rs6000-vect-unroll-limit): New parameter.
(rs6000-vect-unroll-issue): Likewise.
(rs6000-vect-unroll-reduc-threshold): Likewise.
* doc/invoke.texi (rs6000-vect-unroll-limit): Document new parameter.
gcc/config/rs6000/rs6000.cc
gcc/config/rs6000/rs6000.opt
gcc/doc/invoke.texi