LCOV - code coverage report
Current view: top level - gcc - tree-vect-slp.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.5 % 5977 5529
Test Date: 2026-08-01 15:33:25 Functions: 95.1 % 182 173
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* SLP - Basic Block Vectorization
       2              :    Copyright (C) 2007-2026 Free Software Foundation, Inc.
       3              :    Contributed by Dorit Naishlos <dorit@il.ibm.com>
       4              :    and Ira Rosen <irar@il.ibm.com>
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify it under
       9              : the terms of the GNU General Public License as published by the Free
      10              : Software Foundation; either version 3, or (at your option) any later
      11              : version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      14              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16              : for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : #include "config.h"
      23              : #define INCLUDE_ALGORITHM
      24              : #include "system.h"
      25              : #include "coretypes.h"
      26              : #include "backend.h"
      27              : #include "target.h"
      28              : #include "rtl.h"
      29              : #include "tree.h"
      30              : #include "gimple.h"
      31              : #include "tree-pass.h"
      32              : #include "ssa.h"
      33              : #include "optabs-tree.h"
      34              : #include "insn-config.h"
      35              : #include "recog.h"            /* FIXME: for insn_data */
      36              : #include "fold-const.h"
      37              : #include "stor-layout.h"
      38              : #include "gimple-iterator.h"
      39              : #include "cfgloop.h"
      40              : #include "tree-vectorizer.h"
      41              : #include "langhooks.h"
      42              : #include "gimple-walk.h"
      43              : #include "dbgcnt.h"
      44              : #include "tree-vector-builder.h"
      45              : #include "vec-perm-indices.h"
      46              : #include "gimple-fold.h"
      47              : #include "internal-fn.h"
      48              : #include "dump-context.h"
      49              : #include "cfganal.h"
      50              : #include "tree-eh.h"
      51              : #include "tree-cfg.h"
      52              : #include "alloc-pool.h"
      53              : #include "sreal.h"
      54              : #include "predict.h"
      55              : 
      56              : #define REDUC_GROUP_FIRST_ELEMENT(S) \
      57              :   (gcc_checking_assert (!(S)->dr_aux.dr), (S)->first_element)
      58              : 
      59              : static bool vect_transform_slp_perm_load_1 (vec_info *, slp_tree,
      60              :                                             load_permutation_t &,
      61              :                                             const vec<tree> &,
      62              :                                             gimple_stmt_iterator *,
      63              :                                             poly_uint64, bool, bool,
      64              :                                             unsigned *,
      65              :                                             unsigned * = nullptr,
      66              :                                             bool = false);
      67              : static int vectorizable_slp_permutation_1 (vec_info *, gimple_stmt_iterator *,
      68              :                                            slp_tree, lane_permutation_t &,
      69              :                                            vec<slp_tree> &, bool);
      70              : static void vect_print_slp_tree (dump_flags_t, dump_location_t, slp_tree);
      71              : static bool vect_slp_can_convert_to_external (const vec<stmt_vec_info> &);
      72              : 
      73              : static object_allocator<_slp_tree> *slp_tree_pool;
      74              : static slp_tree slp_first_node;
      75              : 
      76              : void
      77      1124071 : vect_slp_init (void)
      78              : {
      79      1124071 :   slp_tree_pool = new object_allocator<_slp_tree> ("SLP nodes");
      80      1124071 : }
      81              : 
      82              : void
      83      1124071 : vect_slp_fini (void)
      84              : {
      85      1813456 :   while (slp_first_node)
      86       689385 :     delete slp_first_node;
      87      2248142 :   delete slp_tree_pool;
      88      1124071 :   slp_tree_pool = NULL;
      89      1124071 : }
      90              : 
      91              : void *
      92      8295382 : _slp_tree::operator new (size_t n)
      93              : {
      94      8295382 :   gcc_assert (n == sizeof (_slp_tree));
      95      8295382 :   return slp_tree_pool->allocate_raw ();
      96              : }
      97              : 
      98              : void
      99      8295382 : _slp_tree::operator delete (void *node, size_t n)
     100              : {
     101      8295382 :   gcc_assert (n == sizeof (_slp_tree));
     102      8295382 :   slp_tree_pool->remove_raw (node);
     103      8295382 : }
     104              : 
     105              : 
     106              : /* Initialize a SLP node.  */
     107              : 
     108      8295382 : _slp_tree::_slp_tree ()
     109              : {
     110      8295382 :   this->prev_node = NULL;
     111      8295382 :   if (slp_first_node)
     112      7270571 :     slp_first_node->prev_node = this;
     113      8295382 :   this->next_node = slp_first_node;
     114      8295382 :   slp_first_node = this;
     115      8295382 :   SLP_TREE_SCALAR_STMTS (this) = vNULL;
     116      8295382 :   SLP_TREE_SCALAR_OPS (this) = vNULL;
     117      8295382 :   SLP_TREE_LIVE_LANES (this) = vNULL;
     118      8295382 :   SLP_TREE_VEC_DEFS (this) = vNULL;
     119      8295382 :   SLP_TREE_CHILDREN (this) = vNULL;
     120      8295382 :   SLP_TREE_LOAD_PERMUTATION (this) = vNULL;
     121      8295382 :   SLP_TREE_LANE_PERMUTATION (this) = vNULL;
     122      8295382 :   SLP_TREE_DEF_TYPE (this) = vect_uninitialized_def;
     123      8295382 :   SLP_TREE_CODE (this) = ERROR_MARK;
     124      8295382 :   SLP_TREE_GS_SCALE (this) = 0;
     125      8295382 :   SLP_TREE_GS_BASE (this) = NULL_TREE;
     126      8295382 :   this->ldst_lanes = false;
     127      8295382 :   this->avoid_stlf_fail = false;
     128      8295382 :   SLP_TREE_VECTYPE (this) = NULL_TREE;
     129      8295382 :   SLP_TREE_REPRESENTATIVE (this) = NULL;
     130      8295382 :   this->cycle_info.id = -1;
     131      8295382 :   this->cycle_info.reduc_idx = -1;
     132      8295382 :   SLP_TREE_REF_COUNT (this) = 1;
     133      8295382 :   this->failed = NULL;
     134      8295382 :   this->max_nunits = 1;
     135      8295382 :   this->lanes = 0;
     136      8295382 :   SLP_TREE_TYPE (this) = undef_vec_info_type;
     137      8295382 :   this->data = NULL;
     138      8295382 : }
     139              : 
     140              : /* Tear down a SLP node.  */
     141              : 
     142      8295382 : _slp_tree::~_slp_tree ()
     143              : {
     144      8295382 :   if (this->prev_node)
     145      5094181 :     this->prev_node->next_node = this->next_node;
     146              :   else
     147      3201201 :     slp_first_node = this->next_node;
     148      8295382 :   if (this->next_node)
     149      6279980 :     this->next_node->prev_node = this->prev_node;
     150      8295382 :   SLP_TREE_CHILDREN (this).release ();
     151      8295382 :   SLP_TREE_SCALAR_STMTS (this).release ();
     152      8295382 :   SLP_TREE_SCALAR_OPS (this).release ();
     153      8295382 :   SLP_TREE_LIVE_LANES (this).release ();
     154      8295382 :   SLP_TREE_VEC_DEFS (this).release ();
     155      8295382 :   SLP_TREE_LOAD_PERMUTATION (this).release ();
     156      8295382 :   SLP_TREE_LANE_PERMUTATION (this).release ();
     157      8295382 :   if (this->failed)
     158      2251103 :     free (failed);
     159      8295382 :   if (this->data)
     160      1273928 :     delete this->data;
     161      8295382 : }
     162              : 
     163              : /* Push the single SSA definition in DEF to the vector of vector defs.  */
     164              : 
     165              : void
     166       532756 : _slp_tree::push_vec_def (gimple *def)
     167              : {
     168       532756 :   if (gphi *phi = dyn_cast <gphi *> (def))
     169        59487 :     vec_defs.quick_push (gimple_phi_result (phi));
     170              :   else
     171              :     {
     172       473269 :       def_operand_p defop = single_ssa_def_operand (def, SSA_OP_ALL_DEFS);
     173       473269 :       vec_defs.quick_push (get_def_from_ptr (defop));
     174              :     }
     175       532756 : }
     176              : 
     177              : /* Recursively free the memory allocated for the SLP tree rooted at NODE.  */
     178              : 
     179              : void
     180     15603971 : vect_free_slp_tree (slp_tree node)
     181              : {
     182     15603971 :   int i;
     183     15603971 :   slp_tree child;
     184              : 
     185     15603971 :   if (--SLP_TREE_REF_COUNT (node) != 0)
     186     15603971 :     return;
     187              : 
     188     11774058 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
     189      4168061 :     if (child)
     190      3788717 :       vect_free_slp_tree (child);
     191              : 
     192      7605997 :   delete node;
     193              : }
     194              : 
     195              : /* Return a location suitable for dumpings related to the SLP instance.  */
     196              : 
     197              : dump_user_location_t
     198      3533849 : _slp_instance::location () const
     199              : {
     200      3533849 :   if (!root_stmts.is_empty ())
     201       412030 :     return root_stmts[0]->stmt;
     202              :   else
     203      3121819 :     return SLP_TREE_SCALAR_STMTS (root)[0]->stmt;
     204              : }
     205              : 
     206              : 
     207              : /* Free the memory allocated for the SLP instance.  */
     208              : 
     209              : void
     210      1620171 : vect_free_slp_instance (slp_instance instance)
     211              : {
     212      1620171 :   vect_free_slp_tree (SLP_INSTANCE_TREE (instance));
     213      1620171 :   SLP_INSTANCE_LOADS (instance).release ();
     214      1620171 :   SLP_INSTANCE_ROOT_STMTS (instance).release ();
     215      1620171 :   SLP_INSTANCE_REMAIN_DEFS (instance).release ();
     216      1620171 :   instance->subgraph_entries.release ();
     217      1620171 :   instance->cost_vec.release ();
     218      1620171 :   free (instance);
     219      1620171 : }
     220              : 
     221              : 
     222              : /* Create a SLP node with NOPS children with CODE, either VEC_PERM_EXPR
     223              :    for a permute node or else ERROR_MARK.  */
     224              : 
     225              : slp_tree
     226        97525 : vect_create_new_slp_node (unsigned nops, tree_code code)
     227              : {
     228        97525 :   gcc_assert (code == ERROR_MARK || code == VEC_PERM_EXPR);
     229        97525 :   slp_tree node = new _slp_tree;
     230        97525 :   SLP_TREE_SCALAR_STMTS (node) = vNULL;
     231        97525 :   SLP_TREE_CHILDREN (node).create (nops);
     232        97525 :   SLP_TREE_DEF_TYPE (node) = vect_internal_def;
     233        97525 :   SLP_TREE_CODE (node) = code;
     234        97525 :   return node;
     235              : }
     236              : 
     237              : /* Create a SLP node inplace at NODE for SCALAR_STMTS and NOPS children.  */
     238              : 
     239              : static slp_tree
     240      3969114 : vect_create_new_slp_node (slp_tree node,
     241              :                           vec<stmt_vec_info> scalar_stmts, unsigned nops)
     242              : {
     243      3969114 :   SLP_TREE_SCALAR_STMTS (node) = scalar_stmts;
     244      3969114 :   SLP_TREE_CHILDREN (node).create (nops);
     245      3969114 :   SLP_TREE_DEF_TYPE (node) = vect_internal_def;
     246      3969114 :   SLP_TREE_REPRESENTATIVE (node) = scalar_stmts[0];
     247      3969114 :   SLP_TREE_LANES (node) = scalar_stmts.length ();
     248      3969114 :   return node;
     249              : }
     250              : 
     251              : /* Create an SLP node for SCALAR_STMTS and NOPS children.  */
     252              : 
     253              : static slp_tree
     254         8377 : vect_create_new_slp_node (vec<stmt_vec_info> scalar_stmts, unsigned nops)
     255              : {
     256         8377 :   return vect_create_new_slp_node (new _slp_tree, scalar_stmts, nops);
     257              : }
     258              : 
     259              : /* Create a vect_external_def SLP node inplace at NODE for scalar
     260              :    operands OPS.  */
     261              : 
     262              : static slp_tree
     263      1965688 : vect_create_new_slp_node (slp_tree node, vec<tree> ops)
     264              : {
     265      1965688 :   SLP_TREE_SCALAR_OPS (node) = ops;
     266      1965688 :   SLP_TREE_DEF_TYPE (node) = vect_external_def;
     267            0 :   SLP_TREE_LANES (node) = ops.length ();
     268      1965688 :   return node;
     269              : }
     270              : 
     271              : /* Create a vect_external_def SLP node for scalar operands OPS.  */
     272              : 
     273              : static slp_tree
     274      1965688 : vect_create_new_slp_node (vec<tree> ops)
     275              : {
     276      1965688 :   return vect_create_new_slp_node (new _slp_tree, ops);
     277              : }
     278              : 
     279              : 
     280              : /* This structure is used in creation of an SLP tree.  Each instance
     281              :    corresponds to the same operand in a group of scalar stmts in an SLP
     282              :    node.  */
     283              : typedef struct _slp_oprnd_info
     284              : {
     285              :   /* Def-stmts for the operands.  */
     286              :   vec<stmt_vec_info> def_stmts;
     287              :   /* Operands.  */
     288              :   vec<tree> ops;
     289              :   /* Information about the first statement, its vector def-type, type, the
     290              :      operand itself in case it's constant, and an indication if it's a pattern
     291              :      stmt and gather/scatter info.  */
     292              :   tree first_op_type;
     293              :   enum vect_def_type first_dt;
     294              :   bool any_pattern;
     295              :   bool first_gs_p;
     296              :   gather_scatter_info first_gs_info;
     297              : } *slp_oprnd_info;
     298              : 
     299              : 
     300              : /* Allocate operands info for NOPS operands, and GROUP_SIZE def-stmts for each
     301              :    operand.  */
     302              : static vec<slp_oprnd_info>
     303      3531379 : vect_create_oprnd_info (int nops, int group_size)
     304              : {
     305      3531379 :   int i;
     306      3531379 :   slp_oprnd_info oprnd_info;
     307      3531379 :   vec<slp_oprnd_info> oprnds_info;
     308              : 
     309      3531379 :   oprnds_info.create (nops);
     310     12708069 :   for (i = 0; i < nops; i++)
     311              :     {
     312      5645311 :       oprnd_info = XNEW (struct _slp_oprnd_info);
     313      5645311 :       oprnd_info->def_stmts.create (group_size);
     314      5645311 :       oprnd_info->ops.create (group_size);
     315      5645311 :       oprnd_info->first_dt = vect_uninitialized_def;
     316      5645311 :       oprnd_info->first_op_type = NULL_TREE;
     317      5645311 :       oprnd_info->any_pattern = false;
     318      5645311 :       oprnd_info->first_gs_p = false;
     319      5645311 :       oprnds_info.quick_push (oprnd_info);
     320              :     }
     321              : 
     322      3531379 :   return oprnds_info;
     323              : }
     324              : 
     325              : 
     326              : /* Free operands info.  */
     327              : 
     328              : static void
     329      3531379 : vect_free_oprnd_info (vec<slp_oprnd_info> &oprnds_info)
     330              : {
     331      3531379 :   int i;
     332      3531379 :   slp_oprnd_info oprnd_info;
     333              : 
     334      9176690 :   FOR_EACH_VEC_ELT (oprnds_info, i, oprnd_info)
     335              :     {
     336      5645311 :       oprnd_info->def_stmts.release ();
     337      5645311 :       oprnd_info->ops.release ();
     338      5645311 :       XDELETE (oprnd_info);
     339              :     }
     340              : 
     341      3531379 :   oprnds_info.release ();
     342      3531379 : }
     343              : 
     344              : /* Return the execution frequency of NODE (so that a higher value indicates
     345              :    a "more important" node when optimizing for speed).  */
     346              : 
     347              : static sreal
     348      3655518 : vect_slp_node_weight (slp_tree node)
     349              : {
     350      3655518 :   stmt_vec_info stmt_info = vect_orig_stmt (SLP_TREE_REPRESENTATIVE (node));
     351      3655518 :   basic_block bb = gimple_bb (stmt_info->stmt);
     352      3655518 :   return bb->count.to_sreal_scale (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count);
     353              : }
     354              : 
     355              : /* Return true if STMTS contains a pattern statement.  */
     356              : 
     357              : static bool
     358        31046 : vect_contains_pattern_stmt_p (vec<stmt_vec_info> stmts)
     359              : {
     360        31046 :   stmt_vec_info stmt_info;
     361        31046 :   unsigned int i;
     362        89446 :   FOR_EACH_VEC_ELT (stmts, i, stmt_info)
     363        66393 :     if (stmt_info && is_pattern_stmt_p (stmt_info))
     364              :       return true;
     365              :   return false;
     366              : }
     367              : 
     368              : /* Return true when all lanes in the external or constant NODE have
     369              :    the same value.  */
     370              : 
     371              : static bool
     372       648698 : vect_slp_tree_uniform_p (slp_tree node)
     373              : {
     374       648698 :   gcc_assert (SLP_TREE_DEF_TYPE (node) == vect_constant_def
     375              :               || SLP_TREE_DEF_TYPE (node) == vect_external_def);
     376              : 
     377              :   /* Pre-existing vectors.  */
     378      1137894 :   if (SLP_TREE_SCALAR_OPS (node).is_empty ())
     379              :     return false;
     380              : 
     381              :   unsigned i;
     382              :   tree op, first = NULL_TREE;
     383      1490190 :   FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
     384      1330688 :     if (!first)
     385              :       first = op;
     386       681990 :     else if (!operand_equal_p (first, op, 0))
     387              :       return false;
     388              : 
     389              :   return true;
     390              : }
     391              : 
     392              : /* Find the place of the data-ref in STMT_INFO in the interleaving chain
     393              :    that starts from FIRST_STMT_INFO.  Return -1 if the data-ref is not a part
     394              :    of the chain.  */
     395              : 
     396              : int
     397       749780 : vect_get_place_in_interleaving_chain (stmt_vec_info stmt_info,
     398              :                                       stmt_vec_info first_stmt_info)
     399              : {
     400       749780 :   stmt_vec_info next_stmt_info = first_stmt_info;
     401       749780 :   int result = 0;
     402              : 
     403       749780 :   if (first_stmt_info != DR_GROUP_FIRST_ELEMENT (stmt_info))
     404              :     return -1;
     405              : 
     406      2129711 :   do
     407              :     {
     408      2129711 :       if (next_stmt_info == stmt_info)
     409              :         return result;
     410      1379931 :       next_stmt_info = DR_GROUP_NEXT_ELEMENT (next_stmt_info);
     411      1379931 :       if (next_stmt_info)
     412      1379931 :         result += DR_GROUP_GAP (next_stmt_info);
     413              :     }
     414      1379931 :   while (next_stmt_info);
     415              : 
     416              :   return -1;
     417              : }
     418              : 
     419              : /* Check whether it is possible to load COUNT elements of type ELT_TYPE
     420              :    using the method implemented by duplicate_and_interleave.  Return true
     421              :    if so, returning the number of intermediate vectors in *NVECTORS_OUT
     422              :    (if nonnull) and the type of each intermediate vector in *VECTOR_TYPE_OUT
     423              :    (if nonnull).  */
     424              : 
     425              : bool
     426            0 : can_duplicate_and_interleave_p (vec_info *vinfo, unsigned int count,
     427              :                                 tree elt_type, unsigned int *nvectors_out,
     428              :                                 tree *vector_type_out,
     429              :                                 tree *permutes)
     430              : {
     431            0 :   tree base_vector_type = get_vectype_for_scalar_type (vinfo, elt_type, count);
     432            0 :   if (!base_vector_type || !VECTOR_MODE_P (TYPE_MODE (base_vector_type)))
     433            0 :     return false;
     434              : 
     435            0 :   machine_mode base_vector_mode = TYPE_MODE (base_vector_type);
     436            0 :   poly_int64 elt_bytes = count * GET_MODE_UNIT_SIZE (base_vector_mode);
     437            0 :   unsigned int nvectors = 1;
     438            0 :   for (;;)
     439              :     {
     440            0 :       scalar_int_mode int_mode;
     441            0 :       poly_int64 elt_bits = elt_bytes * BITS_PER_UNIT;
     442            0 :       if (int_mode_for_size (elt_bits, 1).exists (&int_mode))
     443              :         {
     444              :           /* Get the natural vector type for this SLP group size.  */
     445            0 :           tree int_type = build_nonstandard_integer_type
     446            0 :             (GET_MODE_BITSIZE (int_mode), 1);
     447            0 :           tree vector_type
     448            0 :             = get_vectype_for_scalar_type (vinfo, int_type, count);
     449            0 :           poly_int64 half_nelts;
     450            0 :           if (vector_type
     451            0 :               && VECTOR_MODE_P (TYPE_MODE (vector_type))
     452            0 :               && known_eq (GET_MODE_SIZE (TYPE_MODE (vector_type)),
     453              :                            GET_MODE_SIZE (base_vector_mode))
     454            0 :               && multiple_p (GET_MODE_NUNITS (TYPE_MODE (vector_type)),
     455              :                              2, &half_nelts))
     456              :             {
     457              :               /* Try fusing consecutive sequences of COUNT / NVECTORS elements
     458              :                  together into elements of type INT_TYPE and using the result
     459              :                  to build NVECTORS vectors.  */
     460            0 :               poly_uint64 nelts = GET_MODE_NUNITS (TYPE_MODE (vector_type));
     461            0 :               vec_perm_builder sel1 (nelts, 2, 3);
     462            0 :               vec_perm_builder sel2 (nelts, 2, 3);
     463              : 
     464            0 :               for (unsigned int i = 0; i < 3; ++i)
     465              :                 {
     466            0 :                   sel1.quick_push (i);
     467            0 :                   sel1.quick_push (i + nelts);
     468            0 :                   sel2.quick_push (half_nelts + i);
     469            0 :                   sel2.quick_push (half_nelts + i + nelts);
     470              :                 }
     471            0 :               vec_perm_indices indices1 (sel1, 2, nelts);
     472            0 :               vec_perm_indices indices2 (sel2, 2, nelts);
     473            0 :               machine_mode vmode = TYPE_MODE (vector_type);
     474            0 :               if (can_vec_perm_const_p (vmode, vmode, indices1)
     475            0 :                   && can_vec_perm_const_p (vmode, vmode, indices2))
     476              :                 {
     477            0 :                   if (nvectors_out)
     478            0 :                     *nvectors_out = nvectors;
     479            0 :                   if (vector_type_out)
     480            0 :                     *vector_type_out = vector_type;
     481            0 :                   if (permutes)
     482              :                     {
     483            0 :                       permutes[0] = vect_gen_perm_mask_checked (vector_type,
     484              :                                                                 indices1);
     485            0 :                       permutes[1] = vect_gen_perm_mask_checked (vector_type,
     486              :                                                                 indices2);
     487              :                     }
     488            0 :                   return true;
     489              :                 }
     490            0 :             }
     491              :         }
     492            0 :       if (!multiple_p (elt_bytes, 2, &elt_bytes))
     493              :         return false;
     494            0 :       nvectors *= 2;
     495              :       /* We need to be able to fuse COUNT / NVECTORS elements together.  */
     496            0 :       if (!multiple_p (count, nvectors))
     497              :         return false;
     498              :     }
     499              : }
     500              : 
     501              : /* Return true if DTA and DTB match.  */
     502              : 
     503              : static bool
     504     17234384 : vect_def_types_match (enum vect_def_type dta, enum vect_def_type dtb)
     505              : {
     506     17234384 :   return (dta == dtb
     507       364628 :           || ((dta == vect_external_def || dta == vect_constant_def)
     508       225539 :               && (dtb == vect_external_def || dtb == vect_constant_def)));
     509              : }
     510              : 
     511              : #define GATHER_SCATTER_OFFSET (-3)
     512              : 
     513              : /* For most SLP statements, there is a one-to-one mapping between
     514              :    gimple arguments and child nodes.  If that is not true for STMT,
     515              :    return an array that contains:
     516              : 
     517              :    - the number of child nodes, followed by
     518              :    - for each child node, the index of the argument associated with that node.
     519              :      The special index -1 is the first operand of an embedded comparison and
     520              :      the special index -2 is the second operand of an embedded comparison.
     521              :      The special index -3 is the offset of a gather as analyzed by
     522              :      vect_check_gather_scatter.
     523              : 
     524              :    SWAP is as for vect_get_and_check_slp_defs.  */
     525              : 
     526              : static const int *
     527     25271897 : vect_get_operand_map (const gimple *stmt, bool gather_scatter_p,
     528              :                       unsigned char swap)
     529              : {
     530     25271897 :   static const int no_arg_map[] = { 0 };
     531     25271897 :   static const int arg0_map[] = { 1, 0 };
     532     25271897 :   static const int arg2_map[] = { 1, 2 };
     533     25271897 :   static const int arg2_arg3_map[] = { 2, 2, 3 };
     534     25271897 :   static const int arg2_arg4_map[] = { 2, 2, 4 };
     535     25271897 :   static const int arg2_arg5_arg6_map[] = { 3, 2, 5, 6 };
     536     25271897 :   static const int arg2_arg4_arg5_map[] = { 3, 2, 4, 5 };
     537     25271897 :   static const int arg3_arg2_map[] = { 2, 3, 2 };
     538     25271897 :   static const int op00_map[] = { 1, -1 };
     539     25271897 :   static const int op1_op0_map[] = { 2, 1, 0 };
     540     25271897 :   static const int off_map[] = { 1, GATHER_SCATTER_OFFSET };
     541     25271897 :   static const int off_op0_map[] = { 2, GATHER_SCATTER_OFFSET, 0 };
     542     25271897 :   static const int off_arg2_arg3_map[] = { 3, GATHER_SCATTER_OFFSET, 2, 3 };
     543     25271897 :   static const int off_arg3_arg2_map[] = { 3, GATHER_SCATTER_OFFSET, 3, 2 };
     544     25271897 :   static const int mask_call_maps[6][7] = {
     545              :         { 1, 1, },
     546              :         { 2, 1, 2, },
     547              :         { 3, 1, 2, 3, },
     548              :         { 4, 1, 2, 3, 4, },
     549              :         { 5, 1, 2, 3, 4, 5, },
     550              :         { 6, 1, 2, 3, 4, 5, 6 },
     551              :   };
     552              : 
     553     25271897 :   gcc_checking_assert (!swap
     554              :                        || !is_gimple_assign (stmt)
     555              :                        || TREE_CODE_CLASS
     556              :                             (gimple_assign_rhs_code (stmt)) == tcc_comparison
     557              :                        || commutative_tree_code
     558              :                             (gimple_assign_rhs_code (stmt)));
     559              : 
     560     25271897 :   if (auto assign = dyn_cast<const gassign *> (stmt))
     561              :     {
     562     23720954 :       tree_code code = gimple_assign_rhs_code (assign);
     563     23720954 :       if (code == COND_EXPR
     564     23720954 :           && COMPARISON_CLASS_P (gimple_assign_rhs1 (assign)))
     565            0 :         gcc_unreachable ();
     566     23720954 :       else if ((TREE_CODE_CLASS (code) == tcc_comparison
     567     22215769 :                 || commutative_tree_code (code))
     568     32862339 :                && swap)
     569              :         return op1_op0_map;
     570     23677883 :       else if (code == VIEW_CONVERT_EXPR)
     571              :         return op00_map;
     572     23668714 :       else if (gather_scatter_p)
     573        45960 :         return (TREE_CODE (gimple_assign_lhs (assign)) != SSA_NAME
     574        45960 :                 ? off_op0_map : off_map);
     575              :     }
     576      1550943 :   else if (auto call = dyn_cast<const gcall *> (stmt))
     577              :     {
     578       176621 :       if (gimple_call_internal_p (call))
     579        93637 :         switch (gimple_call_internal_fn (call))
     580              :           {
     581        16137 :           case IFN_MASK_LOAD:
     582        27548 :             return gather_scatter_p ? off_arg2_arg3_map : arg2_arg3_map;
     583              : 
     584              :           case IFN_GATHER_LOAD:
     585              :             return arg2_map;
     586              : 
     587            0 :           case IFN_MASK_GATHER_LOAD:
     588            0 :           case IFN_MASK_LEN_GATHER_LOAD:
     589            0 :             return arg2_arg5_arg6_map;
     590              : 
     591            0 :           case IFN_SCATTER_STORE:
     592            0 :             return arg2_arg4_map;
     593              : 
     594            0 :           case IFN_MASK_SCATTER_STORE:
     595            0 :           case IFN_MASK_LEN_SCATTER_STORE:
     596            0 :             return arg2_arg4_arg5_map;
     597              : 
     598         9125 :           case IFN_MASK_STORE:
     599        16828 :             return gather_scatter_p ? off_arg3_arg2_map : arg3_arg2_map;
     600              : 
     601          996 :           case IFN_MASK_CALL:
     602          996 :             {
     603          996 :               unsigned nargs = gimple_call_num_args (call);
     604          996 :               if (nargs >= 2 && nargs <= 7)
     605          996 :                 return mask_call_maps[nargs-2];
     606              :               else
     607              :                 return nullptr;
     608              :             }
     609              : 
     610          278 :           case IFN_CLZ:
     611          278 :           case IFN_CTZ:
     612          278 :             return arg0_map;
     613              : 
     614         7290 :           case IFN_GOMP_SIMD_LANE:
     615         7290 :             return no_arg_map;
     616              : 
     617              :           default:
     618              :             break;
     619              :           }
     620              :     }
     621              :   return nullptr;
     622              : }
     623              : 
     624              : static const int *
     625     25250562 : vect_get_operand_map (const stmt_vec_info stmt, unsigned char swap = 0)
     626              : {
     627            0 :   return vect_get_operand_map (stmt->stmt, STMT_VINFO_GATHER_SCATTER_P (stmt),
     628            0 :                                swap);
     629              : }
     630              : 
     631              : /* Return the SLP node child index for operand OP of STMT.  */
     632              : 
     633              : int
     634      1390673 : vect_slp_child_index_for_operand (const stmt_vec_info stmt, int op)
     635              : {
     636      1390673 :   const int *opmap = vect_get_operand_map (stmt);
     637      1390673 :   if (!opmap)
     638              :     return op;
     639        21811 :   for (int i = 1; i < 1 + opmap[0]; ++i)
     640        21811 :     if (opmap[i] == op)
     641        12180 :       return i - 1;
     642            0 :   gcc_unreachable ();
     643              : }
     644              : 
     645              : /* Helper class for mapping of GIMPLE operands to SLP children.  */
     646              : /* ???  Add vect_slp_child_index_for_operand here and amend opmaps
     647              :    with the full reverse mapping and indicating the position of the
     648              :    first commutative operand index, eliding the swap_p argument from
     649              :    vect_get_operand_map.  Adjust all consumers.  */
     650              : 
     651              : struct slp_oprnds {
     652              :   slp_oprnds (stmt_vec_info);
     653              :   tree get_op_for_slp_child (stmt_vec_info, unsigned);
     654              :   const int *opmap;
     655              :   const unsigned int num_slp_children;
     656              : };
     657              : 
     658      4585778 : slp_oprnds::slp_oprnds (stmt_vec_info stmt_info)
     659      4585778 :   : opmap (vect_get_operand_map (stmt_info)),
     660      4585778 :     num_slp_children (opmap ? opmap[0] : gimple_num_args (stmt_info->stmt))
     661              : {
     662      4585778 : }
     663              : 
     664              : /* For SLP child number N get the corresponding tree operand from GIMPLE
     665              :    statement described by STMT_INFO.  */
     666              : 
     667              : tree
     668      5121490 : slp_oprnds::get_op_for_slp_child (stmt_vec_info stmt_info, unsigned n)
     669              : {
     670      5121490 :   gcc_assert (n < num_slp_children);
     671      5121490 :   int opno = opmap ? opmap[n + 1] : (int) n;
     672      5121490 :   if (opno == GATHER_SCATTER_OFFSET)
     673            0 :     gcc_unreachable (); // TODO
     674      5121490 :   else if (opno < 0)
     675         2522 :     return TREE_OPERAND (gimple_arg (stmt_info->stmt, 0), -1 - opno);
     676              :   else
     677      5118968 :     return gimple_arg (stmt_info->stmt, opno);
     678              : }
     679              : 
     680              : /* Get the defs for the rhs of STMT (collect them in OPRNDS_INFO), check that
     681              :    they are of a valid type and that they match the defs of the first stmt of
     682              :    the SLP group (stored in OPRNDS_INFO).  This function tries to match stmts
     683              :    by swapping operands of STMTS[STMT_NUM] when possible.  Non-zero SWAP
     684              :    indicates swap is required for cond_expr stmts.  Specifically, SWAP
     685              :    is 1 if STMT is cond and operands of comparison need to be swapped;
     686              :    SWAP is 2 if STMT is cond and code of comparison needs to be inverted.
     687              : 
     688              :    If there was a fatal error return -1; if the error could be corrected by
     689              :    swapping operands of father node of this one, return 1; if everything is
     690              :    ok return 0.  */
     691              : static int
     692     13065853 : vect_get_and_check_slp_defs (vec_info *vinfo, tree vectype, unsigned char swap,
     693              :                              bool *skip_args,
     694              :                              vec<stmt_vec_info> stmts, unsigned stmt_num,
     695              :                              vec<slp_oprnd_info> *oprnds_info)
     696              : {
     697     13065853 :   stmt_vec_info stmt_info = stmts[stmt_num];
     698     13065853 :   tree oprnd;
     699     13065853 :   unsigned int i, number_of_oprnds;
     700     13065853 :   enum vect_def_type dt = vect_uninitialized_def;
     701     13065853 :   slp_oprnd_info oprnd_info;
     702     13065853 :   gather_scatter_info gs_info;
     703     13065853 :   unsigned int gs_op = -1u;
     704     13065853 :   unsigned int commutative_op = -1U;
     705     13065853 :   bool first = stmt_num == 0;
     706              : 
     707     13065853 :   if (!stmt_info)
     708              :     {
     709            0 :       for (auto oi : *oprnds_info)
     710              :         {
     711            0 :           oi->def_stmts.quick_push (NULL);
     712            0 :           oi->ops.quick_push (NULL_TREE);
     713              :         }
     714              :       return 0;
     715              :     }
     716              : 
     717     13065853 :   if (!is_a<gcall *> (stmt_info->stmt)
     718              :       && !is_a<gassign *> (stmt_info->stmt)
     719              :       && !is_a<gphi *> (stmt_info->stmt))
     720              :     return -1;
     721              : 
     722     13065853 :   number_of_oprnds = gimple_num_args (stmt_info->stmt);
     723     13065853 :   const int *map = vect_get_operand_map (stmt_info, swap);
     724     13065853 :   if (map)
     725        80256 :     number_of_oprnds = *map++;
     726     13065853 :   if (gcall *stmt = dyn_cast <gcall *> (stmt_info->stmt))
     727              :     {
     728        54584 :       if (gimple_call_internal_p (stmt))
     729              :         {
     730        33284 :           internal_fn ifn = gimple_call_internal_fn (stmt);
     731        33284 :           commutative_op = first_commutative_argument (ifn);
     732        33284 :           if (internal_gather_scatter_fn_p (ifn))
     733              :             {
     734            0 :               vect_describe_gather_scatter_call
     735            0 :                 (stmt_info,
     736            0 :                  first ? &(*oprnds_info)[0]->first_gs_info : &gs_info);
     737            0 :               if (first)
     738            0 :                 (*oprnds_info)[0]->first_gs_p = true;
     739              :               gs_op = 0;
     740              :             }
     741              :         }
     742              :     }
     743     13011269 :   else if (gassign *stmt = dyn_cast <gassign *> (stmt_info->stmt))
     744              :     {
     745     15141366 :       if (commutative_tree_code (gimple_assign_rhs_code (stmt)))
     746      8520170 :         commutative_op = 0;
     747              :     }
     748              : 
     749     13065853 :   bool swapped = (swap != 0);
     750     13065853 :   bool backedge = false;
     751     13065853 :   enum vect_def_type *dts = XALLOCAVEC (enum vect_def_type, number_of_oprnds);
     752     36135909 :   for (i = 0; i < number_of_oprnds; i++)
     753              :     {
     754     23071302 :       oprnd_info = (*oprnds_info)[i];
     755     23071302 :       int opno = map ? map[i] : int (i);
     756     23071302 :       if (opno == GATHER_SCATTER_OFFSET)
     757              :         {
     758        24053 :           gcc_assert (STMT_VINFO_GATHER_SCATTER_P (stmt_info));
     759        24053 :           if (!is_a <loop_vec_info> (vinfo)
     760        24053 :               || !vect_check_gather_scatter (stmt_info, vectype,
     761              :                                              as_a <loop_vec_info> (vinfo),
     762              :                                              first ? &oprnd_info->first_gs_info
     763              :                                              : &gs_info))
     764         1246 :             return -1;
     765              : 
     766        24053 :           if (first)
     767              :             {
     768        23779 :               oprnd_info->first_gs_p = true;
     769        23779 :               oprnd = oprnd_info->first_gs_info.offset;
     770              :             }
     771              :           else
     772              :             {
     773          274 :               gs_op = i;
     774          274 :               oprnd = gs_info.offset;
     775              :             }
     776              :         }
     777     23047249 :       else if (opno < 0)
     778         3083 :         oprnd = TREE_OPERAND (gimple_arg (stmt_info->stmt, 0), -1 - opno);
     779              :       else
     780              :         {
     781     23044166 :           oprnd = gimple_arg (stmt_info->stmt, opno);
     782     23044166 :           if (gphi *stmt = dyn_cast <gphi *> (stmt_info->stmt))
     783              :             {
     784      1269600 :               edge e = gimple_phi_arg_edge (stmt, opno);
     785      2539200 :               backedge = (is_a <bb_vec_info> (vinfo)
     786      1962472 :                           ? e->flags & EDGE_DFS_BACK
     787       692872 :                           : dominated_by_p (CDI_DOMINATORS, e->src,
     788       692872 :                                             gimple_bb (stmt_info->stmt)));
     789              :             }
     790              :         }
     791              : 
     792     23071302 :       stmt_vec_info def_stmt_info;
     793     23071302 :       if (!vect_is_simple_use (oprnd, vinfo, &dts[i], &def_stmt_info))
     794              :         {
     795          991 :           if (dump_enabled_p ())
     796            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     797              :                              "Build SLP failed: can't analyze def for %T\n",
     798              :                              oprnd);
     799              : 
     800          991 :           return -1;
     801              :         }
     802              : 
     803     23070311 :       if (skip_args[i])
     804              :         {
     805       556021 :           oprnd_info->def_stmts.quick_push (NULL);
     806       556021 :           oprnd_info->ops.quick_push (NULL_TREE);
     807       556021 :           oprnd_info->first_dt = vect_uninitialized_def;
     808       556021 :           continue;
     809              :         }
     810              : 
     811     22514290 :       oprnd_info->def_stmts.quick_push (def_stmt_info);
     812     22514290 :       oprnd_info->ops.quick_push (oprnd);
     813              : 
     814     22514290 :       if (def_stmt_info
     815     22514290 :           && is_pattern_stmt_p (def_stmt_info))
     816              :         {
     817       442937 :           if (STMT_VINFO_RELATED_STMT (vect_orig_stmt (def_stmt_info))
     818              :               != def_stmt_info)
     819       317644 :             oprnd_info->any_pattern = true;
     820              :           else
     821              :             /* If we promote this to external use the original stmt def.  */
     822       125293 :             oprnd_info->ops.last ()
     823       250586 :               = gimple_get_lhs (vect_orig_stmt (def_stmt_info)->stmt);
     824              :         }
     825              : 
     826              :       /* If there's a extern def on a backedge make sure we can
     827              :          code-generate at the region start.
     828              :          ???  This is another case that could be fixed by adjusting
     829              :          how we split the function but at the moment we'd have conflicting
     830              :          goals there.  */
     831     22514290 :       if (backedge
     832       173389 :           && dts[i] == vect_external_def
     833          276 :           && is_a <bb_vec_info> (vinfo)
     834          276 :           && TREE_CODE (oprnd) == SSA_NAME
     835          255 :           && !SSA_NAME_IS_DEFAULT_DEF (oprnd)
     836     22514545 :           && !dominated_by_p (CDI_DOMINATORS, vinfo->bbs[0],
     837          255 :                               gimple_bb (SSA_NAME_DEF_STMT (oprnd))))
     838              :         {
     839          255 :           if (dump_enabled_p ())
     840            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     841              :                              "Build SLP failed: extern def %T only defined "
     842              :                              "on backedge\n", oprnd);
     843          255 :           return -1;
     844              :         }
     845              : 
     846     22514035 :       if (first)
     847              :         {
     848      5128045 :           tree type = TREE_TYPE (oprnd);
     849      5128045 :           dt = dts[i];
     850              : 
     851              :           /* For the swapping logic below force vect_reduction_def
     852              :              for the reduction op in a SLP reduction group.  */
     853      5128045 :           if (!STMT_VINFO_DATA_REF (stmt_info)
     854      3939521 :               && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
     855         5242 :               && (int)i == STMT_VINFO_REDUC_IDX (stmt_info)
     856      5130626 :               && def_stmt_info)
     857         2581 :             dts[i] = dt = vect_reduction_def;
     858              : 
     859              :           /* Check the types of the definition.  */
     860      5128045 :           switch (dt)
     861              :             {
     862      5128045 :             case vect_external_def:
     863      5128045 :             case vect_constant_def:
     864      5128045 :             case vect_internal_def:
     865      5128045 :             case vect_reduction_def:
     866      5128045 :             case vect_double_reduction_def:
     867      5128045 :             case vect_induction_def:
     868      5128045 :             case vect_nested_cycle:
     869      5128045 :             case vect_first_order_recurrence:
     870      5128045 :               break;
     871              : 
     872            0 :             default:
     873              :               /* FORNOW: Not supported.  */
     874            0 :               if (dump_enabled_p ())
     875            0 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     876              :                                  "Build SLP failed: illegal type of def %T\n",
     877              :                                  oprnd);
     878            0 :               return -1;
     879              :             }
     880              : 
     881      5128045 :           oprnd_info->first_dt = dt;
     882      5128045 :           oprnd_info->first_op_type = type;
     883              :         }
     884              :     }
     885     13064607 :   if (first)
     886              :     return 0;
     887              : 
     888              :   /* Now match the operand definition types to that of the first stmt.  */
     889     26619537 :   for (i = 0; i < number_of_oprnds;)
     890              :     {
     891     17380357 :       if (skip_args[i])
     892              :         {
     893        44403 :           ++i;
     894        44403 :           continue;
     895              :         }
     896              : 
     897     17335954 :       oprnd_info = (*oprnds_info)[i];
     898     17335954 :       dt = dts[i];
     899     17335954 :       stmt_vec_info def_stmt_info = oprnd_info->def_stmts[stmt_num];
     900     17335954 :       oprnd = oprnd_info->ops[stmt_num];
     901     17335954 :       tree type = TREE_TYPE (oprnd);
     902              : 
     903     17335954 :       if (!types_compatible_p (oprnd_info->first_op_type, type))
     904              :         {
     905       108517 :           if (dump_enabled_p ())
     906           93 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     907              :                              "Build SLP failed: different operand types\n");
     908       108517 :           return 1;
     909              :         }
     910              : 
     911     17227437 :       if ((gs_op == i) != oprnd_info->first_gs_p)
     912              :         {
     913            0 :           if (dump_enabled_p ())
     914            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     915              :                              "Build SLP failed: mixed gather and non-gather\n");
     916            0 :           return 1;
     917              :         }
     918     17227437 :       else if (gs_op == i)
     919              :         {
     920          242 :           if (!operand_equal_p (oprnd_info->first_gs_info.base,
     921          242 :                                 gs_info.base))
     922              :             {
     923           16 :               if (dump_enabled_p ())
     924            6 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     925              :                                  "Build SLP failed: different gather base\n");
     926           16 :               return 1;
     927              :             }
     928          226 :           if (oprnd_info->first_gs_info.scale != gs_info.scale)
     929              :             {
     930            8 :               if (dump_enabled_p ())
     931            2 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     932              :                                  "Build SLP failed: different gather scale\n");
     933            8 :               return 1;
     934              :             }
     935              :         }
     936              : 
     937              :       /* Not first stmt of the group, check that the def-stmt/s match
     938              :          the def-stmt/s of the first stmt.  Allow different definition
     939              :          types for reduction chains: the first stmt must be a
     940              :          vect_reduction_def (a phi node), and the rest
     941              :          end in the reduction chain.  */
     942     17227413 :       if ((!vect_def_types_match (oprnd_info->first_dt, dt)
     943       305987 :            && !(oprnd_info->first_dt == vect_reduction_def
     944         4806 :                 && !STMT_VINFO_DATA_REF (stmt_info)
     945         4806 :                 && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
     946         4780 :                 && def_stmt_info
     947         4778 :                 && !STMT_VINFO_DATA_REF (def_stmt_info)
     948         4778 :                 && (REDUC_GROUP_FIRST_ELEMENT (def_stmt_info)
     949              :                     == REDUC_GROUP_FIRST_ELEMENT (stmt_info))))
     950     16926204 :           || (!STMT_VINFO_DATA_REF (stmt_info)
     951     15599889 :               && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
     952         9961 :               && ((!def_stmt_info
     953         9765 :                    || STMT_VINFO_DATA_REF (def_stmt_info)
     954        17987 :                    || (REDUC_GROUP_FIRST_ELEMENT (def_stmt_info)
     955              :                        != REDUC_GROUP_FIRST_ELEMENT (stmt_info)))
     956         9961 :                   != (oprnd_info->first_dt != vect_reduction_def))))
     957              :         {
     958              :           /* Try swapping operands if we got a mismatch.  For BB
     959              :              vectorization only in case it will clearly improve things.  */
     960       303932 :           if (i == commutative_op && !swapped
     961       301209 :               && (!is_a <bb_vec_info> (vinfo)
     962         5261 :                   || (!vect_def_types_match ((*oprnds_info)[i+1]->first_dt,
     963         5261 :                                              dts[i+1])
     964         1486 :                       && (vect_def_types_match (oprnd_info->first_dt, dts[i+1])
     965              :                           || vect_def_types_match
     966          224 :                                ((*oprnds_info)[i+1]->first_dt, dts[i])))))
     967              :             {
     968         2723 :               if (dump_enabled_p ())
     969          153 :                 dump_printf_loc (MSG_NOTE, vect_location,
     970              :                                  "trying swapped operands\n");
     971         2723 :               std::swap (dts[i], dts[i+1]);
     972         2723 :               std::swap ((*oprnds_info)[i]->def_stmts[stmt_num],
     973         2723 :                          (*oprnds_info)[i+1]->def_stmts[stmt_num]);
     974         2723 :               std::swap ((*oprnds_info)[i]->ops[stmt_num],
     975         2723 :                          (*oprnds_info)[i+1]->ops[stmt_num]);
     976              :               /* After swapping some operands we lost track whether an
     977              :                  operand has any pattern defs so be conservative here.  */
     978         2723 :               if ((*oprnds_info)[i]->any_pattern
     979         2723 :                   || (*oprnds_info)[i+1]->any_pattern)
     980           36 :                 (*oprnds_info)[i]->any_pattern
     981           18 :                   = (*oprnds_info)[i+1]->any_pattern = true;
     982         2723 :               swapped = true;
     983         2723 :               continue;
     984              :             }
     985              : 
     986       298486 :           if (is_a <bb_vec_info> (vinfo)
     987       282946 :               && !oprnd_info->any_pattern
     988       581181 :               && number_of_oprnds > 1)
     989              :             {
     990              :               /* Now for commutative ops we should see whether we can
     991              :                  make the other operand matching.  */
     992       107734 :               if (dump_enabled_p ())
     993          251 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     994              :                                  "treating operand as external\n");
     995       107734 :               oprnd_info->first_dt = dt = vect_external_def;
     996              :             }
     997              :           else
     998              :             {
     999       190752 :               if (dump_enabled_p ())
    1000          411 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1001              :                                  "Build SLP failed: different types\n");
    1002       190752 :               return 1;
    1003              :             }
    1004              :         }
    1005              : 
    1006              :       /* Make sure to demote the overall operand to external.  */
    1007     17033938 :       if (dt == vect_external_def)
    1008       348960 :         oprnd_info->first_dt = vect_external_def;
    1009              :       /* For a SLP reduction chain we want to duplicate the reduction to
    1010              :          each of the chain members.  That gets us a sane SLP graph (still
    1011              :          the stmts are not 100% correct wrt the initial values).  */
    1012     16684978 :       else if ((dt == vect_internal_def
    1013     16684978 :                 || dt == vect_reduction_def)
    1014     15717473 :                && oprnd_info->first_dt == vect_reduction_def
    1015       101220 :                && !STMT_VINFO_DATA_REF (stmt_info)
    1016       101220 :                && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
    1017         4778 :                && !STMT_VINFO_DATA_REF (def_stmt_info)
    1018     16689756 :                && (REDUC_GROUP_FIRST_ELEMENT (def_stmt_info)
    1019              :                    == REDUC_GROUP_FIRST_ELEMENT (stmt_info)))
    1020              :         {
    1021         4778 :           oprnd_info->def_stmts[stmt_num] = oprnd_info->def_stmts[0];
    1022         4778 :           oprnd_info->ops[stmt_num] = oprnd_info->ops[0];
    1023              :         }
    1024              : 
    1025     17033938 :       ++i;
    1026              :     }
    1027              : 
    1028              :   /* Swap operands.  */
    1029      9239180 :   if (swapped)
    1030              :     {
    1031        43169 :       if (dump_enabled_p ())
    1032          457 :         dump_printf_loc (MSG_NOTE, vect_location,
    1033              :                          "swapped operands to match def types in %G",
    1034              :                          stmt_info->stmt);
    1035              :     }
    1036              : 
    1037              :   return 0;
    1038              : }
    1039              : 
    1040              : /* Return true if call statements CALL1 and CALL2 are similar enough
    1041              :    to be combined into the same SLP group.  */
    1042              : 
    1043              : bool
    1044        70778 : compatible_calls_p (gcall *call1, gcall *call2, bool allow_two_operators)
    1045              : {
    1046        70778 :   unsigned int nargs = gimple_call_num_args (call1);
    1047        70778 :   if (nargs != gimple_call_num_args (call2))
    1048              :     return false;
    1049              : 
    1050        64417 :   auto cfn1 = gimple_call_combined_fn (call1);
    1051        64417 :   auto cfn2 = gimple_call_combined_fn (call2);
    1052        64417 :   if (cfn1 != cfn2
    1053            2 :       && (!allow_two_operators
    1054            2 :           || !((cfn1 == CFN_FMA || cfn1 == CFN_FMS)
    1055            2 :                && (cfn2 == CFN_FMA || cfn2 == CFN_FMS))))
    1056              :     return false;
    1057              : 
    1058        64417 :   if (gimple_call_internal_p (call1))
    1059              :     {
    1060         7241 :       if (!types_compatible_p (TREE_TYPE (gimple_call_lhs (call1)),
    1061         7241 :                                TREE_TYPE (gimple_call_lhs (call2))))
    1062              :         return false;
    1063        14878 :       for (unsigned int i = 0; i < nargs; ++i)
    1064         7637 :         if (!types_compatible_p (TREE_TYPE (gimple_call_arg (call1, i)),
    1065         7637 :                                  TREE_TYPE (gimple_call_arg (call2, i))))
    1066              :           return false;
    1067              :     }
    1068              :   else
    1069              :     {
    1070        57176 :       if (!operand_equal_p (gimple_call_fn (call1),
    1071        57176 :                             gimple_call_fn (call2), 0))
    1072              :         return false;
    1073              : 
    1074        42282 :       if (gimple_call_fntype (call1) != gimple_call_fntype (call2))
    1075              :         return false;
    1076              :     }
    1077              : 
    1078              :   /* Check that any unvectorized arguments are equal.  */
    1079        21335 :   if (const int *map = vect_get_operand_map (call1, false, false))
    1080              :     {
    1081           15 :       unsigned int nkept = *map++;
    1082           15 :       unsigned int mapi = 0;
    1083           57 :       for (unsigned int i = 0; i < nargs; ++i)
    1084           42 :         if (mapi < nkept && map[mapi] == int (i))
    1085           27 :           mapi += 1;
    1086           15 :         else if (!operand_equal_p (gimple_call_arg (call1, i),
    1087           15 :                                    gimple_call_arg (call2, i)))
    1088              :           return false;
    1089              :     }
    1090              : 
    1091              :   return true;
    1092              : }
    1093              : 
    1094              : /* A subroutine of vect_build_slp_tree for checking VECTYPE, which is the
    1095              :    caller's attempt to find the vector type in STMT_INFO with the narrowest
    1096              :    element type.  Return true if VECTYPE is nonnull and if it is valid
    1097              :    for STMT_INFO.  When returning true, update MAX_NUNITS to reflect the
    1098              :    number of units in VECTYPE.  GROUP_SIZE and MAX_NUNITS are as for
    1099              :    vect_build_slp_tree.  */
    1100              : 
    1101              : static bool
    1102      5892385 : vect_record_max_nunits (vec_info *vinfo, stmt_vec_info stmt_info,
    1103              :                         unsigned int group_size,
    1104              :                         tree vectype, poly_uint64 *max_nunits)
    1105              : {
    1106      5892385 :   if (!vectype)
    1107              :     {
    1108         4028 :       if (dump_enabled_p ())
    1109            7 :         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1110              :                          "Build SLP failed: unsupported data-type in %G\n",
    1111              :                          stmt_info->stmt);
    1112              :       /* Fatal mismatch.  */
    1113         4028 :       return false;
    1114              :     }
    1115              : 
    1116              :   /* If populating the vector type requires unrolling then fail
    1117              :      before adjusting *max_nunits for basic-block vectorization.  */
    1118      5888357 :   if (is_a <bb_vec_info> (vinfo)
    1119      5888357 :       && !multiple_p (group_size, TYPE_VECTOR_SUBPARTS (vectype)))
    1120              :     {
    1121       215950 :       if (dump_enabled_p ())
    1122          134 :         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1123              :                          "Build SLP failed: unrolling required "
    1124              :                          "in basic block SLP\n");
    1125              :       /* Fatal mismatch.  */
    1126       215950 :       return false;
    1127              :     }
    1128              : 
    1129              :   /* In case of multiple types we need to detect the smallest type.  */
    1130      5672407 :   vect_update_max_nunits (max_nunits, vectype);
    1131      5672407 :   return true;
    1132              : }
    1133              : 
    1134              : /* Verify if the scalar stmts STMTS are isomorphic, require data
    1135              :    permutation or are of unsupported types of operation.  Return
    1136              :    true if they are, otherwise return false and indicate in *MATCHES
    1137              :    which stmts are not isomorphic to the first one.  If MATCHES[0]
    1138              :    is false then this indicates the comparison could not be
    1139              :    carried out or the stmts will never be vectorized by SLP.
    1140              : 
    1141              :    Note COND_EXPR is possibly isomorphic to another one after swapping its
    1142              :    operands.  Set SWAP[i] to 1 if stmt I is COND_EXPR and isomorphic to
    1143              :    the first stmt by swapping the two operands of comparison; set SWAP[i]
    1144              :    to 2 if stmt I is isormorphic to the first stmt by inverting the code
    1145              :    of comparison.  Take A1 >= B1 ? X1 : Y1 as an example, it can be swapped
    1146              :    to (B1 <= A1 ? X1 : Y1); or be inverted to (A1 < B1) ? Y1 : X1.  */
    1147              : 
    1148              : static bool
    1149      6204224 : vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
    1150              :                        vec<stmt_vec_info> stmts,
    1151              :                        poly_uint64 *max_nunits, bool *matches,
    1152              :                        bool *two_operators, tree *node_vectype)
    1153              : {
    1154      6204224 :   unsigned int group_size = stmts.length ();
    1155      6204224 :   unsigned int i;
    1156      6204224 :   stmt_vec_info first_stmt_info = stmts[0];
    1157      6204224 :   code_helper first_stmt_code = ERROR_MARK;
    1158      6204224 :   code_helper alt_stmt_code = ERROR_MARK;
    1159      6204224 :   code_helper first_cond_code = ERROR_MARK;
    1160      6204224 :   bool need_same_oprnds = false;
    1161      6204224 :   tree first_lhs = NULL_TREE;
    1162      6204224 :   tree first_op1 = NULL_TREE;
    1163      6204224 :   stmt_vec_info first_load = NULL, prev_first_load = NULL;
    1164      6204224 :   bool first_stmt_ldst_p = false, first_stmt_ldst_masklen_p = false;
    1165      6204224 :   bool first_stmt_phi_p = false;
    1166      6204224 :   int first_reduc_idx = -1;
    1167      6204224 :   bool maybe_soft_fail = false;
    1168      6204224 :   tree soft_fail_nunits_vectype = NULL_TREE;
    1169              : 
    1170      6204224 :   tree vectype, nunits_vectype;
    1171      6204224 :   if (!vect_get_vector_types_for_stmt (vinfo, first_stmt_info, &vectype,
    1172              :                                        &nunits_vectype, group_size))
    1173              :     {
    1174              :       /* Fatal mismatch.  */
    1175       261204 :       matches[0] = false;
    1176       261204 :       return false;
    1177              :     }
    1178      5943020 :   if (is_a <bb_vec_info> (vinfo)
    1179      5943020 :       && known_le (TYPE_VECTOR_SUBPARTS (vectype), 1U))
    1180              :     {
    1181       366113 :       if (dump_enabled_p ())
    1182          287 :         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1183              :                          "Build SLP failed: not using single lane "
    1184              :                          "vector type %T\n", vectype);
    1185       366113 :       matches[0] = false;
    1186       366113 :       return false;
    1187              :     }
    1188              :   /* Record nunits required but continue analysis, producing matches[]
    1189              :      as if nunits was not an issue.  This allows splitting of groups
    1190              :      to happen.  */
    1191      5576907 :   if (nunits_vectype
    1192      5576907 :       && !vect_record_max_nunits (vinfo, first_stmt_info, group_size,
    1193              :                                   nunits_vectype, max_nunits))
    1194              :     {
    1195       215950 :       gcc_assert (is_a <bb_vec_info> (vinfo));
    1196       215950 :       maybe_soft_fail = true;
    1197       215950 :       soft_fail_nunits_vectype = nunits_vectype;
    1198              :     }
    1199              : 
    1200      5576907 :   gcc_assert (vectype || !gimple_get_lhs (first_stmt_info->stmt));
    1201      5576907 :   *node_vectype = vectype;
    1202              : 
    1203              :   /* For every stmt in NODE find its def stmt/s.  */
    1204      5576907 :   stmt_vec_info stmt_info;
    1205     23482766 :   FOR_EACH_VEC_ELT (stmts, i, stmt_info)
    1206              :     {
    1207     18083093 :       bool ldst_p = false;
    1208     18083093 :       bool ldst_masklen_p = false;
    1209     18083093 :       bool phi_p = false;
    1210     18083093 :       code_helper rhs_code = ERROR_MARK;
    1211              : 
    1212     18083093 :       swap[i] = 0;
    1213     18083093 :       matches[i] = false;
    1214     18083093 :       if (!stmt_info)
    1215              :         {
    1216        41079 :           matches[i] = true;
    1217     17946938 :           continue;
    1218              :         }
    1219              : 
    1220     18042014 :       gimple *stmt = stmt_info->stmt;
    1221     18042014 :       if (dump_enabled_p ())
    1222       226146 :         dump_printf_loc (MSG_NOTE, vect_location, "Build SLP for %G", stmt);
    1223              : 
    1224              :       /* Fail to vectorize statements marked as unvectorizable, throw
    1225              :          or are volatile.  */
    1226     18042014 :       if (!STMT_VINFO_VECTORIZABLE (stmt_info)
    1227     17790454 :           || stmt_can_throw_internal (cfun, stmt)
    1228     34967655 :           || gimple_has_volatile_ops (stmt))
    1229              :         {
    1230       258512 :           if (dump_enabled_p ())
    1231          232 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1232              :                              "Build SLP failed: unvectorizable statement %G",
    1233              :                              stmt);
    1234              :           /* ???  For BB vectorization we want to commutate operands in a way
    1235              :              to shuffle all unvectorizable defs into one operand and have
    1236              :              the other still vectorized.  The following doesn't reliably
    1237              :              work for this though but it's the easiest we can do here.  */
    1238       258512 :           if (is_a <bb_vec_info> (vinfo) && i != 0)
    1239       106654 :             continue;
    1240              :           /* Fatal mismatch.  */
    1241       151858 :           matches[0] = false;
    1242       151858 :           return false;
    1243              :         }
    1244              : 
    1245     17783502 :       gcall *call_stmt = dyn_cast <gcall *> (stmt);
    1246     17783502 :       tree lhs = gimple_get_lhs (stmt);
    1247     17783502 :       if (lhs == NULL_TREE && !call_stmt)
    1248              :         {
    1249           36 :           if (dump_enabled_p ())
    1250            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1251              :                              "Build SLP failed: not GIMPLE_ASSIGN nor "
    1252              :                              "GIMPLE_CALL %G", stmt);
    1253           36 :           if (is_a <bb_vec_info> (vinfo) && i != 0)
    1254           36 :             continue;
    1255              :           /* Fatal mismatch.  */
    1256            0 :           matches[0] = false;
    1257            0 :           return false;
    1258              :         }
    1259              : 
    1260     17783466 :       if (call_stmt)
    1261              :         {
    1262       174420 :           combined_fn cfn = gimple_call_combined_fn (call_stmt);
    1263       174420 :           if (cfn != CFN_LAST && cfn != CFN_MASK_CALL)
    1264        59936 :             rhs_code = cfn;
    1265              :           else
    1266              :             rhs_code = CALL_EXPR;
    1267              : 
    1268       174420 :           if (cfn == CFN_GATHER_LOAD
    1269       174420 :               || cfn == CFN_SCATTER_STORE)
    1270              :             ldst_p = true;
    1271              :           else if (cfn == CFN_MASK_LOAD
    1272              :                    || cfn == CFN_MASK_GATHER_LOAD
    1273              :                    || cfn == CFN_MASK_LEN_GATHER_LOAD
    1274              :                    || cfn == CFN_MASK_SCATTER_STORE
    1275              :                    || cfn == CFN_MASK_LEN_SCATTER_STORE)
    1276              :             {
    1277              :               ldst_p = true;
    1278              :               ldst_masklen_p = true;
    1279              :             }
    1280              :           else if (cfn == CFN_MASK_STORE)
    1281              :             {
    1282              :               ldst_p = true;
    1283              :               ldst_masklen_p = true;
    1284              :               rhs_code = CFN_MASK_STORE;
    1285              :             }
    1286              :           else if (cfn == CFN_GOMP_SIMD_LANE)
    1287              :             ;
    1288       162546 :           else if ((cfn != CFN_LAST
    1289              :                     && cfn != CFN_MASK_CALL
    1290        48062 :                     && internal_fn_p (cfn)
    1291        37616 :                     && !vectorizable_internal_fn_p (as_internal_fn (cfn)))
    1292       162463 :                    || gimple_call_tail_p (call_stmt)
    1293       162463 :                    || gimple_call_noreturn_p (call_stmt)
    1294       325009 :                    || gimple_call_chain (call_stmt))
    1295              :             {
    1296          443 :               if (dump_enabled_p ())
    1297           13 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1298              :                                  "Build SLP failed: unsupported call type %G",
    1299              :                                  (gimple *) call_stmt);
    1300          443 :               if (is_a <bb_vec_info> (vinfo) && i != 0)
    1301           72 :                 continue;
    1302              :               /* Fatal mismatch.  */
    1303          371 :               matches[0] = false;
    1304          371 :               return false;
    1305              :             }
    1306              :         }
    1307     17609046 :       else if (gimple_code (stmt) == GIMPLE_PHI)
    1308              :         {
    1309              :           rhs_code = ERROR_MARK;
    1310              :           phi_p = true;
    1311              :         }
    1312              :       else
    1313              :         {
    1314     16744233 :           rhs_code = gimple_assign_rhs_code (stmt);
    1315     16744233 :           ldst_p = STMT_VINFO_DATA_REF (stmt_info) != nullptr;
    1316              :         }
    1317              : 
    1318              :       /* Check the operation.  */
    1319     17783023 :       if (i == 0)
    1320              :         {
    1321      5424678 :           first_lhs = lhs;
    1322      5424678 :           first_stmt_code = rhs_code;
    1323      5424678 :           first_stmt_ldst_p = ldst_p;
    1324      5424678 :           first_stmt_ldst_masklen_p = ldst_masklen_p;
    1325      5424678 :           first_stmt_phi_p = phi_p;
    1326      5424678 :           first_reduc_idx = STMT_VINFO_REDUC_IDX (stmt_info);
    1327              : 
    1328              :           /* Shift arguments should be equal in all the packed stmts for a
    1329              :              vector shift with scalar shift operand.  */
    1330      5424678 :           if (rhs_code == LSHIFT_EXPR
    1331      5353143 :               || rhs_code == RSHIFT_EXPR
    1332      5273434 :               || rhs_code == LROTATE_EXPR
    1333     10697998 :               || rhs_code == RROTATE_EXPR)
    1334              :             {
    1335              :               /* First see if we have a vector/vector shift.  */
    1336       151836 :               if (!directly_supported_p (rhs_code, vectype, optab_vector))
    1337              :                 {
    1338              :                   /* No vector/vector shift, arrange for a vector/scalar
    1339              :                      SLP layout.  */
    1340       139645 :                   need_same_oprnds = true;
    1341       139645 :                   first_op1 = gimple_assign_rhs2 (stmt);
    1342              :                 }
    1343              :             }
    1344      5272842 :           else if (rhs_code == WIDEN_LSHIFT_EXPR)
    1345              :             {
    1346            0 :               need_same_oprnds = true;
    1347            0 :               first_op1 = gimple_assign_rhs2 (stmt);
    1348              :             }
    1349      5272842 :           else if (!ldst_p
    1350      5272842 :                    && rhs_code == BIT_FIELD_REF)
    1351              :             {
    1352         8900 :               tree vec = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
    1353         8900 :               if (!is_a <bb_vec_info> (vinfo)
    1354         8774 :                   || TREE_CODE (vec) != SSA_NAME
    1355              :                   /* When the element types are not compatible we pun the
    1356              :                      source to the target vectype which requires equal size.  */
    1357        17662 :                   || ((!VECTOR_TYPE_P (TREE_TYPE (vec))
    1358         7957 :                        || !types_compatible_p (TREE_TYPE (vectype),
    1359         7957 :                                                TREE_TYPE (TREE_TYPE (vec))))
    1360         1124 :                       && !operand_equal_p (TYPE_SIZE (vectype),
    1361         1124 :                                            TYPE_SIZE (TREE_TYPE (vec)))))
    1362              :                 {
    1363          853 :                   if (dump_enabled_p ())
    1364            0 :                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1365              :                                      "Build SLP failed: "
    1366              :                                      "BIT_FIELD_REF not supported\n");
    1367              :                   /* Fatal mismatch.  */
    1368          853 :                   matches[0] = false;
    1369          853 :                   return false;
    1370              :                 }
    1371              :             }
    1372      5263942 :           else if (rhs_code == CFN_DIV_POW2)
    1373              :             {
    1374            0 :               need_same_oprnds = true;
    1375            0 :               first_op1 = gimple_call_arg (call_stmt, 1);
    1376              :             }
    1377      5263942 :           else if (rhs_code == CFN_GOMP_SIMD_LANE)
    1378              :             {
    1379         3645 :               need_same_oprnds = true;
    1380         3645 :               first_op1 = gimple_call_arg (call_stmt, 1);
    1381              :             }
    1382              :         }
    1383              :       else
    1384              :         {
    1385     12358345 :           int comm_arg;
    1386     12358723 :           if (first_reduc_idx != STMT_VINFO_REDUC_IDX (stmt_info)
    1387              :               /* For SLP reduction groups the index isn't necessarily
    1388              :                  uniform but only that of the first stmt matters.  */
    1389         2340 :               && !(first_reduc_idx != -1
    1390         2340 :                    && STMT_VINFO_REDUC_IDX (stmt_info) != -1
    1391         2340 :                    && REDUC_GROUP_FIRST_ELEMENT (stmt_info))
    1392     12358345 :               && !(first_reduc_idx != -1
    1393         1049 :                    && STMT_VINFO_REDUC_IDX (stmt_info) != -1
    1394         1049 :                    && (comm_arg = first_commutative_argument
    1395         1049 :                                     (rhs_code, TREE_TYPE (lhs))) >= 0
    1396              :                    && (first_reduc_idx
    1397          815 :                        == 2 * comm_arg + 1 - STMT_VINFO_REDUC_IDX (stmt_info))))
    1398              :             {
    1399          378 :               if (dump_enabled_p ())
    1400              :                 {
    1401           12 :                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1402              :                                    "Build SLP failed: different reduc_idx "
    1403              :                                    "%d instead of %d in %G",
    1404              :                                    STMT_VINFO_REDUC_IDX (stmt_info),
    1405              :                                    first_reduc_idx, stmt);
    1406              :                 }
    1407              :               /* Mismatch.  */
    1408          378 :               continue;
    1409              :             }
    1410     12357967 :           if (!ldst_p
    1411      9727377 :               && first_stmt_code != rhs_code
    1412     13884642 :               && alt_stmt_code == ERROR_MARK)
    1413              :             alt_stmt_code = rhs_code;
    1414     13862473 :           if ((!ldst_p
    1415      9727377 :                && first_stmt_code != rhs_code
    1416      1526675 :                && (first_stmt_code != IMAGPART_EXPR
    1417          220 :                    || rhs_code != REALPART_EXPR)
    1418      1526654 :                && (first_stmt_code != REALPART_EXPR
    1419          743 :                    || rhs_code != IMAGPART_EXPR)
    1420              :                /* Handle mismatches in plus/minus by computing both
    1421              :                   and merging the results.  */
    1422      1526643 :                && !((((first_stmt_code == PLUS_EXPR
    1423      1407661 :                        || first_stmt_code == MINUS_EXPR)
    1424       149109 :                       && (alt_stmt_code == PLUS_EXPR
    1425       139272 :                           || alt_stmt_code == MINUS_EXPR))
    1426      1495330 :                      || ((first_stmt_code == CFN_FMA
    1427      1495328 :                           || first_stmt_code == CFN_FMS)
    1428            2 :                          && (alt_stmt_code == CFN_FMA
    1429            2 :                              || alt_stmt_code == CFN_FMS)))
    1430        31315 :                     && rhs_code == alt_stmt_code)
    1431      1539118 :                && !(first_stmt_code.is_tree_code ()
    1432      1397794 :                     && rhs_code.is_tree_code ()
    1433      1281345 :                     && (TREE_CODE_CLASS (tree_code (first_stmt_code))
    1434              :                         == tcc_comparison)
    1435       140285 :                     && (swap_tree_comparison (tree_code (first_stmt_code))
    1436       140285 :                         == tree_code (rhs_code))
    1437              :                     && (first_reduc_idx == -1
    1438            0 :                         || REDUC_GROUP_FIRST_ELEMENT (stmt_info))))
    1439              :               || (ldst_p
    1440      5261180 :                   && (STMT_VINFO_GROUPED_ACCESS (stmt_info)
    1441      2630590 :                       != STMT_VINFO_GROUPED_ACCESS (first_stmt_info)))
    1442              :               || (ldst_p
    1443      2578451 :                   && (STMT_VINFO_GATHER_SCATTER_P (stmt_info)
    1444      2578451 :                       != STMT_VINFO_GATHER_SCATTER_P (first_stmt_info)))
    1445     10853625 :               || first_stmt_ldst_p != ldst_p
    1446     10853469 :               || (ldst_p && first_stmt_ldst_masklen_p != ldst_masklen_p)
    1447     23211428 :               || first_stmt_phi_p != phi_p)
    1448              :             {
    1449      1504506 :               if (dump_enabled_p ())
    1450              :                 {
    1451         3303 :                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1452              :                                    "Build SLP failed: different operation "
    1453              :                                    "in stmt %G", stmt);
    1454         3303 :                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1455              :                                    "original stmt %G", first_stmt_info->stmt);
    1456              :                 }
    1457              :               /* Mismatch.  */
    1458      1504506 :               continue;
    1459              :             }
    1460              : 
    1461     10870268 :           if (!ldst_p
    1462      8275145 :               && first_stmt_code == BIT_FIELD_REF
    1463     10880026 :               && (TREE_OPERAND (gimple_assign_rhs1 (first_stmt_info->stmt), 0)
    1464        26565 :                   != TREE_OPERAND (gimple_assign_rhs1 (stmt_info->stmt), 0)))
    1465              :             {
    1466        16807 :               if (dump_enabled_p ())
    1467           76 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1468              :                                  "Build SLP failed: different BIT_FIELD_REF "
    1469              :                                  "arguments in %G", stmt);
    1470              :               /* Mismatch.  */
    1471        16807 :               continue;
    1472              :             }
    1473              : 
    1474     10836654 :           if (call_stmt
    1475        71491 :               && first_stmt_code != CFN_MASK_LOAD
    1476     10907743 :               && first_stmt_code != CFN_MASK_STORE)
    1477              :             {
    1478        70778 :               if (!is_a <gcall *> (stmts[0]->stmt)
    1479        70778 :                   || !compatible_calls_p (as_a <gcall *> (stmts[0]->stmt),
    1480              :                                           call_stmt, true))
    1481              :                 {
    1482        49443 :                   if (dump_enabled_p ())
    1483            0 :                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1484              :                                      "Build SLP failed: different calls in %G",
    1485              :                                      stmt);
    1486              :                   /* Mismatch.  */
    1487        49443 :                   continue;
    1488              :                 }
    1489              :             }
    1490              : 
    1491     10578132 :           if ((phi_p || gimple_could_trap_p (stmt_info->stmt))
    1492     11667209 :               && (gimple_bb (first_stmt_info->stmt)
    1493      1089077 :                   != gimple_bb (stmt_info->stmt)))
    1494              :             {
    1495        47629 :               if (dump_enabled_p ())
    1496            8 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1497              :                                  "Build SLP failed: different BB for PHI "
    1498              :                                  "or possibly trapping operation in %G", stmt);
    1499              :               /* Mismatch.  */
    1500        47629 :               continue;
    1501              :             }
    1502              : 
    1503     10739582 :           if (need_same_oprnds)
    1504              :             {
    1505        68836 :               tree other_op1 = gimple_arg (stmt, 1);
    1506        68836 :               if (!operand_equal_p (first_op1, other_op1, 0))
    1507              :                 {
    1508         8943 :                   if (dump_enabled_p ())
    1509          133 :                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1510              :                                      "Build SLP failed: different shift "
    1511              :                                      "arguments in %G", stmt);
    1512              :                   /* Mismatch.  */
    1513         8943 :                   continue;
    1514              :                 }
    1515              :             }
    1516              : 
    1517     10731376 :           if (first_lhs
    1518     10730639 :               && lhs
    1519     10730639 :               && !types_compatible_p (TREE_TYPE (lhs), TREE_TYPE (first_lhs)))
    1520              :             {
    1521          737 :               if (dump_enabled_p ())
    1522            6 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1523              :                                  "Build SLP failed: different vector type "
    1524              :                                  "in %G", stmt);
    1525              :               /* Mismatch.  */
    1526          737 :               continue;
    1527              :             }
    1528              :         }
    1529              : 
    1530              :       /* Grouped store or load.  */
    1531     16153727 :       if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
    1532              :         {
    1533      3985809 :           gcc_assert (ldst_p);
    1534      3985809 :           if (DR_IS_WRITE (STMT_VINFO_DATA_REF (stmt_info)))
    1535              :             {
    1536              :               /* Store.  */
    1537      3081891 :               gcc_assert (rhs_code == CFN_MASK_STORE
    1538              :                           || REFERENCE_CLASS_P (lhs)
    1539              :                           || DECL_P (lhs));
    1540              :             }
    1541              :           else
    1542              :             {
    1543              :               /* Load.  */
    1544       903918 :               first_load = DR_GROUP_FIRST_ELEMENT (stmt_info);
    1545       903918 :               if (prev_first_load)
    1546              :                 {
    1547              :                   /* Check that there are no loads from different interleaving
    1548              :                      chains in the same node.  */
    1549       416681 :                   if (prev_first_load != first_load)
    1550              :                     {
    1551        57806 :                       if (dump_enabled_p ())
    1552         2178 :                         dump_printf_loc (MSG_MISSED_OPTIMIZATION,
    1553              :                                          vect_location,
    1554              :                                          "Build SLP failed: different "
    1555              :                                          "interleaving chains in one node %G",
    1556              :                                          stmt);
    1557              :                       /* Mismatch.  */
    1558        57806 :                       continue;
    1559              :                     }
    1560              :                 }
    1561              :               else
    1562              :                 prev_first_load = first_load;
    1563              :            }
    1564              :         }
    1565              :       /* Non-grouped store or load.  */
    1566     12167918 :       else if (ldst_p)
    1567              :         {
    1568       918030 :           if (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info))
    1569       642283 :               && rhs_code != CFN_GATHER_LOAD
    1570              :               && rhs_code != CFN_MASK_GATHER_LOAD
    1571              :               && rhs_code != CFN_MASK_LEN_GATHER_LOAD
    1572              :               && rhs_code != CFN_SCATTER_STORE
    1573              :               && rhs_code != CFN_MASK_SCATTER_STORE
    1574              :               && rhs_code != CFN_MASK_LEN_SCATTER_STORE
    1575       642283 :               && !STMT_VINFO_GATHER_SCATTER_P (stmt_info)
    1576              :               /* Not grouped loads are handled as externals for BB
    1577              :                  vectorization.  For loop vectorization we can handle
    1578              :                  splats the same we handle single element interleaving.
    1579              :                  Likewise we can handle a collection of invariant refs.  */
    1580      1540489 :               && (is_a <bb_vec_info> (vinfo)
    1581       622459 :                   || (stmt_info != first_stmt_info
    1582        68115 :                   && !(integer_zerop (DR_STEP (STMT_VINFO_DATA_REF (stmt_info)))
    1583          241 :                       && integer_zerop (DR_STEP (STMT_VINFO_DATA_REF
    1584              :                                                          (first_stmt_info)))))))
    1585              :             {
    1586              :               /* Not grouped load.  */
    1587        67633 :               if (dump_enabled_p ())
    1588          145 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1589              :                                  "Build SLP failed: not grouped load %G", stmt);
    1590              : 
    1591        67633 :               if (i != 0)
    1592        67633 :                 continue;
    1593              :               /* Fatal mismatch.  */
    1594            0 :               matches[0] = false;
    1595            0 :               return false;
    1596              :             }
    1597              :         }
    1598              :       /* Not memory operation.  */
    1599              :       else
    1600              :         {
    1601     11249888 :           if (!phi_p
    1602     10546107 :               && rhs_code.is_tree_code ()
    1603     10496503 :               && TREE_CODE_CLASS (tree_code (rhs_code)) != tcc_binary
    1604      1809924 :               && TREE_CODE_CLASS (tree_code (rhs_code)) != tcc_unary
    1605      1124803 :               && TREE_CODE_CLASS (tree_code (rhs_code)) != tcc_expression
    1606      1054907 :               && TREE_CODE_CLASS (tree_code (rhs_code)) != tcc_comparison
    1607        89492 :               && rhs_code != VIEW_CONVERT_EXPR
    1608              :               && rhs_code != CALL_EXPR
    1609              :               && rhs_code != BIT_FIELD_REF
    1610     11249888 :               && rhs_code != SSA_NAME)
    1611              :             {
    1612        24152 :               if (dump_enabled_p ())
    1613           17 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1614              :                                  "Build SLP failed: operation unsupported %G",
    1615              :                                  stmt);
    1616        24152 :               if (is_a <bb_vec_info> (vinfo) && i != 0)
    1617            0 :                 continue;
    1618              :               /* Fatal mismatch.  */
    1619        24152 :               matches[0] = false;
    1620        24152 :               return false;
    1621              :             }
    1622              : 
    1623     11225736 :           if (rhs_code == COND_EXPR)
    1624              :             {
    1625        67045 :               tree cond_expr = gimple_assign_rhs1 (stmt);
    1626        67045 :               enum tree_code cond_code = TREE_CODE (cond_expr);
    1627        67045 :               enum tree_code swap_code = ERROR_MARK;
    1628        67045 :               enum tree_code invert_code = ERROR_MARK;
    1629              : 
    1630        67045 :               if (i == 0)
    1631        54789 :                 first_cond_code = TREE_CODE (cond_expr);
    1632        12256 :               else if (TREE_CODE_CLASS (cond_code) == tcc_comparison)
    1633              :                 {
    1634            0 :                   bool honor_nans = HONOR_NANS (TREE_OPERAND (cond_expr, 0));
    1635            0 :                   swap_code = swap_tree_comparison (cond_code);
    1636            0 :                   invert_code = invert_tree_comparison (cond_code, honor_nans);
    1637              :                 }
    1638              : 
    1639        67045 :               if (first_cond_code == cond_code)
    1640              :                 ;
    1641              :               /* Isomorphic can be achieved by swapping.  */
    1642            0 :               else if (first_cond_code == swap_code)
    1643            0 :                 swap[i] = 1;
    1644              :               /* Isomorphic can be achieved by inverting.  */
    1645            0 :               else if (first_cond_code == invert_code)
    1646            0 :                 swap[i] = 2;
    1647              :               else
    1648              :                 {
    1649            0 :                   if (dump_enabled_p ())
    1650            0 :                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1651              :                                      "Build SLP failed: different"
    1652              :                                      " operation %G", stmt);
    1653              :                   /* Mismatch.  */
    1654            0 :                   continue;
    1655              :                 }
    1656              :             }
    1657              : 
    1658     11225736 :           if (i != 0
    1659      8157325 :               && first_stmt_code != rhs_code
    1660        74455 :               && first_stmt_code.is_tree_code ()
    1661        74453 :               && rhs_code.is_tree_code ()
    1662        74453 :               && TREE_CODE_CLASS ((tree_code)first_stmt_code) == tcc_comparison
    1663     11269203 :               && (swap_tree_comparison ((tree_code)first_stmt_code)
    1664        43467 :                   == (tree_code)rhs_code))
    1665        43467 :             swap[i] = 1;
    1666              : 
    1667     11225736 :           if (i != 0
    1668      8157325 :               && first_reduc_idx != STMT_VINFO_REDUC_IDX (stmt_info)
    1669         1692 :               && first_reduc_idx != -1
    1670         1692 :               && STMT_VINFO_REDUC_IDX (stmt_info) != -1
    1671         1692 :               && rhs_code.is_tree_code ()
    1672         1684 :               && commutative_tree_code (tree_code (rhs_code))
    1673     11227418 :               && first_reduc_idx == 1 - STMT_VINFO_REDUC_IDX (stmt_info))
    1674         1682 :             swap[i] = 1;
    1675              :         }
    1676              : 
    1677     16004136 :       matches[i] = true;
    1678              :     }
    1679              : 
    1680     21395004 :   for (i = 0; i < group_size; ++i)
    1681     16779999 :     if (!matches[i])
    1682              :       return false;
    1683              : 
    1684              :   /* If we allowed a two-operation SLP node verify the target can cope
    1685              :      with the permute we are going to use.  */
    1686      4615005 :   if (alt_stmt_code != ERROR_MARK
    1687      4615005 :       && (!alt_stmt_code.is_tree_code ()
    1688        57550 :           || (TREE_CODE_CLASS (tree_code (alt_stmt_code)) != tcc_reference
    1689        57550 :               && TREE_CODE_CLASS (tree_code (alt_stmt_code)) != tcc_comparison)))
    1690              :     {
    1691        16291 :       *two_operators = true;
    1692              :     }
    1693              : 
    1694      4615005 :   if (maybe_soft_fail)
    1695              :     {
    1696       161545 :       unsigned HOST_WIDE_INT const_nunits;
    1697       161545 :       if (!TYPE_VECTOR_SUBPARTS
    1698       161545 :             (soft_fail_nunits_vectype).is_constant (&const_nunits)
    1699       161545 :           || const_nunits > group_size)
    1700            0 :         matches[0] = false;
    1701              :       else
    1702              :         {
    1703              :           /* With constant vector elements simulate a mismatch at the
    1704              :              point we need to split.  */
    1705       161545 :           unsigned tail = group_size & (const_nunits - 1);
    1706       161545 :           memset (&matches[group_size - tail], 0, sizeof (bool) * tail);
    1707              :         }
    1708       161545 :       return false;
    1709              :     }
    1710              : 
    1711              :   return true;
    1712              : }
    1713              : 
    1714              : /* Traits for the hash_set to record failed SLP builds for a stmt set.
    1715              :    Note we never remove apart from at destruction time so we do not
    1716              :    need a special value for deleted that differs from empty.  */
    1717              : struct bst_traits
    1718              : {
    1719              :   typedef vec <stmt_vec_info> value_type;
    1720              :   typedef vec <stmt_vec_info> compare_type;
    1721              :   static inline hashval_t hash (value_type);
    1722              :   static inline bool equal (value_type existing, value_type candidate);
    1723    511397681 :   static inline bool is_empty (value_type x) { return !x.exists (); }
    1724    115348305 :   static inline bool is_deleted (value_type x) { return !x.exists (); }
    1725              :   static const bool empty_zero_p = true;
    1726            0 :   static inline void mark_empty (value_type &x) { x.release (); }
    1727              :   static inline void mark_deleted (value_type &x) { x.release (); }
    1728      9836855 :   static inline void remove (value_type &x) { x.release (); }
    1729              : };
    1730              : inline hashval_t
    1731    100338193 : bst_traits::hash (value_type x)
    1732              : {
    1733    100338193 :   inchash::hash h;
    1734    446159274 :   for (unsigned i = 0; i < x.length (); ++i)
    1735    345821081 :     h.add_int (x[i] ? gimple_uid (x[i]->stmt) : -1);
    1736    100338193 :   return h.end ();
    1737              : }
    1738              : inline bool
    1739     88003866 : bst_traits::equal (value_type existing, value_type candidate)
    1740              : {
    1741    264011598 :   if (existing.length () != candidate.length ())
    1742              :     return false;
    1743     87948899 :   for (unsigned i = 0; i < existing.length (); ++i)
    1744     83397523 :     if (existing[i] != candidate[i])
    1745              :       return false;
    1746              :   return true;
    1747              : }
    1748              : 
    1749              : typedef hash_map <vec <stmt_vec_info>, slp_tree,
    1750              :                   simple_hashmap_traits <bst_traits, slp_tree> >
    1751              :   scalar_stmts_to_slp_tree_map_t;
    1752              : 
    1753              : /* Release BST_MAP.  */
    1754              : 
    1755              : static void
    1756      1888402 : release_scalar_stmts_to_slp_tree_map (scalar_stmts_to_slp_tree_map_t *bst_map)
    1757              : {
    1758              :   /* The map keeps a reference on SLP nodes built, release that.  */
    1759     11725257 :   for (scalar_stmts_to_slp_tree_map_t::iterator it = bst_map->begin ();
    1760     21562112 :        it != bst_map->end (); ++it)
    1761      9836855 :     if ((*it).second)
    1762      9836855 :       vect_free_slp_tree ((*it).second);
    1763      1888402 :   delete bst_map;
    1764      1888402 : }
    1765              : 
    1766              : /* ???  This was std::pair<std::pair<tree_code, vect_def_type>, tree>
    1767              :    but then vec::insert does memmove and that's not compatible with
    1768              :    std::pair.  */
    1769              : struct chain_op_t
    1770              : {
    1771      4365073 :   chain_op_t (tree_code code_, vect_def_type dt_, tree op_)
    1772      4365073 :       : code (code_), dt (dt_), op (op_) {}
    1773              :   tree_code code;
    1774              :   vect_def_type dt;
    1775              :   tree op;
    1776              : };
    1777              : 
    1778              : /* Comparator for sorting associatable chains.  */
    1779              : 
    1780              : static int
    1781     12719169 : dt_sort_cmp (const void *op1_, const void *op2_, void *)
    1782              : {
    1783     12719169 :   auto *op1 = (const chain_op_t *) op1_;
    1784     12719169 :   auto *op2 = (const chain_op_t *) op2_;
    1785     12719169 :   if (op1->dt != op2->dt)
    1786      1843042 :     return (int)op1->dt - (int)op2->dt;
    1787     10876127 :   return (int)op1->code - (int)op2->code;
    1788              : }
    1789              : 
    1790              : /* Linearize the associatable expression chain at START with the
    1791              :    associatable operation CODE (where PLUS_EXPR also allows MINUS_EXPR),
    1792              :    filling CHAIN with the result and using WORKLIST as intermediate storage.
    1793              :    CODE_STMT and ALT_CODE_STMT are filled with the first stmt using CODE
    1794              :    or MINUS_EXPR.  *CHAIN_STMTS if not NULL is filled with all computation
    1795              :    stmts, starting with START.  When ALLOW_ALT_CODE is false, do not
    1796              :    follow into MINUS_EXPR when building a PLUS chain (treat MINUS as leaf).  */
    1797              : 
    1798              : static void
    1799      1881433 : vect_slp_linearize_chain (vec_info *vinfo,
    1800              :                           vec<std::pair<tree_code, gimple *> > &worklist,
    1801              :                           vec<chain_op_t> &chain,
    1802              :                           enum tree_code code, gimple *start,
    1803              :                           gimple *&code_stmt, gimple *&alt_code_stmt,
    1804              :                           vec<gimple *> *chain_stmts,
    1805              :                           bool allow_alt_code = true)
    1806              : {
    1807              :   /* For each lane linearize the addition/subtraction (or other
    1808              :      uniform associatable operation) expression tree.  */
    1809      1881433 :   worklist.safe_push (std::make_pair (code, start));
    1810      4365073 :   while (!worklist.is_empty ())
    1811              :     {
    1812      2483640 :       auto entry = worklist.pop ();
    1813      2483640 :       gassign *stmt = as_a <gassign *> (entry.second);
    1814      2483640 :       enum tree_code in_code = entry.first;
    1815      4967280 :       enum tree_code this_code = gimple_assign_rhs_code (stmt);
    1816              :       /* Pick some stmts suitable for SLP_TREE_REPRESENTATIVE.  */
    1817      2483640 :       if (!code_stmt
    1818      2483640 :           && gimple_assign_rhs_code (stmt) == code)
    1819      1584084 :         code_stmt = stmt;
    1820       899556 :       else if (!alt_code_stmt
    1821       899556 :                && gimple_assign_rhs_code (stmt) == MINUS_EXPR)
    1822       354520 :         alt_code_stmt = stmt;
    1823      2483640 :       if (chain_stmts)
    1824      2402497 :         chain_stmts->safe_push (stmt);
    1825      7450920 :       for (unsigned opnum = 1; opnum <= 2; ++opnum)
    1826              :         {
    1827      4967280 :           tree op = gimple_op (stmt, opnum);
    1828      4967280 :           vect_def_type dt;
    1829      4967280 :           stmt_vec_info def_stmt_info;
    1830      4967280 :           bool res = vect_is_simple_use (op, vinfo, &dt, &def_stmt_info);
    1831      4967280 :           gcc_assert (res);
    1832      4967280 :           if (dt == vect_internal_def
    1833      4967280 :               && is_pattern_stmt_p (def_stmt_info))
    1834         9255 :             op = gimple_get_lhs (def_stmt_info->stmt);
    1835      4967280 :           gimple *use_stmt;
    1836      4967280 :           use_operand_p use_p;
    1837      4967280 :           if (dt == vect_internal_def
    1838      4535203 :               && single_imm_use (op, &use_p, &use_stmt)
    1839      2917828 :               && is_gimple_assign (def_stmt_info->stmt)
    1840      7691697 :               && (gimple_assign_rhs_code (def_stmt_info->stmt) == code
    1841      2122525 :                   || (allow_alt_code
    1842        57260 :                       && code == PLUS_EXPR
    1843        36218 :                       && (gimple_assign_rhs_code (def_stmt_info->stmt)
    1844              :                           == MINUS_EXPR))))
    1845              :             {
    1846       602207 :               tree_code op_def_code = this_code;
    1847       602207 :               if (op_def_code == MINUS_EXPR && opnum == 1)
    1848        55385 :                 op_def_code = PLUS_EXPR;
    1849       602207 :               if (in_code == MINUS_EXPR)
    1850          222 :                 op_def_code = op_def_code == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR;
    1851       602207 :               worklist.safe_push (std::make_pair (op_def_code,
    1852       602207 :                                                   def_stmt_info->stmt));
    1853              :             }
    1854              :           else
    1855              :             {
    1856      4365073 :               tree_code op_def_code = this_code;
    1857      4365073 :               if (op_def_code == MINUS_EXPR && opnum == 1)
    1858       299252 :                 op_def_code = PLUS_EXPR;
    1859      4365073 :               if (in_code == MINUS_EXPR)
    1860         4278 :                 op_def_code = op_def_code == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR;
    1861      4365073 :               chain.safe_push (chain_op_t (op_def_code, dt, op));
    1862              :             }
    1863              :         }
    1864              :     }
    1865      1881433 : }
    1866              : 
    1867              : /* Distance from the node currently being discovered to the closest upthread
    1868              :    commutative operation whose operand-zero discovery may still be fixed by
    1869              :    retrying with swapped operands, or -1U if there is none.  */
    1870              : 
    1871              : static unsigned least_upthread_swappable_op_distance = -1U;
    1872              : 
    1873              : static slp_tree
    1874              : vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
    1875              :                        vec<stmt_vec_info> stmts,
    1876              :                        poly_uint64 *max_nunits,
    1877              :                        bool *matches, unsigned *limit, unsigned *tree_size,
    1878              :                        scalar_stmts_to_slp_tree_map_t *bst_map);
    1879              : 
    1880              : static slp_tree
    1881      6710806 : vect_build_slp_tree (vec_info *vinfo,
    1882              :                      vec<stmt_vec_info> stmts,
    1883              :                      poly_uint64 *max_nunits,
    1884              :                      bool *matches, unsigned *limit, unsigned *tree_size,
    1885              :                      scalar_stmts_to_slp_tree_map_t *bst_map)
    1886              : {
    1887      6710806 :   unsigned int group_size = stmts.length ();
    1888      6710806 :   if (slp_tree *leader = bst_map->get (stmts))
    1889              :     {
    1890       501157 :       if (dump_enabled_p ())
    1891        17368 :         dump_printf_loc (MSG_NOTE, vect_location, "re-using %sSLP tree %p\n",
    1892        17368 :                          !(*leader)->failed ? "" : "failed ",
    1893              :                          (void *) *leader);
    1894       501157 :       if (!(*leader)->failed)
    1895              :         {
    1896       451502 :           SLP_TREE_REF_COUNT (*leader)++;
    1897       451502 :           vect_update_max_nunits (max_nunits, (*leader)->max_nunits);
    1898       451502 :           stmts.release ();
    1899       451502 :           return *leader;
    1900              :         }
    1901        49655 :       memcpy (matches, (*leader)->failed, sizeof (bool) * group_size);
    1902        49655 :       return NULL;
    1903              :     }
    1904              : 
    1905              :   /* Single-lane SLP doesn't have the chance of run-away, do not account
    1906              :      it to the limit.  */
    1907      6209649 :   if (stmts.length () > 1)
    1908              :     {
    1909      3514883 :       if (*limit == 0)
    1910              :         {
    1911         1293 :           if (dump_enabled_p ())
    1912           15 :             dump_printf_loc (MSG_NOTE, vect_location,
    1913              :                              "SLP discovery limit exceeded\n");
    1914         1293 :           memset (matches, 0, sizeof (bool) * group_size);
    1915         1293 :           return NULL;
    1916              :         }
    1917      3513590 :       --*limit;
    1918              :     }
    1919              : 
    1920              :   /* Seed the bst_map with a stub node to be filled by vect_build_slp_tree_2
    1921              :      so we can pick up backedge destinations during discovery.  */
    1922      6208356 :   slp_tree res = new _slp_tree;
    1923      6208356 :   SLP_TREE_DEF_TYPE (res) = vect_internal_def;
    1924      6208356 :   SLP_TREE_SCALAR_STMTS (res) = stmts;
    1925      6208356 :   bst_map->put (stmts.copy (), res);
    1926              : 
    1927      6208356 :   if (dump_enabled_p ())
    1928       150120 :     dump_printf_loc (MSG_NOTE, vect_location,
    1929              :                      "starting SLP discovery for node %p\n", (void *) res);
    1930              : 
    1931      6208356 :   poly_uint64 this_max_nunits = 1;
    1932      6208356 :   slp_tree res_ = vect_build_slp_tree_2 (vinfo, res, stmts,
    1933              :                                         &this_max_nunits,
    1934              :                                         matches, limit, tree_size, bst_map);
    1935      6208356 :   if (!res_)
    1936              :     {
    1937      2251103 :       if (dump_enabled_p ())
    1938         7822 :         dump_printf_loc (MSG_NOTE, vect_location,
    1939              :                          "SLP discovery for node %p failed\n", (void *) res);
    1940              :       /* Mark the node invalid so we can detect those when still in use
    1941              :          as backedge destinations.  */
    1942      2251103 :       SLP_TREE_SCALAR_STMTS (res) = vNULL;
    1943      2251103 :       SLP_TREE_DEF_TYPE (res) = vect_uninitialized_def;
    1944      2251103 :       res->failed = XNEWVEC (bool, group_size);
    1945      2251103 :       if (flag_checking)
    1946              :         {
    1947              :           unsigned i;
    1948      4072625 :           for (i = 0; i < group_size; ++i)
    1949      4072625 :             if (!matches[i])
    1950              :               break;
    1951      2251103 :           gcc_assert (i < group_size);
    1952              :         }
    1953      2251103 :       memcpy (res->failed, matches, sizeof (bool) * group_size);
    1954              :     }
    1955              :   else
    1956              :     {
    1957      3957253 :       if (dump_enabled_p ())
    1958       142298 :         dump_printf_loc (MSG_NOTE, vect_location,
    1959              :                          "SLP discovery for node %p succeeded\n",
    1960              :                          (void *) res);
    1961      3957253 :       gcc_assert (res_ == res);
    1962      3957253 :       res->max_nunits = this_max_nunits;
    1963      3957253 :       vect_update_max_nunits (max_nunits, this_max_nunits);
    1964              :       /* Keep a reference for the bst_map use.  */
    1965      3957253 :       SLP_TREE_REF_COUNT (res)++;
    1966              :     }
    1967              :   return res_;
    1968              : }
    1969              : 
    1970              : /* Helper for building an associated SLP node chain.  */
    1971              : 
    1972              : static void
    1973          158 : vect_slp_build_two_operator_nodes (slp_tree perm, tree vectype,
    1974              :                                    slp_tree op0, slp_tree op1,
    1975              :                                    stmt_vec_info oper1, stmt_vec_info oper2,
    1976              :                                    vec<std::pair<unsigned, unsigned> > lperm)
    1977              : {
    1978          158 :   unsigned group_size = SLP_TREE_LANES (op1);
    1979              : 
    1980          158 :   slp_tree child1 = new _slp_tree;
    1981          158 :   SLP_TREE_DEF_TYPE (child1) = vect_internal_def;
    1982          158 :   SLP_TREE_VECTYPE (child1) = vectype;
    1983          158 :   SLP_TREE_LANES (child1) = group_size;
    1984          158 :   SLP_TREE_CHILDREN (child1).create (2);
    1985          158 :   SLP_TREE_CHILDREN (child1).quick_push (op0);
    1986          158 :   SLP_TREE_CHILDREN (child1).quick_push (op1);
    1987          158 :   SLP_TREE_REPRESENTATIVE (child1) = oper1;
    1988              : 
    1989          158 :   slp_tree child2 = new _slp_tree;
    1990          158 :   SLP_TREE_DEF_TYPE (child2) = vect_internal_def;
    1991          158 :   SLP_TREE_VECTYPE (child2) = vectype;
    1992          158 :   SLP_TREE_LANES (child2) = group_size;
    1993          158 :   SLP_TREE_CHILDREN (child2).create (2);
    1994          158 :   SLP_TREE_CHILDREN (child2).quick_push (op0);
    1995          158 :   SLP_TREE_REF_COUNT (op0)++;
    1996          158 :   SLP_TREE_CHILDREN (child2).quick_push (op1);
    1997          158 :   SLP_TREE_REF_COUNT (op1)++;
    1998          158 :   SLP_TREE_REPRESENTATIVE (child2) = oper2;
    1999              : 
    2000          158 :   SLP_TREE_DEF_TYPE (perm) = vect_internal_def;
    2001          158 :   SLP_TREE_CODE (perm) = VEC_PERM_EXPR;
    2002          158 :   SLP_TREE_VECTYPE (perm) = vectype;
    2003          158 :   SLP_TREE_LANES (perm) = group_size;
    2004              :   /* ???  We should set this NULL but that's not expected.  */
    2005          158 :   SLP_TREE_REPRESENTATIVE (perm) = oper1;
    2006          158 :   SLP_TREE_LANE_PERMUTATION (perm) = lperm;
    2007          158 :   SLP_TREE_CHILDREN (perm).quick_push (child1);
    2008          158 :   SLP_TREE_CHILDREN (perm).quick_push (child2);
    2009          158 : }
    2010              : 
    2011              : /* Recursively build an SLP tree starting from NODE.
    2012              :    Fail (and return a value not equal to zero) if def-stmts are not
    2013              :    isomorphic, require data permutation or are of unsupported types of
    2014              :    operation.  Otherwise, return 0.
    2015              :    The value returned is the depth in the SLP tree where a mismatch
    2016              :    was found.  */
    2017              : 
    2018              : static slp_tree
    2019      6208356 : vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
    2020              :                        vec<stmt_vec_info> stmts,
    2021              :                        poly_uint64 *max_nunits,
    2022              :                        bool *matches, unsigned *limit, unsigned *tree_size,
    2023              :                        scalar_stmts_to_slp_tree_map_t *bst_map)
    2024              : {
    2025      6208356 :   unsigned int group_size = stmts.length ();
    2026      6208356 :   unsigned nops, i, this_tree_size = 0;
    2027      6208356 :   poly_uint64 this_max_nunits = *max_nunits;
    2028              : 
    2029      6208356 :   matches[0] = false;
    2030              : 
    2031      6208356 :   stmt_vec_info stmt_info = stmts[0];
    2032      6208356 :   if (!is_a<gcall *> (stmt_info->stmt)
    2033              :       && !is_a<gassign *> (stmt_info->stmt)
    2034              :       && !is_a<gphi *> (stmt_info->stmt))
    2035              :     return NULL;
    2036              : 
    2037      6208258 :   nops = gimple_num_args (stmt_info->stmt);
    2038      6208258 :   if (const int *map = vect_get_operand_map (stmt_info))
    2039        37037 :     nops = map[0];
    2040              : 
    2041              :   /* If the SLP node is a PHI (induction or reduction), terminate
    2042              :      the recursion.  */
    2043      6208258 :   bool *skip_args = XALLOCAVEC (bool, nops);
    2044      6208258 :   memset (skip_args, 0, sizeof (bool) * nops);
    2045      6208258 :   if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
    2046      2893135 :     if (gphi *stmt = dyn_cast <gphi *> (stmt_info->stmt))
    2047              :       {
    2048       315498 :         tree scalar_type = TREE_TYPE (PHI_RESULT (stmt));
    2049       315498 :         tree vectype = get_vectype_for_scalar_type (vinfo, scalar_type,
    2050              :                                                     group_size);
    2051       315498 :         if (!vect_record_max_nunits (vinfo, stmt_info, group_size, vectype,
    2052              :                                      max_nunits))
    2053              :           return NULL;
    2054              : 
    2055       311470 :         vect_def_type def_type = STMT_VINFO_DEF_TYPE (stmt_info);
    2056       311470 :         if (def_type == vect_induction_def)
    2057              :           {
    2058              :             /* Induction PHIs are not cycles but walk the initial
    2059              :                value.  Only for inner loops through, for outer loops
    2060              :                we need to pick up the value from the actual PHIs
    2061              :                to more easily support peeling and epilogue vectorization.  */
    2062       203216 :             class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
    2063       203216 :             if (!nested_in_vect_loop_p (loop, stmt_info))
    2064       202357 :               skip_args[loop_preheader_edge (loop)->dest_idx] = true;
    2065              :             else
    2066              :               loop = loop->inner;
    2067       203216 :             skip_args[loop_latch_edge (loop)->dest_idx] = true;
    2068              :           }
    2069       108254 :         else if (def_type == vect_reduction_def
    2070              :                  || def_type == vect_double_reduction_def
    2071              :                  || def_type == vect_nested_cycle
    2072       108254 :                  || def_type == vect_first_order_recurrence)
    2073              :           {
    2074              :             /* Else def types have to match.  */
    2075              :             stmt_vec_info other_info;
    2076              :             bool all_same = true;
    2077       244712 :             FOR_EACH_VEC_ELT (stmts, i, other_info)
    2078              :               {
    2079       137784 :                 if (STMT_VINFO_DEF_TYPE (other_info) != def_type)
    2080      1993439 :                   return NULL;
    2081       137778 :                 if (other_info != stmt_info)
    2082        26228 :                   all_same = false;
    2083              :               }
    2084       106928 :             class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
    2085              :             /* Reduction initial values are not explicitly represented.  */
    2086       106928 :             if (def_type != vect_first_order_recurrence
    2087       106928 :                 && gimple_bb (stmt_info->stmt) == loop->header)
    2088       103681 :               skip_args[loop_preheader_edge (loop)->dest_idx] = true;
    2089              :             /* Reduction chain backedge defs are filled manually.
    2090              :                ???  Need a better way to identify a SLP reduction chain PHI.
    2091              :                Or a better overall way to SLP match those.  */
    2092       106928 :             if (stmts.length () > 1
    2093       106928 :                 && all_same && def_type == vect_reduction_def)
    2094         2364 :               skip_args[loop_latch_edge (loop)->dest_idx] = true;
    2095              :           }
    2096         1320 :         else if (def_type != vect_internal_def)
    2097              :           return NULL;
    2098              :       }
    2099              : 
    2100              : 
    2101      6204224 :   bool two_operators = false;
    2102      6204224 :   unsigned char *swap = XALLOCAVEC (unsigned char, group_size);
    2103      6204224 :   tree vectype = NULL_TREE;
    2104      6204224 :   if (!vect_build_slp_tree_1 (vinfo, swap, stmts,
    2105              :                               &this_max_nunits, matches, &two_operators,
    2106              :                               &vectype))
    2107              :     return NULL;
    2108              : 
    2109              :   /* If the SLP node is a load, terminate the recursion unless masked.  */
    2110      4453460 :   if (STMT_VINFO_DATA_REF (stmt_info)
    2111      2097900 :       && DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)))
    2112              :     {
    2113       945289 :       if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
    2114              :         gcc_assert (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)));
    2115              :       else
    2116              :         {
    2117       925739 :           *max_nunits = this_max_nunits;
    2118       925739 :           (*tree_size)++;
    2119       925739 :           node = vect_create_new_slp_node (node, stmts, 0);
    2120       925739 :           SLP_TREE_VECTYPE (node) = vectype;
    2121              :           /* And compute the load permutation.  Whether it is actually
    2122              :              a permutation depends on the unrolling factor which is
    2123              :              decided later.  */
    2124       925739 :           vec<unsigned> load_permutation;
    2125       925739 :           int j;
    2126       925739 :           stmt_vec_info load_info;
    2127       925739 :           load_permutation.create (group_size);
    2128       925739 :           stmt_vec_info first_stmt_info
    2129       925739 :             = STMT_VINFO_GROUPED_ACCESS (stmt_info)
    2130       925739 :               ? DR_GROUP_FIRST_ELEMENT (stmt_info) : stmt_info;
    2131       925739 :           bool any_permute = false;
    2132      2243029 :           FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), j, load_info)
    2133              :             {
    2134      1317290 :               int load_place;
    2135      1317290 :               if (! load_info)
    2136              :                 {
    2137        40839 :                   if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
    2138              :                     load_place = j;
    2139              :                   else
    2140              :                     load_place = 0;
    2141              :                 }
    2142      1276451 :               else if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
    2143       749780 :                 load_place = vect_get_place_in_interleaving_chain
    2144       749780 :                     (load_info, first_stmt_info);
    2145              :               else
    2146              :                 /* Recognize the splat case as { 0, 0, ... } but make
    2147              :                    sure to use the appropriate refs for collections
    2148              :                    of invariant refs.  */
    2149       526671 :                 load_place = (load_info == stmt_info) ? 0 : j;
    2150       790860 :               gcc_assert (load_place != -1);
    2151      1317290 :               any_permute |= load_place != j;
    2152      1317290 :               load_permutation.quick_push (load_place);
    2153              :             }
    2154              : 
    2155       925739 :           if (gcall *stmt = dyn_cast <gcall *> (stmt_info->stmt))
    2156              :             {
    2157         3500 :               gcc_assert (gimple_call_internal_p (stmt, IFN_MASK_LOAD));
    2158         3500 :               bool has_gaps = false;
    2159         3500 :               if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
    2160          189 :                 for (stmt_vec_info si = DR_GROUP_NEXT_ELEMENT (first_stmt_info);
    2161          846 :                      si; si = DR_GROUP_NEXT_ELEMENT (si))
    2162          657 :                   if (DR_GROUP_GAP (si) != 1)
    2163           80 :                     has_gaps = true;
    2164              :               /* We cannot handle permuted masked loads directly, see
    2165              :                  PR114375.  We cannot handle strided masked loads or masked
    2166              :                  loads with gaps unless the mask is uniform.  */
    2167         3500 :               if ((STMT_VINFO_GROUPED_ACCESS (stmt_info)
    2168          189 :                    && (DR_GROUP_GAP (first_stmt_info) != 0
    2169          129 :                        || (has_gaps
    2170           35 :                            && STMT_VINFO_SLP_VECT_ONLY (first_stmt_info))))
    2171         6920 :                   || STMT_VINFO_STRIDED_P (stmt_info))
    2172              :                 {
    2173           93 :                   load_permutation.release ();
    2174           93 :                   matches[0] = false;
    2175       922371 :                   return NULL;
    2176              :                 }
    2177              : 
    2178              :               /* For permuted masked loads do an unpermuted masked load of
    2179              :                  the whole group followed by a SLP permute node.  */
    2180         3407 :               if (any_permute
    2181         3407 :                   || (STMT_VINFO_GROUPED_ACCESS (stmt_info)
    2182           83 :                       && DR_GROUP_SIZE (first_stmt_info) != group_size))
    2183              :                 {
    2184              :                   /* Discover the whole unpermuted load.  */
    2185           39 :                   vec<stmt_vec_info> stmts2;
    2186           39 :                   unsigned dr_group_size = STMT_VINFO_GROUPED_ACCESS (stmt_info)
    2187           68 :                       ? DR_GROUP_SIZE (first_stmt_info) : 1;
    2188           39 :                   stmts2.create (dr_group_size);
    2189           39 :                   stmts2.quick_grow_cleared (dr_group_size);
    2190           39 :                   unsigned i = 0;
    2191           39 :                   for (stmt_vec_info si = first_stmt_info;
    2192          464 :                        si; si = DR_GROUP_NEXT_ELEMENT (si))
    2193              :                     {
    2194          425 :                       if (si != first_stmt_info)
    2195         1586 :                         for (unsigned k = 1; k < DR_GROUP_GAP (si); ++k)
    2196         1200 :                           stmts2[i++] = NULL;
    2197          425 :                       stmts2[i++] = si;
    2198              :                     }
    2199           39 :                   bool *matches2 = XALLOCAVEC (bool, dr_group_size);
    2200           39 :                   slp_tree unperm_load
    2201           39 :                     = vect_build_slp_tree (vinfo, stmts2,
    2202              :                                            &this_max_nunits, matches2, limit,
    2203           39 :                                            &this_tree_size, bst_map);
    2204              :                   /* When we are able to do the full masked load emit that
    2205              :                      followed by 'node' being the desired final permutation.  */
    2206           39 :                   if (unperm_load)
    2207              :                     {
    2208           16 :                       gcc_assert
    2209              :                         (!SLP_TREE_LOAD_PERMUTATION (unperm_load).exists ());
    2210           16 :                       lane_permutation_t lperm;
    2211           16 :                       lperm.create (group_size);
    2212           56 :                       for (unsigned j = 0; j < load_permutation.length (); ++j)
    2213           40 :                         lperm.quick_push
    2214           40 :                           (std::make_pair (0, load_permutation[j]));
    2215           16 :                       SLP_TREE_CODE (node) = VEC_PERM_EXPR;
    2216           16 :                       SLP_TREE_CHILDREN (node).safe_push (unperm_load);
    2217           16 :                       SLP_TREE_LANE_PERMUTATION (node) = lperm;
    2218           16 :                       load_permutation.release ();
    2219           16 :                       return node;
    2220              :                     }
    2221           23 :                   stmts2.release ();
    2222           23 :                   load_permutation.release ();
    2223           23 :                   matches[0] = false;
    2224           23 :                   return NULL;
    2225              :                 }
    2226         3368 :               load_permutation.release ();
    2227              :             }
    2228              :           else
    2229              :             {
    2230       922239 :               if (!any_permute
    2231       793659 :                   && STMT_VINFO_GROUPED_ACCESS (stmt_info)
    2232      1215559 :                   && group_size == DR_GROUP_SIZE (first_stmt_info))
    2233       128703 :                 load_permutation.release ();
    2234       922239 :               SLP_TREE_LOAD_PERMUTATION (node) = load_permutation;
    2235       922239 :               return node;
    2236              :             }
    2237              :         }
    2238              :     }
    2239      3508171 :   else if (gimple_assign_single_p (stmt_info->stmt)
    2240      2312060 :            && !gimple_vuse (stmt_info->stmt)
    2241      3517034 :            && gimple_assign_rhs_code (stmt_info->stmt) == BIT_FIELD_REF)
    2242              :     {
    2243              :       /* vect_build_slp_tree_2 determined all BIT_FIELD_REFs reference
    2244              :          the same SSA name vector of a compatible type to vectype.  */
    2245         3386 :       vec<std::pair<unsigned, unsigned> > lperm = vNULL;
    2246         3386 :       tree vec = TREE_OPERAND (gimple_assign_rhs1 (stmt_info->stmt), 0);
    2247         3386 :       stmt_vec_info estmt_info;
    2248        11982 :       FOR_EACH_VEC_ELT (stmts, i, estmt_info)
    2249              :         {
    2250         8743 :           gassign *estmt = as_a <gassign *> (estmt_info->stmt);
    2251         8743 :           tree bfref = gimple_assign_rhs1 (estmt);
    2252         8743 :           HOST_WIDE_INT lane;
    2253         8743 :           if (!known_eq (bit_field_size (bfref),
    2254              :                          tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (vectype))))
    2255        17339 :               || !constant_multiple_p (bit_field_offset (bfref),
    2256         8596 :                                        bit_field_size (bfref), &lane))
    2257              :             {
    2258          147 :               lperm.release ();
    2259          147 :               matches[0] = false;
    2260          147 :               return NULL;
    2261              :             }
    2262         8596 :           lperm.safe_push (std::make_pair (0, (unsigned)lane));
    2263              :         }
    2264         3239 :       slp_tree vnode = vect_create_new_slp_node (vNULL);
    2265         3239 :       if (operand_equal_p (TYPE_SIZE (vectype), TYPE_SIZE (TREE_TYPE (vec))))
    2266              :         /* ???  We record vectype here but we hide eventually necessary
    2267              :            punning and instead rely on code generation to materialize
    2268              :            VIEW_CONVERT_EXPRs as necessary.  We instead should make
    2269              :            this explicit somehow.  */
    2270         1445 :         SLP_TREE_VECTYPE (vnode) = vectype;
    2271              :       else
    2272              :         {
    2273              :           /* For different size but compatible elements we can still
    2274              :              use VEC_PERM_EXPR without punning.  */
    2275         1794 :           gcc_assert (VECTOR_TYPE_P (TREE_TYPE (vec))
    2276              :                       && types_compatible_p (TREE_TYPE (vectype),
    2277              :                                              TREE_TYPE (TREE_TYPE (vec))));
    2278         1794 :           SLP_TREE_VECTYPE (vnode) = TREE_TYPE (vec);
    2279              :         }
    2280         3239 :       auto nunits = TYPE_VECTOR_SUBPARTS (SLP_TREE_VECTYPE (vnode));
    2281         3239 :       unsigned HOST_WIDE_INT const_nunits;
    2282         3239 :       if (nunits.is_constant (&const_nunits))
    2283         3239 :         SLP_TREE_LANES (vnode) = const_nunits;
    2284         3239 :       SLP_TREE_VEC_DEFS (vnode).safe_push (vec);
    2285              :       /* We are always building a permutation node even if it is an identity
    2286              :          permute to shield the rest of the vectorizer from the odd node
    2287              :          representing an actual vector without any scalar ops.
    2288              :          ???  We could hide it completely with making the permute node
    2289              :          external?  */
    2290         3239 :       node = vect_create_new_slp_node (node, stmts, 1);
    2291         3239 :       SLP_TREE_CODE (node) = VEC_PERM_EXPR;
    2292         3239 :       SLP_TREE_LANE_PERMUTATION (node) = lperm;
    2293         3239 :       SLP_TREE_VECTYPE (node) = vectype;
    2294         3239 :       SLP_TREE_CHILDREN (node).quick_push (vnode);
    2295         3239 :       return node;
    2296              :     }
    2297              :   /* When discovery reaches an associatable operation see whether we can
    2298              :      improve that to match up lanes in a way superior to the operand
    2299              :      swapping code which at most looks at two defs.
    2300              :      ???  For BB vectorization we cannot do the brute-force search
    2301              :      for matching as we can succeed by means of builds from scalars
    2302              :      and have no good way to "cost" one build against another.  */
    2303      3504785 :   else if (is_a <loop_vec_info> (vinfo)
    2304              :            /* Do not bother for single-lane SLP.  */
    2305      2056749 :            && group_size > 1
    2306              :            /* ???  We don't handle !vect_internal_def defs below.  */
    2307       113605 :            && STMT_VINFO_DEF_TYPE (stmt_info) == vect_internal_def
    2308              :            /* ???  Do not associate a reduction, this will wreck REDUC_IDX
    2309              :               mapping as long as that exists on the stmt_info level.  */
    2310        88062 :            && STMT_VINFO_REDUC_IDX (stmt_info) == -1
    2311        79513 :            && is_gimple_assign (stmt_info->stmt)
    2312        79194 :            && (associative_tree_code (gimple_assign_rhs_code (stmt_info->stmt))
    2313        52334 :                || gimple_assign_rhs_code (stmt_info->stmt) == MINUS_EXPR)
    2314      3533595 :            && ((FLOAT_TYPE_P (vectype) && flag_associative_math)
    2315        16555 :                || (INTEGRAL_TYPE_P (TREE_TYPE (vectype))
    2316        14021 :                    && TYPE_OVERFLOW_WRAPS (TREE_TYPE (vectype)))))
    2317              :     {
    2318              :       /* See if we have a chain of (mixed) adds or subtracts or other
    2319              :          associatable ops.  */
    2320        21767 :       enum tree_code code = gimple_assign_rhs_code (stmt_info->stmt);
    2321        21767 :       if (code == MINUS_EXPR)
    2322          848 :         code = PLUS_EXPR;
    2323        21767 :       stmt_vec_info other_op_stmt_info = NULL;
    2324        21767 :       stmt_vec_info op_stmt_info = NULL;
    2325        21767 :       unsigned chain_len = 0;
    2326        21767 :       auto_vec<chain_op_t> chain;
    2327        21767 :       auto_vec<std::pair<tree_code, gimple *> > worklist;
    2328        21767 :       auto_vec<vec<chain_op_t> > chains (group_size);
    2329        21767 :       auto_vec<slp_tree, 4> children;
    2330        21767 :       bool hard_fail = true;
    2331        22794 :       for (unsigned lane = 0; lane < group_size; ++lane)
    2332              :         {
    2333        22458 :           if (!stmts[lane])
    2334              :             {
    2335              :               /* ???  Below we require lane zero is present.  */
    2336            0 :               if (lane == 0)
    2337              :                 {
    2338              :                   hard_fail = false;
    2339        21431 :                   break;
    2340              :                 }
    2341            0 :               chains.quick_push (vNULL);
    2342            0 :               continue;
    2343              :             }
    2344              :           /* For each lane linearize the addition/subtraction (or other
    2345              :              uniform associatable operation) expression tree.  */
    2346        22458 :           gimple *op_stmt = NULL, *other_op_stmt = NULL;
    2347        22458 :           vect_slp_linearize_chain (vinfo, worklist, chain, code,
    2348        22458 :                                     stmts[lane]->stmt, op_stmt, other_op_stmt,
    2349              :                                     NULL);
    2350        22458 :           if (!op_stmt_info && op_stmt)
    2351        21116 :             op_stmt_info = vinfo->lookup_stmt (op_stmt);
    2352        22458 :           if (!other_op_stmt_info && other_op_stmt)
    2353          884 :             other_op_stmt_info = vinfo->lookup_stmt (other_op_stmt);
    2354        22458 :           if (chain.length () == 2)
    2355              :             {
    2356              :               /* In a chain of just two elements resort to the regular
    2357              :                  operand swapping scheme.  Likewise if we run into a
    2358              :                  length mismatch process regularly as well as we did not
    2359              :                  process the other lanes we cannot report a good hint what
    2360              :                  lanes to try swapping in the parent.  */
    2361              :               hard_fail = false;
    2362              :               break;
    2363              :             }
    2364         1030 :           else if (chain_len == 0)
    2365          376 :             chain_len = chain.length ();
    2366         1308 :           else if (chain.length () != chain_len)
    2367              :             {
    2368              :               /* ???  Here we could slip in magic to compensate with
    2369              :                  neutral operands.  */
    2370            3 :               matches[lane] = false;
    2371            3 :               if (lane != group_size - 1)
    2372            3 :                 matches[0] = false;
    2373              :               break;
    2374              :             }
    2375         1027 :           chains.quick_push (chain.copy ());
    2376         1027 :           chain.truncate (0);
    2377              :         }
    2378        43534 :       if (chains.length () == group_size)
    2379              :         {
    2380              :           /* We cannot yet use SLP_TREE_CODE to communicate the operation.  */
    2381          336 :           if (!op_stmt_info)
    2382              :             {
    2383            3 :               hard_fail = false;
    2384            3 :               goto out;
    2385              :             }
    2386              :           /* Now we have a set of chains with the same length.  */
    2387              :           /* 1. pre-sort according to def_type and operation.  */
    2388         1248 :           for (unsigned lane = 0; lane < group_size; ++lane)
    2389         1830 :             chains[lane].stablesort (dt_sort_cmp, vinfo);
    2390          333 :           if (dump_enabled_p ())
    2391              :             {
    2392          157 :               dump_printf_loc (MSG_NOTE, vect_location,
    2393              :                                "pre-sorted chains of %s\n",
    2394              :                                get_tree_code_name (code));
    2395          685 :               for (unsigned lane = 0; lane < group_size; ++lane)
    2396              :                 {
    2397          528 :                   if (!stmts[lane])
    2398            0 :                     dump_printf (MSG_NOTE, "--");
    2399              :                   else
    2400         2422 :                     for (unsigned opnum = 0; opnum < chain_len; ++opnum)
    2401         3788 :                       dump_printf (MSG_NOTE, "%s %T ",
    2402         1894 :                                    get_tree_code_name (chains[lane][opnum].code),
    2403         1894 :                                    chains[lane][opnum].op);
    2404          528 :                   dump_printf (MSG_NOTE, "\n");
    2405              :                 }
    2406              :             }
    2407              :           /* 2. try to build children nodes, associating as necessary.  */
    2408              :           /* 2a. prepare and perform early checks to avoid eating into
    2409              :              discovery limit unnecessarily.  */
    2410          333 :           vect_def_type *dts = XALLOCAVEC (vect_def_type, chain_len);
    2411         1407 :           for (unsigned n = 0; n < chain_len; ++n)
    2412              :             {
    2413         1074 :               vect_def_type dt = chains[0][n].dt;
    2414         1074 :               unsigned lane;
    2415         4177 :               for (lane = 0; lane < group_size; ++lane)
    2416         6206 :                 if (stmts[lane] && chains[lane][n].dt != dt)
    2417              :                   {
    2418            0 :                     if (dt == vect_constant_def
    2419            0 :                         && chains[lane][n].dt == vect_external_def)
    2420              :                       dt = vect_external_def;
    2421            0 :                     else if (dt == vect_external_def
    2422            0 :                              && chains[lane][n].dt == vect_constant_def)
    2423              :                       ;
    2424              :                     else
    2425              :                       break;
    2426              :                   }
    2427         1074 :               if (lane != group_size)
    2428              :                 {
    2429            0 :                   if (dump_enabled_p ())
    2430            0 :                     dump_printf_loc (MSG_NOTE, vect_location,
    2431              :                                      "giving up on chain due to mismatched "
    2432              :                                      "def types\n");
    2433            0 :                   matches[lane] = false;
    2434            0 :                   if (lane != group_size - 1)
    2435            0 :                     matches[0] = false;
    2436            0 :                   goto out;
    2437              :                 }
    2438         1074 :               dts[n] = dt;
    2439         1074 :               if (dt == vect_constant_def
    2440         1074 :                   || dt == vect_external_def)
    2441              :                 {
    2442              :                   /* Check whether we can build the invariant.  If we can't
    2443              :                      we never will be able to.  */
    2444           93 :                   tree type = TREE_TYPE (chains[0][n].op);
    2445         1074 :                   if (!GET_MODE_SIZE (vinfo->vector_mode).is_constant ()
    2446              :                       && (TREE_CODE (type) == BOOLEAN_TYPE
    2447              :                           || !can_duplicate_and_interleave_p (vinfo, group_size,
    2448              :                                                               type)))
    2449              :                     {
    2450              :                       matches[0] = false;
    2451              :                       goto out;
    2452              :                     }
    2453              :                 }
    2454          981 :               else if (dt != vect_internal_def)
    2455              :                 {
    2456              :                   /* Not sure, we might need sth special.
    2457              :                      gcc.dg/vect/pr96854.c,
    2458              :                      gfortran.dg/vect/fast-math-pr37021.f90
    2459              :                      and gfortran.dg/vect/pr61171.f trigger.  */
    2460              :                   /* Soft-fail for now.  */
    2461            0 :                   hard_fail = false;
    2462            0 :                   goto out;
    2463              :                 }
    2464              :             }
    2465              :           /* 2b. do the actual build.  */
    2466         1353 :           for (unsigned n = 0; n < chain_len; ++n)
    2467              :             {
    2468         1039 :               vect_def_type dt = dts[n];
    2469         1039 :               unsigned lane;
    2470         1039 :               if (dt == vect_constant_def
    2471         1039 :                   || dt == vect_external_def)
    2472              :                 {
    2473           93 :                   vec<tree> ops;
    2474           93 :                   ops.create (group_size);
    2475          461 :                   for (lane = 0; lane < group_size; ++lane)
    2476          275 :                     if (stmts[lane])
    2477          275 :                       ops.quick_push (chains[lane][n].op);
    2478              :                     else
    2479            0 :                       ops.quick_push (NULL_TREE);
    2480           93 :                   slp_tree child = vect_create_new_slp_node (ops);
    2481           93 :                   SLP_TREE_DEF_TYPE (child) = dt;
    2482           93 :                   children.safe_push (child);
    2483              :                 }
    2484              :               else
    2485              :                 {
    2486          946 :                   vec<stmt_vec_info> op_stmts;
    2487          946 :                   op_stmts.create (group_size);
    2488          946 :                   slp_tree child = NULL;
    2489              :                   /* Brute-force our way.  We have to consider a lane
    2490              :                      failing after fixing an earlier fail up in the
    2491              :                      SLP discovery recursion.  So track the current
    2492              :                      permute per lane.  */
    2493          946 :                   unsigned *perms = XALLOCAVEC (unsigned, group_size);
    2494          946 :                   memset (perms, 0, sizeof (unsigned) * group_size);
    2495         1040 :                   do
    2496              :                     {
    2497         1040 :                       op_stmts.truncate (0);
    2498         5092 :                       for (lane = 0; lane < group_size; ++lane)
    2499         3012 :                         if (stmts[lane])
    2500         3012 :                           op_stmts.quick_push
    2501         3012 :                             (vinfo->lookup_def (chains[lane][n].op));
    2502              :                         else
    2503            0 :                           op_stmts.quick_push (NULL);
    2504         1040 :                       child = vect_build_slp_tree (vinfo, op_stmts,
    2505              :                                                    &this_max_nunits,
    2506              :                                                    matches, limit,
    2507              :                                                    &this_tree_size, bst_map);
    2508              :                       /* ???  We're likely getting too many fatal mismatches
    2509              :                          here so maybe we want to ignore them (but then we
    2510              :                          have no idea which lanes fatally mismatched).  */
    2511         1040 :                       if (child || !matches[0])
    2512              :                         break;
    2513              :                       /* Swap another lane we have not yet matched up into
    2514              :                          lanes that did not match.  If we run out of
    2515              :                          permute possibilities for a lane terminate the
    2516              :                          search.  */
    2517          287 :                       bool term = false;
    2518          287 :                       for (lane = 1; lane < group_size; ++lane)
    2519          193 :                         if (!matches[lane])
    2520              :                           {
    2521          165 :                             if (n + perms[lane] + 1 == chain_len)
    2522              :                               {
    2523              :                                 term = true;
    2524              :                                 break;
    2525              :                               }
    2526          146 :                             if (dump_enabled_p ())
    2527          113 :                               dump_printf_loc (MSG_NOTE, vect_location,
    2528              :                                                "swapping operand %d and %d "
    2529              :                                                "of lane %d\n",
    2530              :                                                n, n + perms[lane] + 1, lane);
    2531          292 :                             std::swap (chains[lane][n],
    2532          146 :                                        chains[lane][n + perms[lane] + 1]);
    2533          146 :                             perms[lane]++;
    2534              :                           }
    2535          113 :                       if (term)
    2536              :                         break;
    2537              :                     }
    2538              :                   while (1);
    2539          946 :                   if (!child)
    2540              :                     {
    2541           19 :                       if (dump_enabled_p ())
    2542           18 :                         dump_printf_loc (MSG_NOTE, vect_location,
    2543              :                                          "failed to match up op %d\n", n);
    2544           19 :                       op_stmts.release ();
    2545           19 :                       if (lane != group_size - 1)
    2546            9 :                         matches[0] = false;
    2547              :                       else
    2548           10 :                         matches[lane] = false;
    2549           19 :                       goto out;
    2550              :                     }
    2551          927 :                   if (dump_enabled_p ())
    2552              :                     {
    2553          421 :                       dump_printf_loc (MSG_NOTE, vect_location,
    2554              :                                        "matched up op %d to\n", n);
    2555          421 :                       vect_print_slp_tree (MSG_NOTE, vect_location, child);
    2556              :                     }
    2557          927 :                   children.safe_push (child);
    2558              :                 }
    2559              :             }
    2560              :           /* 3. build SLP nodes to combine the chain.  */
    2561         1156 :           for (unsigned lane = 0; lane < group_size; ++lane)
    2562         1696 :             if (stmts[lane] && chains[lane][0].code != code)
    2563              :               {
    2564              :                 /* See if there's any alternate all-PLUS entry.  */
    2565              :                 unsigned n;
    2566            6 :                 for (n = 1; n < chain_len; ++n)
    2567              :                   {
    2568           30 :                     for (lane = 0; lane < group_size; ++lane)
    2569           48 :                       if (stmts[lane] && chains[lane][n].code != code)
    2570              :                         break;
    2571            6 :                     if (lane == group_size)
    2572              :                       break;
    2573              :                   }
    2574            6 :                 if (n != chain_len)
    2575              :                   {
    2576              :                     /* Swap that in at first position.  */
    2577            6 :                     std::swap (children[0], children[n]);
    2578           30 :                     for (lane = 0; lane < group_size; ++lane)
    2579           24 :                       if (stmts[lane])
    2580           24 :                         std::swap (chains[lane][0], chains[lane][n]);
    2581              :                   }
    2582              :                 else
    2583              :                   {
    2584              :                     /* ???  When this triggers and we end up with two
    2585              :                        vect_constant/external_def up-front things break (ICE)
    2586              :                        spectacularly finding an insertion place for the
    2587              :                        all-constant op.  We should have a fully
    2588              :                        vect_internal_def operand though(?) so we can swap
    2589              :                        that into first place and then prepend the all-zero
    2590              :                        constant.  */
    2591            0 :                     if (dump_enabled_p ())
    2592            0 :                       dump_printf_loc (MSG_NOTE, vect_location,
    2593              :                                        "inserting constant zero to compensate "
    2594              :                                        "for (partially) negated first "
    2595              :                                        "operand\n");
    2596            0 :                     chain_len++;
    2597            0 :                     for (lane = 0; lane < group_size; ++lane)
    2598            0 :                       if (stmts[lane])
    2599            0 :                         chains[lane].safe_insert
    2600            0 :                           (0, chain_op_t (code, vect_constant_def, NULL_TREE));
    2601            0 :                     vec<tree> zero_ops;
    2602            0 :                     zero_ops.create (group_size);
    2603            0 :                     zero_ops.quick_push (build_zero_cst (TREE_TYPE (vectype)));
    2604            0 :                     for (lane = 1; lane < group_size; ++lane)
    2605            0 :                       if (stmts[lane])
    2606            0 :                         zero_ops.quick_push (zero_ops[0]);
    2607              :                       else
    2608            0 :                         zero_ops.quick_push (NULL_TREE);
    2609            0 :                     slp_tree zero = vect_create_new_slp_node (zero_ops);
    2610            0 :                     SLP_TREE_DEF_TYPE (zero) = vect_constant_def;
    2611            0 :                     children.safe_insert (0, zero);
    2612              :                   }
    2613              :                 break;
    2614              :               }
    2615         1015 :           for (unsigned i = 1; i < children.length (); ++i)
    2616              :             {
    2617          701 :               slp_tree op0 = children[i - 1];
    2618          701 :               slp_tree op1 = children[i];
    2619          701 :               bool this_two_op = false;
    2620         2569 :               for (unsigned lane = 0; lane < group_size; ++lane)
    2621         4052 :                 if (stmts[lane] && chains[lane][i].code != chains[0][i].code)
    2622              :                   {
    2623              :                     this_two_op = true;
    2624              :                     break;
    2625              :                   }
    2626          701 :               slp_tree child;
    2627          701 :               if (i == children.length () - 1)
    2628          314 :                 child = vect_create_new_slp_node (node, stmts, 2);
    2629              :               else
    2630          387 :                 child = vect_create_new_slp_node (2, ERROR_MARK);
    2631          701 :               if (this_two_op)
    2632              :                 {
    2633          158 :                   vec<std::pair<unsigned, unsigned> > lperm;
    2634          158 :                   lperm.create (group_size);
    2635          570 :                   for (unsigned lane = 0; lane < group_size; ++lane)
    2636          824 :                     lperm.quick_push (std::make_pair
    2637          412 :                       (chains[lane][i].code != chains[0][i].code, lane));
    2638          316 :                   vect_slp_build_two_operator_nodes (child, vectype, op0, op1,
    2639          158 :                                                      (chains[0][i].code == code
    2640              :                                                       ? op_stmt_info
    2641              :                                                       : other_op_stmt_info),
    2642          158 :                                                      (chains[0][i].code == code
    2643              :                                                       ? other_op_stmt_info
    2644              :                                                       : op_stmt_info),
    2645              :                                                      lperm);
    2646              :                 }
    2647              :               else
    2648              :                 {
    2649          543 :                   SLP_TREE_DEF_TYPE (child) = vect_internal_def;
    2650          543 :                   SLP_TREE_VECTYPE (child) = vectype;
    2651          543 :                   SLP_TREE_LANES (child) = group_size;
    2652          543 :                   SLP_TREE_CHILDREN (child).quick_push (op0);
    2653          543 :                   SLP_TREE_CHILDREN (child).quick_push (op1);
    2654          543 :                   SLP_TREE_REPRESENTATIVE (child)
    2655         1086 :                     = (chains[0][i].code == code
    2656          543 :                        ? op_stmt_info : other_op_stmt_info);
    2657              :                 }
    2658          701 :               children[i] = child;
    2659              :             }
    2660          314 :           *tree_size += this_tree_size + 1;
    2661          314 :           *max_nunits = this_max_nunits;
    2662         1516 :           while (!chains.is_empty ())
    2663          866 :             chains.pop ().release ();
    2664              :           return node;
    2665              :         }
    2666        21431 : out:
    2667        21453 :       if (dump_enabled_p ())
    2668         2817 :         dump_printf_loc (MSG_NOTE, vect_location,
    2669              :                          "failed to line up SLP graph by re-associating "
    2670              :                          "operations in lanes%s\n",
    2671              :                          !hard_fail ? " trying regular discovery" : "");
    2672        21458 :       while (!children.is_empty ())
    2673            5 :         vect_free_slp_tree (children.pop ());
    2674        21614 :       while (!chains.is_empty ())
    2675          161 :         chains.pop ().release ();
    2676              :       /* Hard-fail, otherwise we might run into quadratic processing of the
    2677              :          chains starting one stmt into the chain again.  */
    2678        21453 :       if (hard_fail)
    2679              :         return NULL;
    2680              :       /* Fall thru to normal processing.  */
    2681        21767 :     }
    2682              : 
    2683              :   /* Get at the operands, verifying they are compatible.  */
    2684      3527367 :   vec<slp_oprnd_info> oprnds_info = vect_create_oprnd_info (nops, group_size);
    2685      3527367 :   slp_oprnd_info oprnd_info;
    2686     16591974 :   FOR_EACH_VEC_ELT (stmts, i, stmt_info)
    2687              :     {
    2688     26131706 :       int res = vect_get_and_check_slp_defs (vinfo, vectype,
    2689     13065853 :                                              swap[i], skip_args,
    2690              :                                              stmts, i, &oprnds_info);
    2691     13065853 :       if (res != 0)
    2692       599832 :         matches[(res == -1) ? 0 : i] = false;
    2693     13065853 :       if (!matches[0])
    2694              :         break;
    2695              :     }
    2696     16252034 :   for (i = 0; i < group_size; ++i)
    2697     12963210 :     if (!matches[i])
    2698              :       {
    2699       238543 :         vect_free_oprnd_info (oprnds_info);
    2700       238543 :         return NULL;
    2701              :       }
    2702      9866472 :   swap = NULL;
    2703              : 
    2704      9866472 :   bool has_two_operators_perm = false;
    2705     19732944 :   auto_vec<unsigned> two_op_perm_indices[2];
    2706      3288824 :   vec<stmt_vec_info> two_op_scalar_stmts[2] = {vNULL, vNULL};
    2707              : 
    2708      3304901 :   if (two_operators && oprnds_info.length () == 2 && group_size > 2)
    2709              :     {
    2710         4012 :       unsigned idx = 0;
    2711         4012 :       hash_map<gimple *, unsigned> seen;
    2712         4012 :       vec<slp_oprnd_info> new_oprnds_info
    2713         4012 :         = vect_create_oprnd_info (1, group_size);
    2714         4012 :       bool success = true;
    2715              : 
    2716         4012 :       enum tree_code code = ERROR_MARK;
    2717         4012 :       if (oprnds_info[0]->def_stmts[0]
    2718         4012 :           && is_a<gassign *> (oprnds_info[0]->def_stmts[0]->stmt))
    2719         3951 :         code = gimple_assign_rhs_code (oprnds_info[0]->def_stmts[0]->stmt);
    2720         4012 :       basic_block bb = nullptr;
    2721              : 
    2722         7708 :       for (unsigned j = 0; j < group_size; ++j)
    2723              :         {
    2724        18015 :           FOR_EACH_VEC_ELT (oprnds_info, i, oprnd_info)
    2725              :             {
    2726        14319 :               stmt_vec_info stmt_info = oprnd_info->def_stmts[j];
    2727        14319 :               if (!stmt_info
    2728        14153 :                   || !is_a<gassign *> (stmt_info->stmt)
    2729        14150 :                   || gimple_assign_rhs_code (stmt_info->stmt) != code
    2730        25109 :                   || skip_args[i])
    2731              :                 {
    2732              :                   success = false;
    2733         3533 :                   break;
    2734              :                 }
    2735              :               /* Avoid mixing lanes with defs in different basic-blocks.  */
    2736        10790 :               if (!bb)
    2737         4147 :                 bb = gimple_bb (vect_orig_stmt (stmt_info)->stmt);
    2738         8577 :               else if (gimple_bb (vect_orig_stmt (stmt_info)->stmt) != bb)
    2739              :                 {
    2740              :                   success = false;
    2741              :                   break;
    2742              :                 }
    2743              : 
    2744        10786 :               bool exists;
    2745        10786 :               unsigned &stmt_idx
    2746        10786 :                 = seen.get_or_insert (stmt_info->stmt, &exists);
    2747              : 
    2748        10786 :               if (!exists)
    2749              :                 {
    2750         9405 :                   new_oprnds_info[0]->def_stmts.safe_push (stmt_info);
    2751         9405 :                   new_oprnds_info[0]->ops.safe_push (oprnd_info->ops[j]);
    2752         9405 :                   stmt_idx = idx;
    2753         9405 :                   idx++;
    2754              :                 }
    2755              : 
    2756        10786 :               two_op_perm_indices[i].safe_push (stmt_idx);
    2757              :             }
    2758              : 
    2759         7229 :           if (!success)
    2760              :             break;
    2761              :         }
    2762              : 
    2763         4012 :       if (success && idx == group_size)
    2764              :         {
    2765           98 :           if (dump_enabled_p ())
    2766              :             {
    2767            0 :               dump_printf_loc (MSG_NOTE, vect_location,
    2768              :                                "Replace two_operators operands:\n");
    2769              : 
    2770            0 :               FOR_EACH_VEC_ELT (oprnds_info, i, oprnd_info)
    2771              :                 {
    2772            0 :                   dump_printf_loc (MSG_NOTE, vect_location,
    2773              :                                    "Operand %u:\n", i);
    2774            0 :                   for (unsigned j = 0; j < group_size; j++)
    2775            0 :                     dump_printf_loc (MSG_NOTE, vect_location, "\tstmt %u %G",
    2776            0 :                                      j, oprnd_info->def_stmts[j]->stmt);
    2777              :                 }
    2778              : 
    2779            0 :               dump_printf_loc (MSG_NOTE, vect_location,
    2780              :                                "With a single operand:\n");
    2781            0 :               for (unsigned j = 0; j < group_size; j++)
    2782            0 :                 dump_printf_loc (MSG_NOTE, vect_location, "\tstmt %u %G",
    2783            0 :                                  j, new_oprnds_info[0]->def_stmts[j]->stmt);
    2784              :             }
    2785              : 
    2786           98 :           two_op_scalar_stmts[0].safe_splice (oprnds_info[0]->def_stmts);
    2787           98 :           two_op_scalar_stmts[1].safe_splice (oprnds_info[1]->def_stmts);
    2788              : 
    2789           98 :           new_oprnds_info[0]->first_op_type = oprnds_info[0]->first_op_type;
    2790           98 :           new_oprnds_info[0]->first_dt = oprnds_info[0]->first_dt;
    2791           98 :           new_oprnds_info[0]->any_pattern = oprnds_info[0]->any_pattern;
    2792           98 :           new_oprnds_info[0]->first_gs_p = oprnds_info[0]->first_gs_p;
    2793           98 :           new_oprnds_info[0]->first_gs_info = oprnds_info[0]->first_gs_info;
    2794              : 
    2795           98 :           vect_free_oprnd_info (oprnds_info);
    2796           98 :           oprnds_info = new_oprnds_info;
    2797           98 :           nops = 1;
    2798           98 :           has_two_operators_perm = true;
    2799              :         }
    2800              :       else
    2801         3914 :         vect_free_oprnd_info (new_oprnds_info);
    2802         4012 :     }
    2803              : 
    2804      6577648 :   auto_vec<slp_tree, 4> children;
    2805              : 
    2806      3288824 :   stmt_info = stmts[0];
    2807              : 
    2808      3288824 :   int reduc_idx = -1;
    2809      3288824 :   int gs_scale = 0;
    2810      3288824 :   tree gs_base = NULL_TREE;
    2811              : 
    2812              :   /* Create SLP_TREE nodes for the definition node/s.  */
    2813      8456258 :   FOR_EACH_VEC_ELT (oprnds_info, i, oprnd_info)
    2814              :     {
    2815      5284977 :       slp_tree child = nullptr;
    2816      5284977 :       unsigned int j;
    2817      5284977 :       unsigned old_swap_distance;
    2818      5284977 :       bool can_swap;
    2819      5284977 :       bool can_swap_nonmatching;
    2820      5284977 :       bool *stmt_can_swap;
    2821              : 
    2822              :       /* We're skipping certain operands from processing, for example
    2823              :          outer loop reduction initial defs.  */
    2824      5284977 :       if (skip_args[i])
    2825              :         {
    2826       511618 :           children.safe_push (NULL);
    2827      5679052 :           continue;
    2828              :         }
    2829              : 
    2830      4773359 :       if (oprnd_info->first_dt == vect_uninitialized_def)
    2831              :         {
    2832              :           /* COND_EXPR have one too many eventually if the condition
    2833              :              is a SSA name.  */
    2834            0 :           gcc_assert (i == 3 && nops == 4);
    2835            0 :           continue;
    2836              :         }
    2837              : 
    2838      4773359 :       if (oprnd_info->first_gs_p)
    2839              :         {
    2840        23729 :           gs_scale = oprnd_info->first_gs_info.scale;
    2841        23729 :           gs_base = oprnd_info->first_gs_info.base;
    2842              :         }
    2843              : 
    2844      4773359 :       if (is_a <bb_vec_info> (vinfo)
    2845      1708288 :           && oprnd_info->first_dt == vect_internal_def
    2846      5688980 :           && !oprnd_info->any_pattern)
    2847              :         {
    2848              :           /* For BB vectorization, if all defs are the same do not
    2849              :              bother to continue the build along the single-lane
    2850              :              graph but use a splat of the scalar value.  */
    2851       862022 :           stmt_vec_info first_def = oprnd_info->def_stmts[0];
    2852       929323 :           for (j = 1; j < group_size; ++j)
    2853       879497 :             if (oprnd_info->def_stmts[j] != first_def)
    2854              :               break;
    2855       862022 :           if (j == group_size
    2856              :               /* But avoid doing this for loads where we may be
    2857              :                  able to CSE things, unless the stmt is not
    2858              :                  vectorizable.  */
    2859       862022 :               && (!STMT_VINFO_VECTORIZABLE (first_def)
    2860        59405 :                   || !gimple_vuse (first_def->stmt)))
    2861              :             {
    2862        40444 :               if (dump_enabled_p ())
    2863          107 :                 dump_printf_loc (MSG_NOTE, vect_location,
    2864              :                                  "Using a splat of the uniform operand %G",
    2865              :                                  first_def->stmt);
    2866        40444 :               oprnd_info->first_dt = vect_external_def;
    2867              :             }
    2868              :         }
    2869              : 
    2870      4773359 :       if (oprnd_info->first_dt == vect_external_def
    2871      4773359 :           || oprnd_info->first_dt == vect_constant_def)
    2872              :         {
    2873      1571011 :           if (!GET_MODE_SIZE (vinfo->vector_mode).is_constant ())
    2874              :             {
    2875              :               tree op0;
    2876              :               tree uniform_val = op0 = oprnd_info->ops[0];
    2877              :               for (j = 1; j < oprnd_info->ops.length (); ++j)
    2878              :                 if (oprnd_info->ops[j]
    2879              :                     && !operand_equal_p (uniform_val, oprnd_info->ops[j]))
    2880              :                   {
    2881              :                     uniform_val = NULL_TREE;
    2882              :                     break;
    2883              :                   }
    2884              :               if (!uniform_val
    2885              :                   && !can_duplicate_and_interleave_p (vinfo,
    2886              :                                                       oprnd_info->ops.length (),
    2887              :                                                       TREE_TYPE (op0)))
    2888              :                 {
    2889              :                   matches[j] = false;
    2890              :                   if (dump_enabled_p ())
    2891              :                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    2892              :                                      "Build SLP failed: invalid type of def "
    2893              :                                      "for variable-length SLP %T\n", op0);
    2894              :                   goto fail;
    2895              :                 }
    2896              :             }
    2897      1571011 :           slp_tree invnode = vect_create_new_slp_node (oprnd_info->ops);
    2898      1571011 :           SLP_TREE_DEF_TYPE (invnode) = oprnd_info->first_dt;
    2899      1571011 :           oprnd_info->ops = vNULL;
    2900      1571011 :           children.safe_push (invnode);
    2901      1571011 :           continue;
    2902      1571011 :         }
    2903              : 
    2904              :       /* See which SLP operand a reduction chain continues on.  We want
    2905              :          to chain even PHIs but not backedges.  */
    2906      3202348 :       if (STMT_VINFO_REDUC_DEF (oprnd_info->def_stmts[0])
    2907      3202348 :           || STMT_VINFO_REDUC_IDX (oprnd_info->def_stmts[0]) != -1)
    2908              :         {
    2909       237631 :           if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle)
    2910              :             {
    2911          776 :               if (oprnd_info->first_dt == vect_double_reduction_def)
    2912          388 :                 reduc_idx = i;
    2913              :             }
    2914       236855 :           else if (is_a <gphi *> (stmt_info->stmt)
    2915       236855 :                    && gimple_phi_num_args
    2916       101710 :                         (as_a <gphi *> (stmt_info->stmt)) != 1)
    2917              :             ;
    2918       135538 :           else if (STMT_VINFO_REDUC_IDX (stmt_info) == -1
    2919          393 :                    && STMT_VINFO_DEF_TYPE (stmt_info) != vect_double_reduction_def)
    2920              :             ;
    2921       135538 :           else if (reduc_idx == -1)
    2922       127047 :             reduc_idx = i;
    2923              :           else
    2924              :             /* For .COND_* reduction operations the else value can be the
    2925              :                same as one of the operation operands.  The other def
    2926              :                stmts have been moved, so we can't check easily.  Check
    2927              :                it's a call at least.  */
    2928         8491 :             gcc_assert (is_a <gcall *> (stmt_info->stmt));
    2929              :         }
    2930              : 
    2931              :       /* When we have a masked load with uniform mask discover this
    2932              :          as a single-lane mask with a splat permute.  This way we can
    2933              :          recognize this as a masked load-lane by stripping the splat.  */
    2934      3202348 :       if (is_a <gcall *> (STMT_VINFO_STMT (stmt_info))
    2935        58336 :           && gimple_call_internal_p (STMT_VINFO_STMT (stmt_info),
    2936              :                                      IFN_MASK_LOAD)
    2937         6193 :           && STMT_VINFO_GROUPED_ACCESS (stmt_info)
    2938      3202425 :           && ! STMT_VINFO_SLP_VECT_ONLY (DR_GROUP_FIRST_ELEMENT (stmt_info)))
    2939              :         {
    2940           35 :           vec<stmt_vec_info> def_stmts2;
    2941           35 :           def_stmts2.create (1);
    2942           35 :           def_stmts2.quick_push (oprnd_info->def_stmts[0]);
    2943           35 :           child = vect_build_slp_tree (vinfo, def_stmts2,
    2944              :                                        &this_max_nunits,
    2945              :                                        matches, limit,
    2946              :                                        &this_tree_size, bst_map);
    2947           35 :           if (child)
    2948              :             {
    2949           35 :               slp_tree pnode = vect_create_new_slp_node (1, VEC_PERM_EXPR);
    2950           35 :               SLP_TREE_VECTYPE (pnode) = SLP_TREE_VECTYPE (child);
    2951           35 :               SLP_TREE_LANES (pnode) = group_size;
    2952           35 :               SLP_TREE_SCALAR_STMTS (pnode).create (group_size);
    2953           35 :               SLP_TREE_LANE_PERMUTATION (pnode).create (group_size);
    2954          210 :               for (unsigned k = 0; k < group_size; ++k)
    2955              :                 {
    2956          175 :                   SLP_TREE_SCALAR_STMTS (pnode)
    2957          175 :                     .quick_push (oprnd_info->def_stmts[0]);
    2958          175 :                   SLP_TREE_LANE_PERMUTATION (pnode)
    2959          175 :                     .quick_push (std::make_pair (0u, 0u));
    2960              :                 }
    2961           35 :               SLP_TREE_CHILDREN (pnode).quick_push (child);
    2962           35 :               pnode->max_nunits = child->max_nunits;
    2963           35 :               children.safe_push (pnode);
    2964           35 :               oprnd_info->def_stmts = vNULL;
    2965           35 :               continue;
    2966           35 :             }
    2967              :           else
    2968            0 :             def_stmts2.release ();
    2969              :         }
    2970              : 
    2971      6404626 :       can_swap = (i == 0
    2972      2365163 :                   && (nops == 2 || nops == 3)
    2973      1533629 :                   && oprnds_info.length () > 1
    2974      1533629 :                   && oprnds_info[1]->first_dt == vect_internal_def
    2975       627362 :                   && (is_gimple_assign (stmt_info->stmt)
    2976        51523 :                       || is_gimple_call (stmt_info->stmt))
    2977              :                   /* Swapping operands for reductions breaks assumptions
    2978              :                      later on.  */
    2979      3783308 :                   && STMT_VINFO_REDUC_IDX (stmt_info) == -1);
    2980      3202313 :       can_swap_nonmatching = can_swap;
    2981      3202313 :       stmt_can_swap = NULL;
    2982      3202313 :       if (can_swap)
    2983              :         {
    2984       525414 :           stmt_can_swap = XALLOCAVEC (bool, group_size);
    2985      8227127 :           for (j = 0; j < group_size; ++j)
    2986              :             {
    2987      7701713 :               stmt_can_swap[j] = false;
    2988      7701713 :               if (!stmts[j])
    2989              :                 /* NULL lanes are gaps and have no stmt to swap.  */
    2990            0 :                 stmt_can_swap[j] = true;
    2991      7701713 :               else if (gassign *stmt = dyn_cast <gassign *> (stmts[j]->stmt))
    2992              :                 {
    2993      7696115 :                   tree_code code = gimple_assign_rhs_code (stmt);
    2994     15392230 :                   stmt_can_swap[j] = (commutative_tree_code (code)
    2995      7696115 :                                       || commutative_ternary_tree_code (code));
    2996              :                 }
    2997         5598 :               else if (gcall *call = dyn_cast <gcall *> (stmts[j]->stmt))
    2998              :                 {
    2999         5598 :                   internal_fn fn = (gimple_call_internal_p (call)
    3000         5598 :                                     ? gimple_call_internal_fn (call) : IFN_LAST);
    3001        11196 :                   stmt_can_swap[j] = ((commutative_binary_fn_p (fn)
    3002         5282 :                                        || commutative_ternary_fn_p (fn))
    3003         5634 :                                       && first_commutative_argument (fn) == 0);
    3004              :                 }
    3005              : 
    3006      7701713 :               if (j != 0 && !stmt_can_swap[j])
    3007      7701713 :                 can_swap_nonmatching = false;
    3008              :             }
    3009              :         }
    3010              : 
    3011      3202313 :       old_swap_distance = least_upthread_swappable_op_distance;
    3012      3202313 :       if (can_swap_nonmatching)
    3013       483274 :         least_upthread_swappable_op_distance = 1;
    3014      2719039 :       else if (least_upthread_swappable_op_distance != -1U)
    3015       352641 :         least_upthread_swappable_op_distance++;
    3016      3202313 :       child = vect_build_slp_tree (vinfo, oprnd_info->def_stmts,
    3017              :                                    &this_max_nunits,
    3018              :                                    matches, limit,
    3019              :                                    &this_tree_size, bst_map);
    3020      3202313 :       least_upthread_swappable_op_distance = old_swap_distance;
    3021      3202313 :       if (child != NULL)
    3022              :         {
    3023      2688327 :           oprnd_info->def_stmts = vNULL;
    3024      2688327 :           children.safe_push (child);
    3025      2688327 :           continue;
    3026              :         }
    3027              : 
    3028              :       /* If the SLP build for operand zero failed and operand zero
    3029              :          and one can be commuted try that for the scalar stmts
    3030              :          that failed the match.  */
    3031       513986 :       if (/* A first scalar stmt mismatch signals a fatal mismatch.  */
    3032       513986 :           matches[0]
    3033       291625 :           && can_swap)
    3034              :         {
    3035              :           /* See whether we can swap the matching or the non-matching
    3036              :              stmt operands.  */
    3037              :           bool swap_not_matching = true;
    3038        76444 :           do
    3039              :             {
    3040      7138286 :               for (j = 0; j < group_size; ++j)
    3041              :                 {
    3042      7078947 :                   if (matches[j] != !swap_not_matching)
    3043        99292 :                     continue;
    3044              :                   /* Verify if we can swap operands of this stmt.  */
    3045      6979655 :                   if (!stmt_can_swap[j])
    3046              :                     {
    3047        17105 :                       if (!swap_not_matching)
    3048         7887 :                         goto fail;
    3049              :                       swap_not_matching = false;
    3050              :                       break;
    3051              :                     }
    3052              :                 }
    3053              :             }
    3054        68557 :           while (j != group_size);
    3055              : 
    3056              :           /* Swap mismatched definition stmts.  */
    3057        59339 :           if (dump_enabled_p ())
    3058          397 :             dump_printf_loc (MSG_NOTE, vect_location,
    3059              :                              "Re-trying with swapped operands of stmts ");
    3060      7110784 :           for (j = 0; j < group_size; ++j)
    3061      7051445 :             if (matches[j] == !swap_not_matching)
    3062              :               {
    3063     13924688 :                 std::swap (oprnds_info[0]->def_stmts[j],
    3064      6962344 :                            oprnds_info[1]->def_stmts[j]);
    3065     13924688 :                 std::swap (oprnds_info[0]->ops[j],
    3066      6962344 :                            oprnds_info[1]->ops[j]);
    3067      6962344 :                 if (dump_enabled_p ())
    3068         1090 :                   dump_printf (MSG_NOTE, "%d ", j);
    3069              :               }
    3070        59339 :           if (dump_enabled_p ())
    3071          397 :             dump_printf (MSG_NOTE, "\n");
    3072              :           /* After swapping some operands we lost track whether an
    3073              :              operand has any pattern defs so be conservative here.  */
    3074       115518 :           if (oprnds_info[0]->any_pattern || oprnds_info[1]->any_pattern)
    3075         4263 :             oprnds_info[0]->any_pattern = oprnds_info[1]->any_pattern = true;
    3076              :           /* And try again with scratch 'matches' ... */
    3077        59339 :           bool *tem = XALLOCAVEC (bool, group_size);
    3078        59339 :           if ((child = vect_build_slp_tree (vinfo, oprnd_info->def_stmts,
    3079              :                                             &this_max_nunits,
    3080              :                                             tem, limit,
    3081              :                                             &this_tree_size, bst_map)) != NULL)
    3082              :             {
    3083         7798 :               oprnd_info->def_stmts = vNULL;
    3084         7798 :               children.safe_push (child);
    3085         7798 :               continue;
    3086              :             }
    3087              :         }
    3088       446760 : fail:
    3089              : 
    3090              :       /* If the SLP build failed and we analyze a basic-block
    3091              :          simply treat nodes we fail to build as externally defined
    3092              :          (and thus build vectors from the scalar defs).
    3093              :          The cost model will reject outright expensive cases.
    3094              :          ???  This doesn't treat cases where permutation ultimatively
    3095              :          fails (or we don't try permutation below).  Ideally we'd
    3096              :          even compute a permutation that will end up with the maximum
    3097              :          SLP tree size...  */
    3098       506188 :       if (is_a <bb_vec_info> (vinfo)
    3099              :           /* ???  Rejecting patterns this way doesn't work.  We'd have to
    3100              :              do extra work to cancel the pattern so the uses see the
    3101              :              scalar version.  */
    3102              :           /* Skip building vector operands from scalars while operand
    3103              :              discovery may still be fixed by retrying with swapped operands.  */
    3104       447407 :           && (least_upthread_swappable_op_distance != 1
    3105              :               /* A first scalar stmt mismatch signals a fatal mismatch
    3106              :                  that the parent commutative retry cannot recover.  */
    3107        31356 :               || !matches[0])
    3108       425018 :           && !is_pattern_stmt_p (stmt_info)
    3109       902660 :           && !oprnd_info->any_pattern)
    3110              :         {
    3111              :           /* But if there's a leading vector sized set of matching stmts
    3112              :              fail here so we can split the group.  This matches the condition
    3113              :              vect_analyze_slp_instance uses.  */
    3114              :           /* ???  We might want to split here and combine the results to support
    3115              :              multiple vector sizes better.  */
    3116       621317 :           for (j = 0; j < group_size; ++j)
    3117       621317 :             if (!matches[j])
    3118              :               break;
    3119       396174 :           if (!known_ge (j, TYPE_VECTOR_SUBPARTS (vectype))
    3120       396143 :               && vect_slp_can_convert_to_external (oprnd_info->def_stmts))
    3121              :             {
    3122       388645 :               if (dump_enabled_p ())
    3123          665 :                 dump_printf_loc (MSG_NOTE, vect_location,
    3124              :                                  "Building vector operands from scalars\n");
    3125       388645 :               this_tree_size++;
    3126       388645 :               child = vect_create_new_slp_node (oprnd_info->ops);
    3127       388645 :               children.safe_push (child);
    3128       388645 :               oprnd_info->ops = vNULL;
    3129       388645 :               continue;
    3130              :             }
    3131              :         }
    3132              : 
    3133       117543 :       gcc_assert (child == NULL);
    3134       138278 :       FOR_EACH_VEC_ELT (children, j, child)
    3135        20735 :         if (child)
    3136        20735 :           vect_free_slp_tree (child);
    3137       117543 :       vect_free_oprnd_info (oprnds_info);
    3138       117543 :       return NULL;
    3139              :     }
    3140              : 
    3141      3171281 :   vect_free_oprnd_info (oprnds_info);
    3142              : 
    3143              :   /* If we have all children of a child built up from uniform scalars
    3144              :      or does more than one possibly expensive vector construction then
    3145              :      just throw that away, causing it built up from scalars.
    3146              :      The exception is the SLP node for the vector store.  */
    3147      3171281 :   if (is_a <bb_vec_info> (vinfo)
    3148      1156606 :       && !STMT_VINFO_GROUPED_ACCESS (stmt_info)
    3149              :       /* ???  Rejecting patterns this way doesn't work.  We'd have to
    3150              :          do extra work to cancel the pattern so the uses see the
    3151              :          scalar version.  */
    3152      3656576 :       && !is_pattern_stmt_p (stmt_info))
    3153              :     {
    3154              :       slp_tree child;
    3155              :       unsigned j;
    3156              :       bool all_uniform_p = true;
    3157              :       unsigned n_vector_builds = 0;
    3158      1353685 :       FOR_EACH_VEC_ELT (children, j, child)
    3159              :         {
    3160       902816 :           if (!child)
    3161              :             ;
    3162       902816 :           else if (SLP_TREE_DEF_TYPE (child) == vect_internal_def)
    3163              :             all_uniform_p = false;
    3164       644688 :           else if (!vect_slp_tree_uniform_p (child))
    3165              :             {
    3166       486496 :               all_uniform_p = false;
    3167       486496 :               if (SLP_TREE_DEF_TYPE (child) == vect_external_def)
    3168       445919 :                 n_vector_builds++;
    3169              :             }
    3170              :         }
    3171       450869 :       if (all_uniform_p
    3172       450869 :           || n_vector_builds > 1
    3173       766873 :           || (n_vector_builds == children.length ()
    3174        35008 :               && is_a <gphi *> (stmt_info->stmt)))
    3175              :         {
    3176              :           /* Roll back.  */
    3177       139836 :           matches[0] = false;
    3178       442655 :           FOR_EACH_VEC_ELT (children, j, child)
    3179       302819 :             if (child)
    3180       302819 :               vect_free_slp_tree (child);
    3181              : 
    3182       139836 :           if (dump_enabled_p ())
    3183          225 :             dump_printf_loc (MSG_NOTE, vect_location,
    3184              :                              "Building parent vector operands from "
    3185              :                              "scalars instead\n");
    3186       139836 :           return NULL;
    3187              :         }
    3188              :     }
    3189              : 
    3190      3031445 :   *tree_size += this_tree_size + 1;
    3191      3031445 :   *max_nunits = this_max_nunits;
    3192              : 
    3193      3031445 :   if (two_operators)
    3194              :     {
    3195              :       /* ???  We'd likely want to either cache in bst_map sth like
    3196              :          { a+b, NULL, a+b, NULL } and { NULL, a-b, NULL, a-b } or
    3197              :          the true { a+b, a+b, a+b, a+b } ... but there we don't have
    3198              :          explicit stmts to put in so the keying on 'stmts' doesn't
    3199              :          work (but we have the same issue with nodes that use 'ops').  */
    3200              : 
    3201         7560 :       if (has_two_operators_perm)
    3202              :         {
    3203           46 :           slp_tree child = children[0];
    3204           46 :           children.truncate (0);
    3205          138 :           for (i = 0; i < 2; i++)
    3206              :             {
    3207           92 :               slp_tree pnode
    3208           92 :                 = vect_create_new_slp_node (two_op_scalar_stmts[i], 2);
    3209           92 :               SLP_TREE_CODE (pnode) = VEC_PERM_EXPR;
    3210           92 :               SLP_TREE_VECTYPE (pnode) = vectype;
    3211           92 :               SLP_TREE_CHILDREN (pnode).quick_push (child);
    3212           92 :               SLP_TREE_CHILDREN (pnode).quick_push (child);
    3213           92 :               lane_permutation_t& perm = SLP_TREE_LANE_PERMUTATION (pnode);
    3214           92 :               children.safe_push (pnode);
    3215              : 
    3216          716 :               for (unsigned j = 0; j < stmts.length (); j++)
    3217          624 :                 perm.safe_push (std::make_pair (0, two_op_perm_indices[i][j]));
    3218              :             }
    3219              : 
    3220           46 :           SLP_TREE_REF_COUNT (child) += 4;
    3221              :         }
    3222              : 
    3223         7560 :       slp_tree one = new _slp_tree;
    3224         7560 :       slp_tree two = new _slp_tree;
    3225         7560 :       SLP_TREE_DEF_TYPE (one) = vect_internal_def;
    3226         7560 :       SLP_TREE_DEF_TYPE (two) = vect_internal_def;
    3227         7560 :       SLP_TREE_VECTYPE (one) = vectype;
    3228         7560 :       SLP_TREE_VECTYPE (two) = vectype;
    3229         7560 :       SLP_TREE_CHILDREN (one).safe_splice (children);
    3230         7560 :       SLP_TREE_CHILDREN (two).safe_splice (children);
    3231         7560 :       slp_tree child;
    3232        30242 :       FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (two), i, child)
    3233        15122 :         SLP_TREE_REF_COUNT (child)++;
    3234              : 
    3235              :       /* Here we record the original defs since this
    3236              :          node represents the final lane configuration.  */
    3237         7560 :       node = vect_create_new_slp_node (node, stmts, 2);
    3238         7560 :       SLP_TREE_VECTYPE (node) = vectype;
    3239         7560 :       SLP_TREE_CODE (node) = VEC_PERM_EXPR;
    3240         7560 :       SLP_TREE_CHILDREN (node).quick_push (one);
    3241         7560 :       SLP_TREE_CHILDREN (node).quick_push (two);
    3242         7560 :       enum tree_code code0 = ERROR_MARK;
    3243         7560 :       enum tree_code ocode = ERROR_MARK;
    3244         7560 :       if (gassign *stmt = dyn_cast <gassign *> (stmts[0]->stmt))
    3245         7558 :         code0 = gimple_assign_rhs_code (stmt);
    3246         7560 :       stmt_vec_info ostmt_info;
    3247         7560 :       unsigned j = 0;
    3248        27065 :       FOR_EACH_VEC_ELT (stmts, i, ostmt_info)
    3249              :         {
    3250        19505 :           int op = 0;
    3251        19505 :           if (gassign *ostmt = dyn_cast <gassign *> (ostmt_info->stmt))
    3252              :             {
    3253        19501 :               if (gimple_assign_rhs_code (ostmt) != code0)
    3254              :                 {
    3255         9771 :                   ocode = gimple_assign_rhs_code (ostmt);
    3256              :                   op = 1;
    3257              :                   j = i;
    3258              :                 }
    3259              :             }
    3260              :           else
    3261              :             {
    3262            8 :               if (gimple_call_combined_fn (stmts[0]->stmt)
    3263            4 :                   != gimple_call_combined_fn (ostmt_info->stmt))
    3264              :                 {
    3265            2 :                   op = 1;
    3266            2 :                   j = i;
    3267              :                 }
    3268              :             }
    3269        19505 :           SLP_TREE_LANE_PERMUTATION (node).safe_push (std::make_pair (op, i));
    3270              :         }
    3271         7560 :       SLP_TREE_CODE (one) = code0;
    3272         7560 :       SLP_TREE_CODE (two) = ocode;
    3273         7560 :       SLP_TREE_LANES (one) = stmts.length ();
    3274         7560 :       SLP_TREE_LANES (two) = stmts.length ();
    3275         7560 :       SLP_TREE_REPRESENTATIVE (one) = stmts[0];
    3276         7560 :       SLP_TREE_REPRESENTATIVE (two) = stmts[j];
    3277              : 
    3278         7560 :       return node;
    3279              :     }
    3280              : 
    3281      3023885 :   node = vect_create_new_slp_node (node, stmts, nops);
    3282      3023885 :   SLP_TREE_VECTYPE (node) = vectype;
    3283      3023885 :   SLP_TREE_CHILDREN (node).splice (children);
    3284      3023885 :   SLP_TREE_GS_SCALE (node) = gs_scale;
    3285      3023885 :   SLP_TREE_GS_BASE (node) = gs_base;
    3286      3023885 :   if (reduc_idx != -1)
    3287              :     {
    3288       118928 :       gcc_assert (STMT_VINFO_REDUC_IDX (stmt_info) != -1
    3289              :                   || STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle
    3290              :                   || STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def);
    3291       118928 :       SLP_TREE_REDUC_IDX (node) = reduc_idx;
    3292       118928 :       node->cycle_info.id = SLP_TREE_CHILDREN (node)[reduc_idx]->cycle_info.id;
    3293              :     }
    3294              :   /* When reaching the reduction PHI, create a vect_reduc_info.  */
    3295      2904957 :   else if ((STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def
    3296      2904957 :             || STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def)
    3297      2904957 :            && is_a <gphi *> (STMT_VINFO_STMT (stmt_info)))
    3298              :     {
    3299       103681 :       loop_vec_info loop_vinfo = as_a <loop_vec_info> (vinfo);
    3300       103681 :       gcc_assert (STMT_VINFO_REDUC_IDX (stmt_info) == -1);
    3301       103681 :       node->cycle_info.id = loop_vinfo->reduc_infos.length ();
    3302       103681 :       vect_reduc_info reduc_info = new vect_reduc_info_s ();
    3303       103681 :       loop_vinfo->reduc_infos.safe_push (reduc_info);
    3304       103681 :       stmt_vec_info reduc_phi = stmt_info;
    3305              :       /* ???  For double reductions vect_is_simple_reduction stores the
    3306              :          reduction type and code on the inner loop header PHI.  */
    3307       103681 :       if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def)
    3308              :         {
    3309          388 :           use_operand_p use_p;
    3310          388 :           gimple *use_stmt;
    3311          388 :           bool res = single_imm_use (gimple_phi_result (stmt_info->stmt),
    3312              :                                      &use_p, &use_stmt);
    3313          388 :           gcc_assert (res);
    3314          388 :           reduc_phi = loop_vinfo->lookup_stmt (use_stmt);
    3315              :         }
    3316       103681 :       VECT_REDUC_INFO_DEF_TYPE (reduc_info) = STMT_VINFO_DEF_TYPE (stmt_info);
    3317       103681 :       VECT_REDUC_INFO_TYPE (reduc_info) = STMT_VINFO_REDUC_TYPE (reduc_phi);
    3318       103681 :       VECT_REDUC_INFO_CODE (reduc_info) = STMT_VINFO_REDUC_CODE (reduc_phi);
    3319       103681 :       VECT_REDUC_INFO_FN (reduc_info) = IFN_LAST;
    3320              :     }
    3321              :   return node;
    3322      9866472 : }
    3323              : 
    3324              : /* Dump a single SLP tree NODE.  */
    3325              : 
    3326              : static void
    3327       457372 : vect_print_slp_tree (dump_flags_t dump_kind, dump_location_t loc,
    3328              :                      slp_tree node)
    3329              : {
    3330       457372 :   unsigned i, j;
    3331       457372 :   slp_tree child;
    3332       457372 :   stmt_vec_info stmt_info;
    3333       457372 :   tree op;
    3334              : 
    3335       457372 :   dump_metadata_t metadata (dump_kind, loc.get_impl_location ());
    3336       457372 :   dump_user_location_t user_loc = loc.get_user_location ();
    3337       457372 :   dump_printf_loc (metadata, user_loc,
    3338              :                    "node%s %p (max_nunits=" HOST_WIDE_INT_PRINT_UNSIGNED
    3339              :                    ", refcnt=%u)",
    3340       457372 :                    SLP_TREE_DEF_TYPE (node) == vect_external_def
    3341              :                    ? " (external)"
    3342              :                    : (SLP_TREE_DEF_TYPE (node) == vect_constant_def
    3343       441185 :                       ? " (constant)"
    3344              :                       : ""), (void *) node,
    3345       457372 :                    estimated_poly_value (node->max_nunits),
    3346              :                                          SLP_TREE_REF_COUNT (node));
    3347       457372 :   if (SLP_TREE_VECTYPE (node))
    3348       387049 :     dump_printf (metadata, " %T", SLP_TREE_VECTYPE (node));
    3349       457372 :   dump_printf (metadata, "%s",
    3350       457372 :                node->avoid_stlf_fail ? " (avoid-stlf-fail)" : "");
    3351       457372 :   if (node->cycle_info.id != -1 || node->cycle_info.reduc_idx != -1)
    3352        24342 :     dump_printf (metadata, " cycle %d, link %d", node->cycle_info.id,
    3353              :                  node->cycle_info.reduc_idx);
    3354       457372 :   dump_printf (metadata, "\n");
    3355       457372 :   if (SLP_TREE_DEF_TYPE (node) == vect_internal_def)
    3356              :     {
    3357       371909 :       if (SLP_TREE_PERMUTE_P (node))
    3358        13902 :         dump_printf_loc (metadata, user_loc, "op: VEC_PERM_EXPR\n");
    3359              :       else
    3360       358007 :         dump_printf_loc (metadata, user_loc, "op template: %G",
    3361       358007 :                          SLP_TREE_REPRESENTATIVE (node)->stmt);
    3362              :     }
    3363       457372 :   if (SLP_TREE_SCALAR_STMTS (node).exists ())
    3364       892146 :     FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
    3365       528456 :       if (stmt_info)
    3366       523058 :         dump_printf_loc (metadata, user_loc, "\t%sstmt %u %G",
    3367       523058 :                          SLP_TREE_LIVE_LANES (node).contains (i)
    3368       519376 :                          ? "[l*]" : (STMT_VINFO_LIVE_P (stmt_info)
    3369       519376 :                                      ? "[l] " : ""),
    3370              :                          i, stmt_info->stmt);
    3371              :       else
    3372         5398 :         dump_printf_loc (metadata, user_loc, "\tstmt %u ---\n", i);
    3373              :   else
    3374              :     {
    3375        93682 :       dump_printf_loc (metadata, user_loc, "\t{ ");
    3376       206648 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
    3377       112966 :         dump_printf (metadata, "%T%s ", op,
    3378       112966 :                      i < SLP_TREE_SCALAR_OPS (node).length () - 1 ? "," : "");
    3379        93682 :       dump_printf (metadata, "}\n");
    3380              :     }
    3381       457372 :   if (SLP_TREE_LOAD_PERMUTATION (node).exists ())
    3382              :     {
    3383        66453 :       dump_printf_loc (metadata, user_loc, "\tload permutation {");
    3384       151983 :       FOR_EACH_VEC_ELT (SLP_TREE_LOAD_PERMUTATION (node), i, j)
    3385        85530 :         dump_printf (dump_kind, " %u", j);
    3386        66453 :       dump_printf (dump_kind, " }\n");
    3387              :     }
    3388       457372 :   if (SLP_TREE_LANE_PERMUTATION (node).exists ())
    3389              :     {
    3390        13910 :       dump_printf_loc (metadata, user_loc, "\tlane permutation {");
    3391        52215 :       for (i = 0; i < SLP_TREE_LANE_PERMUTATION (node).length (); ++i)
    3392        38305 :         dump_printf (dump_kind, " %u[%u]",
    3393        38305 :                      SLP_TREE_LANE_PERMUTATION (node)[i].first,
    3394        38305 :                      SLP_TREE_LANE_PERMUTATION (node)[i].second);
    3395        13910 :       dump_printf (dump_kind, " }%s\n",
    3396        13910 :                    node->ldst_lanes ? " (load-lanes)" : "");
    3397              :     }
    3398       457372 :   if (SLP_TREE_CHILDREN (node).is_empty ())
    3399       174227 :     return;
    3400       283145 :   dump_printf_loc (metadata, user_loc, "\tchildren");
    3401       746776 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    3402       463631 :     dump_printf (dump_kind, " %p", (void *)child);
    3403       283145 :   dump_printf (dump_kind, "%s\n",
    3404       283145 :                node->ldst_lanes && !SLP_TREE_LANE_PERMUTATION (node).exists ()
    3405              :                ? " (store-lanes)" : "");
    3406              : }
    3407              : 
    3408              : DEBUG_FUNCTION void
    3409            0 : debug (slp_tree node)
    3410              : {
    3411            0 :   debug_dump_context ctx;
    3412            0 :   vect_print_slp_tree (MSG_NOTE,
    3413            0 :                        dump_location_t::from_location_t (UNKNOWN_LOCATION),
    3414              :                        node);
    3415            0 : }
    3416              : 
    3417              : /* Recursive helper for the dot producer below.  */
    3418              : 
    3419              : static void
    3420            0 : dot_slp_tree (FILE *f, slp_tree node, hash_set<slp_tree> &visited)
    3421              : {
    3422            0 :   if (visited.add (node))
    3423              :     return;
    3424              : 
    3425            0 :   fprintf (f, "\"%p\" [label=\"", (void *)node);
    3426            0 :   vect_print_slp_tree (MSG_NOTE,
    3427            0 :                        dump_location_t::from_location_t (UNKNOWN_LOCATION),
    3428              :                        node);
    3429            0 :   fprintf (f, "\"];\n");
    3430              : 
    3431              : 
    3432            0 :   for (slp_tree child : SLP_TREE_CHILDREN (node))
    3433            0 :     fprintf (f, "\"%p\" -> \"%p\";", (void *)node, (void *)child);
    3434              : 
    3435            0 :   for (slp_tree child : SLP_TREE_CHILDREN (node))
    3436            0 :     if (child)
    3437            0 :       dot_slp_tree (f, child, visited);
    3438              : }
    3439              : 
    3440              : DEBUG_FUNCTION void
    3441            0 : dot_slp_tree (const char *fname, slp_tree node)
    3442              : {
    3443            0 :   FILE *f = fopen (fname, "w");
    3444            0 :   fprintf (f, "digraph {\n");
    3445            0 :   fflush (f);
    3446            0 :     {
    3447            0 :       debug_dump_context ctx (f);
    3448            0 :       hash_set<slp_tree> visited;
    3449            0 :       dot_slp_tree (f, node, visited);
    3450            0 :     }
    3451            0 :   fflush (f);
    3452            0 :   fprintf (f, "}\n");
    3453            0 :   fclose (f);
    3454            0 : }
    3455              : 
    3456              : DEBUG_FUNCTION void
    3457            0 : dot_slp_tree (const char *fname, const vec<slp_instance> &slp_instances)
    3458              : {
    3459            0 :   FILE *f = fopen (fname, "w");
    3460            0 :   fprintf (f, "digraph {\n");
    3461            0 :   fflush (f);
    3462            0 :     {
    3463            0 :       debug_dump_context ctx (f);
    3464            0 :       hash_set<slp_tree> visited;
    3465            0 :       for (auto inst : slp_instances)
    3466            0 :         dot_slp_tree (f, SLP_INSTANCE_TREE (inst), visited);
    3467            0 :     }
    3468            0 :   fflush (f);
    3469            0 :   fprintf (f, "}\n");
    3470            0 :   fclose (f);
    3471            0 : }
    3472              : 
    3473              : /* Dump a slp tree NODE using flags specified in DUMP_KIND.  */
    3474              : 
    3475              : static void
    3476       496730 : vect_print_slp_graph (dump_flags_t dump_kind, dump_location_t loc,
    3477              :                       slp_tree node, hash_set<slp_tree> &visited)
    3478              : {
    3479       496730 :   unsigned i;
    3480       496730 :   slp_tree child;
    3481              : 
    3482       496730 :   if (visited.add (node))
    3483       496730 :     return;
    3484              : 
    3485       456899 :   vect_print_slp_tree (dump_kind, loc, node);
    3486              : 
    3487      1376916 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    3488       463118 :     if (child)
    3489       419301 :       vect_print_slp_graph (dump_kind, loc, child, visited);
    3490              : }
    3491              : 
    3492              : static void
    3493        47399 : vect_print_slp_graph (dump_flags_t dump_kind, dump_location_t loc,
    3494              :                       slp_tree entry)
    3495              : {
    3496        47399 :   hash_set<slp_tree> visited;
    3497        47399 :   vect_print_slp_graph (dump_kind, loc, entry, visited);
    3498        47399 : }
    3499              : 
    3500              : DEBUG_FUNCTION void
    3501            0 : debug (slp_instance instance)
    3502              : {
    3503            0 :   debug_dump_context ctx;
    3504            0 :   vect_print_slp_graph (MSG_NOTE,
    3505            0 :                         dump_location_t::from_location_t (UNKNOWN_LOCATION),
    3506              :                         SLP_INSTANCE_TREE (instance));
    3507            0 : }
    3508              : 
    3509              : 
    3510              : /* Compute the set of scalar stmts participating in external nodes.  */
    3511              : 
    3512              : static void
    3513      1688819 : vect_slp_gather_extern_scalar_stmts (vec_info *vinfo, slp_tree node,
    3514              :                                      hash_set<slp_tree> &visited,
    3515              :                                      hash_set<stmt_vec_info> &estmts)
    3516              : {
    3517      1688819 :   if (visited.add (node))
    3518              :     return;
    3519              : 
    3520      1629876 :   if (SLP_TREE_DEF_TYPE (node) == vect_internal_def)
    3521              :     {
    3522              :       slp_tree child;
    3523              :       int i;
    3524      1908994 :       FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    3525       975684 :         if (child)
    3526       975684 :           vect_slp_gather_extern_scalar_stmts (vinfo, child, visited, estmts);
    3527              :     }
    3528              :   else
    3529      3897814 :     for (tree def : SLP_TREE_SCALAR_OPS (node))
    3530              :       {
    3531      1810118 :         stmt_vec_info def_stmt = vinfo->lookup_def (def);
    3532      1810118 :         if (def_stmt)
    3533       388280 :           estmts.add (def_stmt);
    3534              :       }
    3535              : }
    3536              : 
    3537              : /* Mark the original scalar stmt coverage of the vector SLP graph of VINFO
    3538              :    with STMT_SLP_TYPE == pure_slp.  */
    3539              : 
    3540              : static void
    3541       245217 : vect_bb_slp_mark_stmts_vectorized (bb_vec_info vinfo)
    3542              : {
    3543              :   /* Gather the scalar stmt leafs of the SLP graph to stop the below DFS
    3544              :      walk on.  */
    3545       245217 :   hash_set<stmt_vec_info> scalar_stmts_in_externs;
    3546       245217 :   hash_set<slp_tree> visited;
    3547      1448786 :   for (auto instance : BB_VINFO_SLP_INSTANCES (vinfo))
    3548       713135 :     vect_slp_gather_extern_scalar_stmts (vinfo, SLP_INSTANCE_TREE (instance),
    3549              :                                          visited, scalar_stmts_in_externs);
    3550              : 
    3551              :   /* DFS walk scalar stmts to compute the vectorized coverage indicated
    3552              :      by STMT_SLP_TYPE (stmt) == pure_slp on the original scalar (non-pattern)
    3553              :      stmts.  */
    3554      1448786 :   for (auto instance : BB_VINFO_SLP_INSTANCES (vinfo))
    3555              :     {
    3556       901805 :       for (auto stmt : SLP_INSTANCE_ROOT_STMTS (instance))
    3557        86680 :         if (!scalar_stmts_in_externs.contains (stmt))
    3558        85284 :           STMT_SLP_TYPE (stmt) = pure_slp;
    3559       713135 :       auto_vec<stmt_vec_info> worklist;
    3560      4017815 :       for (auto stmt : SLP_TREE_SCALAR_STMTS (SLP_INSTANCE_TREE (instance)))
    3561              :         {
    3562      1878410 :           stmt = vect_orig_stmt (stmt);
    3563      1878410 :           if (!scalar_stmts_in_externs.contains (stmt)
    3564      1878410 :               && STMT_SLP_TYPE (stmt) != pure_slp)
    3565              :             {
    3566      1863085 :               STMT_SLP_TYPE (stmt) = pure_slp;
    3567      1863085 :               worklist.safe_push (stmt);
    3568              :             }
    3569              :         }
    3570      3755662 :       while (!worklist.is_empty ())
    3571              :         {
    3572      2333478 :           stmt_vec_info stmt = worklist.pop ();
    3573              : 
    3574              :           /* Now walk relevant parts of the SSA use-def graph.  */
    3575      2333478 :           slp_oprnds child_ops (stmt);
    3576      4950627 :           for (unsigned i = 0; i < child_ops.num_slp_children; ++i)
    3577              :             {
    3578      2617149 :               tree op = child_ops.get_op_for_slp_child (stmt, i);
    3579      2617149 :               stmt_vec_info def = vinfo->lookup_def (op);
    3580      2617149 :               if (def
    3581       943739 :                   && !scalar_stmts_in_externs.contains (def)
    3582      3183383 :                   && STMT_SLP_TYPE (def) != pure_slp)
    3583              :                 {
    3584       470393 :                   STMT_SLP_TYPE (def) = pure_slp;
    3585       470393 :                   worklist.safe_push (def);
    3586              :                 }
    3587              :             }
    3588              :         }
    3589       713135 :     }
    3590       245217 : }
    3591              : 
    3592              : /* Mark the statements of the tree rooted at NODE as relevant (vect_used).  */
    3593              : 
    3594              : static void
    3595      2592623 : vect_mark_slp_stmts_relevant (slp_tree node, hash_set<slp_tree> &visited)
    3596              : {
    3597      2592623 :   if (SLP_TREE_DEF_TYPE (node) != vect_internal_def)
    3598              :     return;
    3599              : 
    3600      1555580 :   if (visited.add (node))
    3601              :     return;
    3602              : 
    3603      7257091 :   for (auto stmt_info : SLP_TREE_SCALAR_STMTS (node))
    3604      3237782 :     if (stmt_info)
    3605              :       {
    3606      3237782 :         gcc_assert (!STMT_VINFO_RELEVANT (stmt_info)
    3607              :                     || STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_scope);
    3608      3237782 :         STMT_VINFO_RELEVANT (stmt_info) = vect_used_in_scope;
    3609              :       }
    3610              : 
    3611      5637180 :   for (auto child: SLP_TREE_CHILDREN (node))
    3612      1775213 :     if (child)
    3613      1775213 :       vect_mark_slp_stmts_relevant (child, visited);
    3614              : }
    3615              : 
    3616              : static void
    3617       817410 : vect_mark_slp_stmts_relevant (slp_tree node)
    3618              : {
    3619       817410 :   hash_set<slp_tree> visited;
    3620       817410 :   vect_mark_slp_stmts_relevant (node, visited);
    3621       817410 : }
    3622              : 
    3623              : 
    3624              : /* Gather loads in the SLP graph NODE and populate the INST loads array.  */
    3625              : 
    3626              : static void
    3627     11121276 : vect_gather_slp_loads (vec<slp_tree> &loads, slp_tree node,
    3628              :                        hash_set<slp_tree> &visited)
    3629              : {
    3630     11121276 :   if (!node || visited.add (node))
    3631      1822818 :     return;
    3632              : 
    3633      9298458 :   if (SLP_TREE_DEF_TYPE (node) != vect_internal_def)
    3634              :     return;
    3635              : 
    3636      6873716 :   if (!SLP_TREE_PERMUTE_P (node))
    3637              :     {
    3638      6661106 :       stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node);
    3639      6661106 :       if (STMT_VINFO_DATA_REF (stmt_info)
    3640      2853477 :           && DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)))
    3641      1625913 :         loads.safe_push (node);
    3642              :     }
    3643              : 
    3644              :   unsigned i;
    3645              :   slp_tree child;
    3646     15677545 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    3647      8803829 :     vect_gather_slp_loads (loads, child, visited);
    3648              : }
    3649              : 
    3650              : 
    3651              : /* Find the last store in SLP INSTANCE.  */
    3652              : 
    3653              : stmt_vec_info
    3654      2821234 : vect_find_last_scalar_stmt_in_slp (slp_tree node)
    3655              : {
    3656      2821234 :   stmt_vec_info last = NULL;
    3657     15884282 :   for (auto stmt_vinfo : SLP_TREE_SCALAR_STMTS (node))
    3658      7431310 :     if (stmt_vinfo)
    3659              :       {
    3660      7431310 :         stmt_vinfo = vect_orig_stmt (stmt_vinfo);
    3661      7431310 :         last = last ? get_later_stmt (stmt_vinfo, last) : stmt_vinfo;
    3662              :       }
    3663              : 
    3664      2821234 :   return last;
    3665              : }
    3666              : 
    3667              : /* Find the first stmt in NODE.  */
    3668              : 
    3669              : stmt_vec_info
    3670       565434 : vect_find_first_scalar_stmt_in_slp (slp_tree node)
    3671              : {
    3672       565434 :   stmt_vec_info first = NULL;
    3673              : 
    3674      3051892 :   for (auto stmt_vinfo : SLP_TREE_SCALAR_STMTS (node))
    3675      1355590 :     if (stmt_vinfo)
    3676              :       {
    3677      1352894 :         stmt_vinfo = vect_orig_stmt (stmt_vinfo);
    3678      1352894 :         if (!first
    3679      1352894 :             || get_later_stmt (stmt_vinfo, first) == first)
    3680              :           first = stmt_vinfo;
    3681              :       }
    3682              : 
    3683       565434 :   return first;
    3684              : }
    3685              : 
    3686              : /* Splits a group of stores, currently beginning at FIRST_VINFO, into
    3687              :    two groups: one (still beginning at FIRST_VINFO) of size GROUP1_SIZE
    3688              :    (also containing the first GROUP1_SIZE stmts, since stores are
    3689              :    consecutive), the second containing the remainder.
    3690              :    Return the first stmt in the second group.  */
    3691              : 
    3692              : static stmt_vec_info
    3693       161882 : vect_split_slp_store_group (stmt_vec_info first_vinfo, unsigned group1_size)
    3694              : {
    3695       161882 :   gcc_assert (DR_GROUP_FIRST_ELEMENT (first_vinfo) == first_vinfo);
    3696       161882 :   gcc_assert (group1_size > 0);
    3697       161882 :   int group2_size = DR_GROUP_SIZE (first_vinfo) - group1_size;
    3698       161882 :   gcc_assert (group2_size > 0);
    3699       161882 :   DR_GROUP_SIZE (first_vinfo) = group1_size;
    3700              : 
    3701       161882 :   stmt_vec_info stmt_info = first_vinfo;
    3702       541340 :   for (unsigned i = group1_size; i > 1; i--)
    3703              :     {
    3704       379458 :       stmt_info = DR_GROUP_NEXT_ELEMENT (stmt_info);
    3705       379458 :       gcc_assert (DR_GROUP_GAP (stmt_info) == 1);
    3706              :     }
    3707              :   /* STMT is now the last element of the first group.  */
    3708       161882 :   stmt_vec_info group2 = DR_GROUP_NEXT_ELEMENT (stmt_info);
    3709       161882 :   DR_GROUP_NEXT_ELEMENT (stmt_info) = 0;
    3710              : 
    3711       161882 :   DR_GROUP_SIZE (group2) = group2_size;
    3712       451173 :   for (stmt_info = group2; stmt_info;
    3713       289291 :        stmt_info = DR_GROUP_NEXT_ELEMENT (stmt_info))
    3714              :     {
    3715       289291 :       DR_GROUP_FIRST_ELEMENT (stmt_info) = group2;
    3716       289291 :       gcc_assert (DR_GROUP_GAP (stmt_info) == 1);
    3717              :     }
    3718              : 
    3719              :   /* For the second group, the DR_GROUP_GAP is that before the original group,
    3720              :      plus skipping over the first vector.  */
    3721       161882 :   DR_GROUP_GAP (group2) = DR_GROUP_GAP (first_vinfo) + group1_size;
    3722              : 
    3723              :   /* DR_GROUP_GAP of the first group now has to skip over the second group too.  */
    3724       161882 :   DR_GROUP_GAP (first_vinfo) += group2_size;
    3725              : 
    3726       161882 :   if (dump_enabled_p ())
    3727           70 :     dump_printf_loc (MSG_NOTE, vect_location, "Split group into %d and %d\n",
    3728              :                      group1_size, group2_size);
    3729              : 
    3730       161882 :   return group2;
    3731              : }
    3732              : 
    3733              : /* Calculate the unrolling factor for an SLP instance with GROUP_SIZE
    3734              :    statements and a vector of NUNITS elements.  */
    3735              : 
    3736              : static poly_uint64
    3737      4367416 : calculate_unrolling_factor (poly_uint64 nunits, unsigned int group_size)
    3738              : {
    3739      4367416 :   return exact_div (common_multiple (nunits, group_size), group_size);
    3740              : }
    3741              : 
    3742              : /* Helper that checks to see if a node is a load node.  */
    3743              : 
    3744              : static inline bool
    3745          103 : vect_is_slp_load_node  (slp_tree root)
    3746              : {
    3747          103 :   return (!SLP_TREE_PERMUTE_P (root)
    3748          103 :           && SLP_TREE_DEF_TYPE (root) == vect_internal_def
    3749           97 :           && STMT_VINFO_GROUPED_ACCESS (SLP_TREE_REPRESENTATIVE (root))
    3750          167 :           && DR_IS_READ (STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (root))));
    3751              : }
    3752              : 
    3753              : 
    3754              : /* Helper function of optimize_load_redistribution that performs the operation
    3755              :    recursively.  */
    3756              : 
    3757              : static slp_tree
    3758        21783 : optimize_load_redistribution_1 (scalar_stmts_to_slp_tree_map_t *bst_map,
    3759              :                                 vec_info *vinfo, unsigned int group_size,
    3760              :                                 hash_map<slp_tree, slp_tree> *load_map,
    3761              :                                 slp_tree root)
    3762              : {
    3763        21783 :   if (slp_tree *leader = load_map->get (root))
    3764         4549 :     return *leader;
    3765              : 
    3766        17234 :   slp_tree node;
    3767        17234 :   unsigned i;
    3768              : 
    3769              :   /* For now, we don't know anything about externals so do not do anything.  */
    3770        17234 :   if (!root || SLP_TREE_DEF_TYPE (root) != vect_internal_def)
    3771              :     return NULL;
    3772        12109 :   else if (SLP_TREE_PERMUTE_P (root))
    3773              :     {
    3774              :       /* First convert this node into a load node and add it to the leaves
    3775              :          list and flatten the permute from a lane to a load one.  If it's
    3776              :          unneeded it will be elided later.  */
    3777           71 :       vec<stmt_vec_info> stmts;
    3778           71 :       stmts.create (SLP_TREE_LANES (root));
    3779           71 :       lane_permutation_t lane_perm = SLP_TREE_LANE_PERMUTATION (root);
    3780          135 :       for (unsigned j = 0; j < lane_perm.length (); j++)
    3781              :         {
    3782          103 :           std::pair<unsigned, unsigned> perm = lane_perm[j];
    3783          103 :           node = SLP_TREE_CHILDREN (root)[perm.first];
    3784              : 
    3785          103 :           if (!vect_is_slp_load_node (node)
    3786          103 :               || SLP_TREE_CHILDREN (node).exists ())
    3787              :             {
    3788           39 :               stmts.release ();
    3789           39 :               goto next;
    3790              :             }
    3791              : 
    3792           64 :           stmts.quick_push (SLP_TREE_SCALAR_STMTS (node)[perm.second]);
    3793              :         }
    3794              : 
    3795           32 :       if (dump_enabled_p ())
    3796            0 :         dump_printf_loc (MSG_NOTE, vect_location,
    3797              :                          "converting stmts on permute node %p\n",
    3798              :                          (void *) root);
    3799              : 
    3800           32 :       bool *matches = XALLOCAVEC (bool, group_size);
    3801           32 :       poly_uint64 max_nunits = 1;
    3802           32 :       unsigned tree_size = 0, limit = 1;
    3803           32 :       node = vect_build_slp_tree (vinfo, stmts, &max_nunits,
    3804              :                                   matches, &limit, &tree_size, bst_map);
    3805           32 :       if (!node)
    3806            0 :         stmts.release ();
    3807              : 
    3808           32 :       load_map->put (root, node);
    3809           32 :       return node;
    3810              :     }
    3811              : 
    3812        12038 : next:
    3813        12077 :   load_map->put (root, NULL);
    3814              : 
    3815        27503 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (root), i , node)
    3816              :     {
    3817        15426 :       slp_tree value
    3818        15426 :         = optimize_load_redistribution_1 (bst_map, vinfo, group_size, load_map,
    3819              :                                           node);
    3820        15426 :       if (value)
    3821              :         {
    3822           32 :           SLP_TREE_REF_COUNT (value)++;
    3823           32 :           SLP_TREE_CHILDREN (root)[i] = value;
    3824              :           /* ???  We know the original leafs of the replaced nodes will
    3825              :              be referenced by bst_map, only the permutes created by
    3826              :              pattern matching are not.  */
    3827           32 :           if (SLP_TREE_REF_COUNT (node) == 1)
    3828           32 :             load_map->remove (node);
    3829           32 :           vect_free_slp_tree (node);
    3830              :         }
    3831              :     }
    3832              : 
    3833              :   return NULL;
    3834              : }
    3835              : 
    3836              : /* Temporary workaround for loads not being CSEd during SLP build.  This
    3837              :    function will traverse the SLP tree rooted in ROOT for INSTANCE and find
    3838              :    VEC_PERM nodes that blend vectors from multiple nodes that all read from the
    3839              :    same DR such that the final operation is equal to a permuted load.  Such
    3840              :    NODES are then directly converted into LOADS themselves.  The nodes are
    3841              :    CSEd using BST_MAP.  */
    3842              : 
    3843              : static void
    3844         4175 : optimize_load_redistribution (scalar_stmts_to_slp_tree_map_t *bst_map,
    3845              :                               vec_info *vinfo, unsigned int group_size,
    3846              :                               hash_map<slp_tree, slp_tree> *load_map,
    3847              :                               slp_tree root)
    3848              : {
    3849         4175 :   slp_tree node;
    3850         4175 :   unsigned i;
    3851              : 
    3852        10532 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (root), i , node)
    3853              :     {
    3854         6357 :       slp_tree value
    3855         6357 :         = optimize_load_redistribution_1 (bst_map, vinfo, group_size, load_map,
    3856              :                                           node);
    3857         6357 :       if (value)
    3858              :         {
    3859            0 :           SLP_TREE_REF_COUNT (value)++;
    3860            0 :           SLP_TREE_CHILDREN (root)[i] = value;
    3861              :           /* ???  We know the original leafs of the replaced nodes will
    3862              :              be referenced by bst_map, only the permutes created by
    3863              :              pattern matching are not.  */
    3864            0 :           if (SLP_TREE_REF_COUNT (node) == 1)
    3865            0 :             load_map->remove (node);
    3866            0 :           vect_free_slp_tree (node);
    3867              :         }
    3868              :     }
    3869         4175 : }
    3870              : 
    3871              : /* Helper function of vect_match_slp_patterns.
    3872              : 
    3873              :    Attempts to match patterns against the slp tree rooted in REF_NODE using
    3874              :    VINFO.  Patterns are matched in post-order traversal.
    3875              : 
    3876              :    If matching is successful the value in REF_NODE is updated and returned, if
    3877              :    not then it is returned unchanged.  */
    3878              : 
    3879              : static bool
    3880      6468018 : vect_match_slp_patterns_2 (slp_tree *ref_node, vec_info *vinfo,
    3881              :                            slp_tree_to_load_perm_map_t *perm_cache,
    3882              :                            slp_compat_nodes_map_t *compat_cache,
    3883              :                            hash_set<slp_tree> *visited)
    3884              : {
    3885      6468018 :   unsigned i;
    3886      6468018 :   slp_tree node = *ref_node;
    3887      6468018 :   bool found_p = false;
    3888      6468018 :   if (!node || visited->add (node))
    3889       922690 :     return false;
    3890              : 
    3891              :   slp_tree child;
    3892     10395317 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    3893      4849989 :     found_p |= vect_match_slp_patterns_2 (&SLP_TREE_CHILDREN (node)[i],
    3894              :                                           vinfo, perm_cache, compat_cache,
    3895              :                                           visited);
    3896              : 
    3897     16635984 :   for (unsigned x = 0; x < num__slp_patterns; x++)
    3898              :     {
    3899     11090656 :       vect_pattern *pattern
    3900     11090656 :         = slp_patterns[x] (perm_cache, compat_cache, ref_node);
    3901     11090656 :       if (pattern)
    3902              :         {
    3903         1108 :           pattern->build (vinfo);
    3904         1108 :           delete pattern;
    3905         1108 :           found_p = true;
    3906              :         }
    3907              :     }
    3908              : 
    3909              :   return found_p;
    3910              : }
    3911              : 
    3912              : /* Applies pattern matching to the given SLP tree rooted in REF_NODE using
    3913              :    vec_info VINFO.
    3914              : 
    3915              :    The modified tree is returned.  Patterns are tried in order and multiple
    3916              :    patterns may match.  */
    3917              : 
    3918              : static bool
    3919      1618029 : vect_match_slp_patterns (slp_instance instance, vec_info *vinfo,
    3920              :                          hash_set<slp_tree> *visited,
    3921              :                          slp_tree_to_load_perm_map_t *perm_cache,
    3922              :                          slp_compat_nodes_map_t *compat_cache)
    3923              : {
    3924      1618029 :   DUMP_VECT_SCOPE ("vect_match_slp_patterns");
    3925      1618029 :   slp_tree *ref_node = &SLP_INSTANCE_TREE (instance);
    3926              : 
    3927      1618029 :   if (dump_enabled_p ())
    3928        31250 :     dump_printf_loc (MSG_NOTE, vect_location,
    3929              :                      "Analyzing SLP tree %p for patterns\n",
    3930        31250 :                      (void *) SLP_INSTANCE_TREE (instance));
    3931              : 
    3932      1618029 :   return vect_match_slp_patterns_2 (ref_node, vinfo, perm_cache, compat_cache,
    3933      1618029 :                                     visited);
    3934              : }
    3935              : 
    3936              : /* STMT_INFO is a store group of size GROUP_SIZE that we are considering
    3937              :    vectorizing with VECTYPE that might be NULL.  MASKED_P indicates whether
    3938              :    the stores are masked.
    3939              :    Return true if we could use IFN_STORE_LANES instead and if that appears
    3940              :    to be the better approach.  */
    3941              : 
    3942              : static bool
    3943         6151 : vect_slp_prefer_store_lanes_p (vec_info *vinfo, stmt_vec_info stmt_info,
    3944              :                                tree vectype, bool masked_p,
    3945              :                                unsigned int group_size,
    3946              :                                unsigned int new_group_size)
    3947              : {
    3948         6151 :   if (!vectype)
    3949              :     {
    3950         6151 :       tree scalar_type = TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (stmt_info)));
    3951         6151 :       vectype = get_vectype_for_scalar_type (vinfo, scalar_type);
    3952              :     }
    3953         6151 :   if (!vectype)
    3954              :     return false;
    3955              :   /* Allow the split if one of the two new groups would operate on full
    3956              :      vectors *within* rather than across one scalar loop iteration.
    3957              :      This is purely a heuristic, but it should work well for group
    3958              :      sizes of 3 and 4, where the possible splits are:
    3959              : 
    3960              :        3->2+1:  OK if the vector has exactly two elements
    3961              :        4->2+2:  Likewise
    3962              :        4->3+1:  Less clear-cut.  */
    3963         6151 :   if (multiple_p (group_size - new_group_size, TYPE_VECTOR_SUBPARTS (vectype))
    3964         3500 :       || multiple_p (new_group_size, TYPE_VECTOR_SUBPARTS (vectype)))
    3965         2674 :     return false;
    3966         3477 :   return vect_store_lanes_supported (vectype, group_size, masked_p) != IFN_LAST;
    3967              : }
    3968              : 
    3969              : /* Analyze an SLP instance starting from a group of grouped stores.  Call
    3970              :    vect_build_slp_tree to build a tree of packed stmts if possible.
    3971              :    Return FALSE if it's impossible to SLP any stmt in the loop.  */
    3972              : 
    3973              : static bool
    3974              : vect_analyze_slp_instance (vec_info *vinfo,
    3975              :                            scalar_stmts_to_slp_tree_map_t *bst_map,
    3976              :                            stmt_vec_info stmt_info, slp_instance_kind kind,
    3977              :                            unsigned max_tree_size, unsigned *limit,
    3978              :                            bool force_single_lane);
    3979              : 
    3980              : /* Build an interleaving scheme for the store sources RHS_NODES from
    3981              :    SCALAR_STMTS.  */
    3982              : 
    3983              : static slp_tree
    3984         8242 : vect_build_slp_store_interleaving (vec<slp_tree> &rhs_nodes,
    3985              :                                    vec<stmt_vec_info> &scalar_stmts,
    3986              :                                    poly_uint64 max_nunits)
    3987              : {
    3988         8242 :   unsigned int group_size = scalar_stmts.length ();
    3989        16484 :   slp_tree node = vect_create_new_slp_node (scalar_stmts,
    3990         8242 :                                             SLP_TREE_CHILDREN
    3991              :                                               (rhs_nodes[0]).length ());
    3992         8242 :   SLP_TREE_VECTYPE (node) = SLP_TREE_VECTYPE (rhs_nodes[0]);
    3993         8242 :   node->max_nunits = max_nunits;
    3994         8242 :   for (unsigned l = 0;
    3995        16511 :        l < SLP_TREE_CHILDREN (rhs_nodes[0]).length (); ++l)
    3996              :     {
    3997              :       /* And a permute merging all RHS SLP trees.  */
    3998         8269 :       slp_tree perm = vect_create_new_slp_node (rhs_nodes.length (),
    3999         8269 :                                                 VEC_PERM_EXPR);
    4000         8269 :       SLP_TREE_CHILDREN (node).quick_push (perm);
    4001         8269 :       SLP_TREE_LANE_PERMUTATION (perm).create (group_size);
    4002         8269 :       SLP_TREE_VECTYPE (perm) = SLP_TREE_VECTYPE (node);
    4003         8269 :       perm->max_nunits = max_nunits;
    4004         8269 :       SLP_TREE_LANES (perm) = group_size;
    4005              :       /* ???  We should set this NULL but that's not expected.  */
    4006         8269 :       SLP_TREE_REPRESENTATIVE (perm)
    4007         8269 :         = SLP_TREE_REPRESENTATIVE (SLP_TREE_CHILDREN (rhs_nodes[0])[l]);
    4008        32149 :       for (unsigned j = 0; j < rhs_nodes.length (); ++j)
    4009              :         {
    4010        23880 :           SLP_TREE_CHILDREN (perm)
    4011        23880 :             .quick_push (SLP_TREE_CHILDREN (rhs_nodes[j])[l]);
    4012        23880 :           SLP_TREE_CHILDREN (rhs_nodes[j])[l]->refcnt++;
    4013        23880 :           for (unsigned k = 0;
    4014        50108 :                k < SLP_TREE_LANES (rhs_nodes[j]); ++k)
    4015              :             {
    4016              :               /* ???  We should populate SLP_TREE_SCALAR_STMTS
    4017              :                  or SLP_TREE_SCALAR_OPS but then we might have
    4018              :                  a mix of both in our children.  */
    4019        26228 :               SLP_TREE_LANE_PERMUTATION (perm)
    4020        26228 :                 .quick_push (std::make_pair (j, k));
    4021              :             }
    4022              :         }
    4023              : 
    4024              :       /* Now we have a single permute node but we cannot code-generate
    4025              :          the case with more than two inputs.
    4026              :          Perform pairwise reduction, reducing the two inputs
    4027              :          with the least number of lanes to one and then repeat until
    4028              :          we end up with two inputs.  That scheme makes sure we end
    4029              :          up with permutes satisfying the restriction of requiring at
    4030              :          most two vector inputs to produce a single vector output
    4031              :          when the number of lanes is even.  */
    4032        15611 :       while (SLP_TREE_CHILDREN (perm).length () > 2)
    4033              :         {
    4034              :           /* When we have three equal sized groups left the pairwise
    4035              :              reduction does not result in a scheme that avoids using
    4036              :              three vectors.  Instead merge the first two groups
    4037              :              to the final size with do-not-care elements (chosen
    4038              :              from the first group) and then merge with the third.
    4039              :                   { A0, B0,  x, A1, B1,  x, ... }
    4040              :                -> { A0, B0, C0, A1, B1, C1, ... }
    4041              :              This handles group size of three (and at least
    4042              :              power-of-two multiples of that).  */
    4043         7342 :           if (SLP_TREE_CHILDREN (perm).length () == 3
    4044         3387 :               && (SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[0])
    4045         3387 :                   == SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[1]))
    4046         7342 :               && (SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[0])
    4047         2515 :                   == SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[2])))
    4048              :             {
    4049         2209 :               int ai = 0;
    4050         2209 :               int bi = 1;
    4051         2209 :               slp_tree a = SLP_TREE_CHILDREN (perm)[ai];
    4052         2209 :               slp_tree b = SLP_TREE_CHILDREN (perm)[bi];
    4053         2209 :               unsigned n = SLP_TREE_LANES (perm);
    4054              : 
    4055         2209 :               slp_tree permab = vect_create_new_slp_node (2, VEC_PERM_EXPR);
    4056         2209 :               SLP_TREE_LANES (permab) = n;
    4057         2209 :               SLP_TREE_LANE_PERMUTATION (permab).create (n);
    4058         2209 :               SLP_TREE_VECTYPE (permab) = SLP_TREE_VECTYPE (perm);
    4059         2209 :               permab->max_nunits = max_nunits;
    4060              :               /* ???  Should be NULL but that's not expected.  */
    4061         2209 :               SLP_TREE_REPRESENTATIVE (permab) = SLP_TREE_REPRESENTATIVE (perm);
    4062         2209 :               SLP_TREE_CHILDREN (permab).quick_push (a);
    4063         4432 :               for (unsigned k = 0; k < SLP_TREE_LANES (a); ++k)
    4064         2223 :                 SLP_TREE_LANE_PERMUTATION (permab)
    4065         2223 :                   .quick_push (std::make_pair (0, k));
    4066         2209 :               SLP_TREE_CHILDREN (permab).quick_push (b);
    4067         4432 :               for (unsigned k = 0; k < SLP_TREE_LANES (b); ++k)
    4068         2223 :                 SLP_TREE_LANE_PERMUTATION (permab)
    4069         2223 :                   .quick_push (std::make_pair (1, k));
    4070              :               /* Push the do-not-care lanes.  */
    4071         4432 :               for (unsigned k = 0; k < SLP_TREE_LANES (a); ++k)
    4072         2223 :                 SLP_TREE_LANE_PERMUTATION (permab)
    4073         2223 :                   .quick_push (std::make_pair (0, k));
    4074              : 
    4075              :               /* Put the merged node into 'perm', in place of a.  */
    4076         2209 :               SLP_TREE_CHILDREN (perm)[ai] = permab;
    4077              :               /* Adjust the references to b in the permutation
    4078              :                  of perm and to the later children which we'll
    4079              :                  remove.  */
    4080         8878 :               for (unsigned k = 0; k < SLP_TREE_LANES (perm); ++k)
    4081              :                 {
    4082         6669 :                   std::pair<unsigned, unsigned> &p
    4083         6669 :                     = SLP_TREE_LANE_PERMUTATION (perm)[k];
    4084         6669 :                   if (p.first == (unsigned) bi)
    4085              :                     {
    4086         2223 :                       p.first = ai;
    4087         2223 :                       p.second += SLP_TREE_LANES (a);
    4088              :                     }
    4089         4446 :                   else if (p.first > (unsigned) bi)
    4090         2223 :                     p.first--;
    4091              :                 }
    4092         2209 :               SLP_TREE_CHILDREN (perm).ordered_remove (bi);
    4093         2209 :               break;
    4094              :             }
    4095              : 
    4096              :           /* Pick the two nodes with the least number of lanes,
    4097              :              prefer the earliest candidate and maintain ai < bi.  */
    4098              :           int ai = -1;
    4099              :           int bi = -1;
    4100        46237 :           for (unsigned ci = 0; ci < SLP_TREE_CHILDREN (perm).length (); ++ci)
    4101              :             {
    4102        41104 :               if (ai == -1)
    4103         5133 :                 ai = ci;
    4104        35971 :               else if (bi == -1)
    4105         5133 :                 bi = ci;
    4106        30838 :               else if ((SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[ci])
    4107        30838 :                         < SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[ai]))
    4108        30838 :                        || (SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[ci])
    4109        25353 :                            < SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[bi])))
    4110              :                 {
    4111        11860 :                   if (SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[ai])
    4112         5930 :                       <= SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[bi]))
    4113         2730 :                     bi = ci;
    4114              :                   else
    4115              :                     {
    4116         3200 :                       ai = bi;
    4117         3200 :                       bi = ci;
    4118              :                     }
    4119              :                 }
    4120              :             }
    4121              : 
    4122              :           /* Produce a merge of nodes ai and bi.  */
    4123         5133 :           slp_tree a = SLP_TREE_CHILDREN (perm)[ai];
    4124         5133 :           slp_tree b = SLP_TREE_CHILDREN (perm)[bi];
    4125         5133 :           unsigned n = SLP_TREE_LANES (a) + SLP_TREE_LANES (b);
    4126         5133 :           slp_tree permab = vect_create_new_slp_node (2, VEC_PERM_EXPR);
    4127         5133 :           SLP_TREE_LANES (permab) = n;
    4128         5133 :           SLP_TREE_LANE_PERMUTATION (permab).create (n);
    4129         5133 :           SLP_TREE_VECTYPE (permab) = SLP_TREE_VECTYPE (perm);
    4130         5133 :           permab->max_nunits = max_nunits;
    4131              :           /* ???  Should be NULL but that's not expected.  */
    4132         5133 :           SLP_TREE_REPRESENTATIVE (permab) = SLP_TREE_REPRESENTATIVE (perm);
    4133         5133 :           SLP_TREE_CHILDREN (permab).quick_push (a);
    4134        13514 :           for (unsigned k = 0; k < SLP_TREE_LANES (a); ++k)
    4135         8381 :             SLP_TREE_LANE_PERMUTATION (permab)
    4136         8381 :               .quick_push (std::make_pair (0, k));
    4137         5133 :           SLP_TREE_CHILDREN (permab).quick_push (b);
    4138        12838 :           for (unsigned k = 0; k < SLP_TREE_LANES (b); ++k)
    4139         7705 :             SLP_TREE_LANE_PERMUTATION (permab)
    4140         7705 :               .quick_push (std::make_pair (1, k));
    4141              : 
    4142              :           /* Put the merged node into 'perm', in place of a.  */
    4143         5133 :           SLP_TREE_CHILDREN (perm)[ai] = permab;
    4144              :           /* Adjust the references to b in the permutation
    4145              :              of perm and to the later children which we'll
    4146              :              remove.  */
    4147        73687 :           for (unsigned k = 0; k < SLP_TREE_LANES (perm); ++k)
    4148              :             {
    4149        68554 :               std::pair<unsigned, unsigned> &p
    4150        68554 :                 = SLP_TREE_LANE_PERMUTATION (perm)[k];
    4151        68554 :               if (p.first == (unsigned) bi)
    4152              :                 {
    4153         7705 :                   p.first = ai;
    4154         7705 :                   p.second += SLP_TREE_LANES (a);
    4155              :                 }
    4156        60849 :               else if (p.first > (unsigned) bi)
    4157        25548 :                 p.first--;
    4158              :             }
    4159         5133 :           SLP_TREE_CHILDREN (perm).ordered_remove (bi);
    4160              :         }
    4161              :     }
    4162              : 
    4163         8242 :   return node;
    4164              : }
    4165              : 
    4166              : /* Analyze an SLP instance starting from SCALAR_STMTS which are a group
    4167              :    of KIND.  Return true if successful.  SCALAR_STMTS is owned by this
    4168              :    function, REMAIN and ROOT_STMT_INFOS ownership is transferred back to
    4169              :    the caller upon failure.  */
    4170              : 
    4171              : static bool
    4172      2133951 : vect_build_slp_instance (vec_info *vinfo,
    4173              :                          slp_instance_kind kind,
    4174              :                          vec<stmt_vec_info> &scalar_stmts,
    4175              :                          vec<stmt_vec_info> &root_stmt_infos,
    4176              :                          vec<tree> &remain,
    4177              :                          unsigned max_tree_size, unsigned *limit,
    4178              :                          scalar_stmts_to_slp_tree_map_t *bst_map,
    4179              :                          bool force_single_lane)
    4180              : {
    4181              :   /* If there's no budget left bail out early.  */
    4182      2133951 :   if (*limit == 0)
    4183              :     {
    4184        25220 :       scalar_stmts.release ();
    4185        25220 :       return false;
    4186              :     }
    4187              : 
    4188      2108731 :   if (kind == slp_inst_kind_ctor)
    4189              :     {
    4190        14312 :       if (dump_enabled_p ())
    4191           86 :         dump_printf_loc (MSG_NOTE, vect_location,
    4192              :                          "Analyzing vectorizable constructor: %G\n",
    4193           43 :                          root_stmt_infos[0]->stmt);
    4194              :     }
    4195      2094419 :   else if (kind == slp_inst_kind_gcond)
    4196              :     {
    4197       290077 :       if (dump_enabled_p ())
    4198         5820 :         dump_printf_loc (MSG_NOTE, vect_location,
    4199              :                          "Analyzing vectorizable control flow: %G",
    4200         2910 :                          root_stmt_infos[0]->stmt);
    4201              :     }
    4202      1804342 :   else if (kind == slp_inst_kind_bb_reduc)
    4203              :     {
    4204      1417123 :       if (dump_enabled_p ())
    4205         6938 :         dump_printf_loc (MSG_NOTE, vect_location,
    4206              :                          "Analyzing vectorizable BB reduction: %G",
    4207         3469 :                          root_stmt_infos[0]->stmt);
    4208              :     }
    4209              : 
    4210      2108731 :   if (dump_enabled_p ())
    4211              :     {
    4212        26186 :       dump_printf_loc (MSG_NOTE, vect_location,
    4213              :                        "Starting SLP discovery for\n");
    4214        56404 :       for (unsigned i = 0; i < scalar_stmts.length (); ++i)
    4215        60436 :         dump_printf_loc (MSG_NOTE, vect_location,
    4216        30218 :                          "  %G", scalar_stmts[i]->stmt);
    4217              :     }
    4218              : 
    4219              :   /* Build the tree for the SLP instance.  */
    4220      2108731 :   unsigned int group_size = scalar_stmts.length ();
    4221      2108731 :   bool *matches = XALLOCAVEC (bool, group_size);
    4222      2108731 :   poly_uint64 max_nunits = 1;
    4223      2108731 :   unsigned tree_size = 0;
    4224              : 
    4225      2108731 :   slp_tree node = NULL;
    4226      2108731 :   if (group_size > 1 && force_single_lane)
    4227              :     {
    4228            0 :       matches[0] = true;
    4229            0 :       matches[1] = false;
    4230              :     }
    4231              :   else
    4232      2108731 :     node = vect_build_slp_tree (vinfo, scalar_stmts,
    4233              :                                 &max_nunits, matches, limit,
    4234              :                                 &tree_size, bst_map);
    4235      2108731 :   if (node != NULL)
    4236              :     {
    4237              :       /* Calculate the unrolling factor based on the smallest type.  */
    4238       817795 :       poly_uint64 unrolling_factor
    4239       817795 :         = calculate_unrolling_factor (max_nunits, group_size);
    4240              : 
    4241       817795 :       if (maybe_ne (unrolling_factor, 1U)
    4242       817795 :           && is_a <bb_vec_info> (vinfo))
    4243              :         {
    4244            0 :           unsigned HOST_WIDE_INT const_max_nunits;
    4245            0 :           if (!max_nunits.is_constant (&const_max_nunits)
    4246            0 :               || const_max_nunits > group_size)
    4247              :             {
    4248            0 :               if (dump_enabled_p ())
    4249            0 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    4250              :                                  "Build SLP failed: store group "
    4251              :                                  "size not a multiple of the vector size "
    4252              :                                  "in basic block SLP\n");
    4253            0 :               vect_free_slp_tree (node);
    4254            0 :               return false;
    4255              :             }
    4256              :           /* Fatal mismatch.  */
    4257            0 :           if (dump_enabled_p ())
    4258            0 :             dump_printf_loc (MSG_NOTE, vect_location,
    4259              :                              "SLP discovery succeeded but node needs "
    4260              :                              "splitting\n");
    4261            0 :           memset (matches, true, group_size);
    4262            0 :           matches[group_size / const_max_nunits * const_max_nunits] = false;
    4263            0 :           vect_free_slp_tree (node);
    4264              :         }
    4265              :       else
    4266              :         {
    4267              :           /* Create a new SLP instance.  */
    4268       817795 :           slp_instance new_instance = XNEW (class _slp_instance);
    4269       817795 :           SLP_INSTANCE_TREE (new_instance) = node;
    4270       817795 :           SLP_INSTANCE_LOADS (new_instance) = vNULL;
    4271       817795 :           SLP_INSTANCE_ROOT_STMTS (new_instance) = root_stmt_infos;
    4272       817795 :           SLP_INSTANCE_REMAIN_DEFS (new_instance) = remain;
    4273       817795 :           SLP_INSTANCE_KIND (new_instance) = kind;
    4274       817795 :           new_instance->reduc_phis = NULL;
    4275       817795 :           new_instance->cost_vec = vNULL;
    4276       817795 :           new_instance->subgraph_entries = vNULL;
    4277              : 
    4278       817795 :           if (dump_enabled_p ())
    4279        23077 :             dump_printf_loc (MSG_NOTE, vect_location,
    4280              :                              "SLP size %u vs. limit %u.\n",
    4281              :                              tree_size, max_tree_size);
    4282              : 
    4283       817795 :           vinfo->slp_instances.safe_push (new_instance);
    4284              : 
    4285              :           /* ???  We've replaced the old SLP_INSTANCE_GROUP_SIZE with
    4286              :              the number of SLP lanes of the root in a few places.
    4287              :              Verify that assumption holds.  */
    4288       817795 :           gcc_assert (SLP_TREE_LANES (SLP_INSTANCE_TREE (new_instance))
    4289              :                        == group_size);
    4290              : 
    4291       817795 :           if (dump_enabled_p ())
    4292              :             {
    4293        23077 :               if (kind == slp_inst_kind_reduc_group)
    4294         1470 :                 dump_printf_loc (MSG_NOTE, vect_location,
    4295              :                                  "SLP discovery of size %d reduction group "
    4296              :                                  "succeeded\n", group_size);
    4297        23077 :               dump_printf_loc (MSG_NOTE, vect_location,
    4298              :                                "Final SLP tree for instance %p:\n",
    4299              :                                (void *) new_instance);
    4300        23077 :               vect_print_slp_graph (MSG_NOTE, vect_location,
    4301              :                                     SLP_INSTANCE_TREE (new_instance));
    4302              :             }
    4303              : 
    4304       817795 :           return true;
    4305              :         }
    4306              :     }
    4307              :   /* Failed to SLP.  */
    4308              : 
    4309              :   /* While we arrive here even with slp_inst_kind_store we should only
    4310              :      for group_size == 1.  The code to split store groups is only in
    4311              :      vect_analyze_slp_instance now.  */
    4312      1290936 :   gcc_assert (kind != slp_inst_kind_store || group_size == 1);
    4313              : 
    4314              :   /* For BB vectorization we get failures only in case of the need of
    4315              :      unrolling, as otherwise we'll simply get operands built from scalars.
    4316              :      Iff there is any mismatches in the toplevel stmts those will prevail,
    4317              :      otherwise we get the non-power-of-two tail of the lanes failed.
    4318              :      For BB reductions we mainly want to catch the first case so we pick
    4319              :      a more useful subset of lanes to reduce.  */
    4320      1290936 :   if (kind == slp_inst_kind_bb_reduc && matches[0])
    4321              :     {
    4322              :       unsigned n_matching = 0;
    4323      2184803 :       for (unsigned i = 0; i < group_size; ++i)
    4324      1545049 :         if (matches[i])
    4325       741841 :           n_matching++;
    4326       639754 :       vec<stmt_vec_info> scalar_stmts2 = vNULL;
    4327              :       /* Try matched parts and put the rest to remain.  */
    4328       639754 :       if (n_matching >= 2 && n_matching >= group_size / 2)
    4329              :         {
    4330              :           /* As we know the matches[] stmts match up, recursing for
    4331              :              non-power-of-two sizes will just force-fail the tail
    4332              :              for us at hopefully optimal vector size and succesfully
    4333              :              finish discovery.  */
    4334        47182 :           scalar_stmts2.create (n_matching);
    4335       244829 :           for (unsigned i = 0; i < group_size; ++i)
    4336       197647 :             if (matches[i])
    4337       141569 :               scalar_stmts2.quick_push (scalar_stmts[i]);
    4338              :             else
    4339        56078 :               remain.safe_push
    4340        59761 :                 (gimple_get_lhs (vect_orig_stmt (scalar_stmts[i])->stmt));
    4341              :         }
    4342              :       /* Try the non-matching part.  */
    4343       592572 :       else if (group_size - n_matching >= 2)
    4344              :         {
    4345              :           /* We do not know whether the !matches[] part matches, so avoid
    4346              :              cutting to a multiple of the vector size too early.  We should
    4347              :              make progress by means of remain only growing and most of the
    4348              :              time prefering the matching[] part.  */
    4349        29535 :           scalar_stmts2.create (scalar_stmts.length () - n_matching);
    4350       250863 :           for (unsigned i = 0; i < group_size; ++i)
    4351       221328 :             if (!matches[i])
    4352       184093 :               scalar_stmts2.quick_push (scalar_stmts[i]);
    4353              :             else
    4354        37235 :               remain.safe_push
    4355        38235 :                 (gimple_get_lhs (vect_orig_stmt (scalar_stmts[i])->stmt));
    4356              :         }
    4357       639754 :       if (scalar_stmts2.exists ())
    4358              :         {
    4359        76717 :           if (dump_enabled_p ())
    4360          202 :             dump_printf_loc (MSG_NOTE, vect_location, "Splitting %d "
    4361              :                              "non-matching lanes to scalar remains\n",
    4362          101 :                              scalar_stmts.length () - scalar_stmts2.length ());
    4363        76717 :           scalar_stmts.release ();
    4364        76717 :           return vect_build_slp_instance (vinfo, kind, scalar_stmts2,
    4365              :                                           root_stmt_infos, remain,
    4366              :                                           max_tree_size, limit, bst_map,
    4367        76717 :                                           force_single_lane);
    4368              :         }
    4369              :     }
    4370              : 
    4371              :   /* Free the allocated memory.  */
    4372      1214219 :   scalar_stmts.release ();
    4373              : 
    4374              :   /* Failed to SLP.  */
    4375      1214219 :   if (dump_enabled_p ())
    4376         3008 :     dump_printf_loc (MSG_NOTE, vect_location, "SLP discovery failed\n");
    4377              :   return false;
    4378              : }
    4379              : 
    4380              : /* Analyze an SLP instance starting from a the start of a reduction chain.
    4381              :    Call vect_build_slp_tree to build a tree of packed stmts if possible.
    4382              :    Return FALSE if SLP build fails.  */
    4383              : 
    4384              : static bool
    4385        73324 : vect_analyze_slp_reduc_chain (loop_vec_info vinfo,
    4386              :                               scalar_stmts_to_slp_tree_map_t *bst_map,
    4387              :                               stmt_vec_info scalar_stmt,
    4388              :                               unsigned max_tree_size, unsigned *limit)
    4389              : {
    4390        73324 :   vec<stmt_vec_info> scalar_stmts = vNULL;
    4391              : 
    4392        73324 :   bool fail = false;
    4393              :   /* ???  We could leave operation code checking to SLP discovery.  */
    4394        73324 :   code_helper code = STMT_VINFO_REDUC_CODE (STMT_VINFO_REDUC_DEF
    4395              :                                               (vect_orig_stmt (scalar_stmt)));
    4396        73324 :   bool first = true;
    4397        73324 :   stmt_vec_info next_stmt = scalar_stmt;
    4398        83314 :   do
    4399              :     {
    4400        83314 :       stmt_vec_info stmt = next_stmt;
    4401        83314 :       gimple_match_op op, orig_op;
    4402        83314 :       if (!gimple_extract_op (STMT_VINFO_STMT (stmt), &op))
    4403            0 :         gcc_unreachable ();
    4404       166628 :       tree reduc_def = gimple_arg (STMT_VINFO_STMT (stmt),
    4405        83314 :                                    STMT_VINFO_REDUC_IDX (stmt));
    4406        83314 :       next_stmt = vect_stmt_to_vectorize (vinfo->lookup_def (reduc_def));
    4407        83314 :       gcc_assert (is_a <gphi *> (STMT_VINFO_STMT (next_stmt))
    4408              :                   || STMT_VINFO_REDUC_IDX (next_stmt) != -1);
    4409        89222 :       if (!gimple_extract_op (STMT_VINFO_STMT (vect_orig_stmt (stmt)),
    4410              :                               &orig_op))
    4411            0 :         gcc_unreachable ();
    4412        83314 :       if (CONVERT_EXPR_CODE_P (op.code)
    4413         4989 :           && tree_nop_conversion_p (op.type, TREE_TYPE (op.ops[0]))
    4414        88291 :           && (first
    4415         2496 :               || is_a <gphi *> (STMT_VINFO_STMT (next_stmt))))
    4416              :         ;
    4417        78397 :       else if (code != orig_op.code)
    4418              :         {
    4419         2726 :           fail = true;
    4420         2726 :           break;
    4421              :         }
    4422              :       else
    4423        75671 :         scalar_stmts.safe_push (stmt);
    4424        80588 :       first = false;
    4425              :     }
    4426        80588 :   while (!is_a <gphi *> (STMT_VINFO_STMT (next_stmt)));
    4427        73324 :   if (fail)
    4428         2726 :     return false;
    4429              : 
    4430              :   /* Remember a stmt with the actual reduction operation.  */
    4431        70598 :   stmt_vec_info reduc_scalar_stmt = scalar_stmts[0];
    4432              : 
    4433              :   /* When the SSA def chain through reduc-idx does not form a natural
    4434              :      reduction chain try to linearize an associative operation manually.  */
    4435        70598 :   if (scalar_stmts.length () == 1
    4436        67975 :       && code.is_tree_code ()
    4437        61904 :       && associative_tree_code ((tree_code)code)
    4438              :       /* We may not associate if a fold-left reduction is required.  */
    4439       131084 :       && !needs_fold_left_reduction_p (TREE_TYPE (gimple_get_lhs
    4440              :                                                     (reduc_scalar_stmt->stmt)),
    4441              :                                        code))
    4442              :     {
    4443        57229 :       auto_vec<chain_op_t> chain;
    4444        57229 :       auto_vec<std::pair<tree_code, gimple *> > worklist;
    4445        57229 :       gimple *op_stmt = NULL, *other_op_stmt = NULL;
    4446        57229 :       if (is_a <gassign *> (scalar_stmts[0]->stmt)
    4447              :           /* We cannot linearize an operation that vect_slp_linearize_chain
    4448              :              would not put on its worklist.  */
    4449        57229 :           && gimple_assign_rhs_code (scalar_stmts[0]->stmt) == (tree_code)code)
    4450              :         {
    4451        56576 :           vect_slp_linearize_chain (vinfo, worklist, chain, (tree_code)code,
    4452        56576 :                                     scalar_stmts[0]->stmt, op_stmt,
    4453              :                                     other_op_stmt,
    4454              :                                     NULL);
    4455              : 
    4456        56576 :           scalar_stmts.truncate (0);
    4457        56576 :           stmt_vec_info tail = NULL;
    4458       283065 :           for (auto el : chain)
    4459              :             {
    4460       113700 :               if (el.dt == vect_external_def
    4461       113700 :                   || el.dt == vect_constant_def
    4462       113700 :                   || el.code != (tree_code) code)
    4463              :                 {
    4464          363 :                   scalar_stmts.release ();
    4465          363 :                   return false;
    4466              :                 }
    4467       113337 :               stmt_vec_info stmt = vinfo->lookup_def (el.op);
    4468       113337 :               if (STMT_VINFO_REDUC_IDX (stmt) != -1
    4469       111053 :                   || STMT_VINFO_REDUC_DEF (stmt))
    4470              :                 {
    4471        56446 :                   gcc_assert (tail == NULL);
    4472        56446 :                   tail = stmt;
    4473        56446 :                   continue;
    4474              :                 }
    4475        56891 :               scalar_stmts.safe_push (stmt);
    4476              :             }
    4477        56213 :           gcc_assert (tail);
    4478              :         }
    4479              : 
    4480              :       /* When this linearization didn't produce a chain see if stripping
    4481              :          a wrapping sign conversion produces one.  */
    4482        56866 :       if (scalar_stmts.length () == 1
    4483        56866 :           && (code == PLUS_EXPR || code == MULT_EXPR || code == BIT_IOR_EXPR
    4484              :               || code == BIT_AND_EXPR || code == BIT_XOR_EXPR))
    4485              :         {
    4486        55079 :           gimple *stmt = scalar_stmts[0]->stmt;
    4487        55079 :           if (!is_gimple_assign (stmt)
    4488        53912 :               || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
    4489         4724 :               || TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME
    4490        59803 :               || !tree_nop_conversion_p (TREE_TYPE (gimple_assign_lhs (stmt)),
    4491         4724 :                                          TREE_TYPE (gimple_assign_rhs1 (stmt))))
    4492              :             {
    4493        53300 :               scalar_stmts.release ();
    4494        53300 :               return false;
    4495              :             }
    4496         1779 :           stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
    4497         1779 :           if (!is_gimple_assign (stmt)
    4498         1779 :               || gimple_assign_rhs_code (stmt) != (tree_code)code)
    4499              :             {
    4500         1760 :               scalar_stmts.release ();
    4501         1760 :               return false;
    4502              :             }
    4503           19 :           chain.truncate (0);
    4504           19 :           vect_slp_linearize_chain (vinfo, worklist, chain, (tree_code)code,
    4505              :                                     stmt, op_stmt, other_op_stmt, NULL);
    4506              : 
    4507           19 :           scalar_stmts.truncate (0);
    4508           19 :           stmt_vec_info tail = NULL;
    4509           93 :           for (auto el : chain)
    4510              :             {
    4511           44 :               if (el.dt == vect_external_def
    4512           44 :                   || el.dt == vect_constant_def
    4513           44 :                   || el.code != (tree_code) code)
    4514              :                 {
    4515            8 :                   scalar_stmts.release ();
    4516            8 :                   return false;
    4517              :                 }
    4518           36 :               stmt_vec_info stmt = vinfo->lookup_def (el.op);
    4519           36 :               if (STMT_VINFO_REDUC_IDX (stmt) != -1
    4520           36 :                   || STMT_VINFO_REDUC_DEF (stmt))
    4521              :                 {
    4522            0 :                   gcc_assert (tail == NULL);
    4523            0 :                   tail = stmt;
    4524            0 :                   continue;
    4525              :                 }
    4526           36 :               scalar_stmts.safe_push (stmt);
    4527              :             }
    4528              :           /* Unlike the above this does not include the reduction SSA
    4529              :              cycle.  */
    4530           11 :           gcc_assert (!tail);
    4531              :         }
    4532              : 
    4533         1798 :       if (scalar_stmts.length () < 2)
    4534              :         {
    4535         1673 :           scalar_stmts.release ();
    4536         1673 :           return false;
    4537              :         }
    4538              : 
    4539          125 :       if (dump_enabled_p ())
    4540              :         {
    4541           34 :           dump_printf_loc (MSG_NOTE, vect_location,
    4542              :                            "Starting SLP discovery of reduction chain for\n");
    4543          140 :           for (unsigned i = 0; i < scalar_stmts.length (); ++i)
    4544          212 :             dump_printf_loc (MSG_NOTE, vect_location,
    4545          106 :                              "  %G", scalar_stmts[i]->stmt);
    4546              :         }
    4547              : 
    4548          125 :       unsigned int group_size = scalar_stmts.length ();
    4549          125 :       bool *matches = XALLOCAVEC (bool, group_size);
    4550          125 :       poly_uint64 max_nunits = 1;
    4551          125 :       unsigned tree_size = 0;
    4552          125 :       slp_tree node = vect_build_slp_tree (vinfo, scalar_stmts,
    4553              :                                            &max_nunits, matches, limit,
    4554          125 :                                            &tree_size, bst_map);
    4555          125 :       if (!node)
    4556              :         {
    4557           47 :           scalar_stmts.release ();
    4558           47 :           return false;
    4559              :         }
    4560              : 
    4561           78 :       unsigned cycle_id = vinfo->reduc_infos.length ();
    4562           78 :       vect_reduc_info reduc_info = new vect_reduc_info_s ();
    4563           78 :       vinfo->reduc_infos.safe_push (reduc_info);
    4564           78 :       VECT_REDUC_INFO_DEF_TYPE (reduc_info) = STMT_VINFO_DEF_TYPE (next_stmt);
    4565           78 :       VECT_REDUC_INFO_TYPE (reduc_info) = STMT_VINFO_REDUC_TYPE (next_stmt);
    4566           78 :       VECT_REDUC_INFO_CODE (reduc_info) = STMT_VINFO_REDUC_CODE (next_stmt);
    4567           78 :       VECT_REDUC_INFO_FN (reduc_info) = IFN_LAST;
    4568           78 :       reduc_info->is_reduc_chain = true;
    4569              : 
    4570              :       /* Build the node for the PHI and possibly the conversions.  */
    4571           78 :       slp_tree phis = vect_create_new_slp_node (2, ERROR_MARK);
    4572           78 :       SLP_TREE_REPRESENTATIVE (phis) = next_stmt;
    4573           78 :       phis->cycle_info.id = cycle_id;
    4574           78 :       SLP_TREE_LANES (phis) = group_size;
    4575           78 :       if (reduc_scalar_stmt == scalar_stmt)
    4576           74 :         SLP_TREE_VECTYPE (phis) = SLP_TREE_VECTYPE (node);
    4577              :       else
    4578            4 :         SLP_TREE_VECTYPE (phis)
    4579            4 :           = signed_or_unsigned_type_for (TYPE_UNSIGNED
    4580              :                                            (TREE_TYPE (gimple_get_lhs
    4581              :                                                          (scalar_stmt->stmt))),
    4582              :                                          SLP_TREE_VECTYPE (node));
    4583              :       /* ???  vect_cse_slp_nodes cannot cope with cycles without any
    4584              :          SLP_TREE_SCALAR_STMTS.  */
    4585           78 :       SLP_TREE_SCALAR_STMTS (phis).create (group_size);
    4586          393 :       for (unsigned i = 0; i < group_size; ++i)
    4587          315 :         SLP_TREE_SCALAR_STMTS (phis).quick_push (next_stmt);
    4588              : 
    4589           78 :       slp_tree op_input = phis;
    4590           78 :       if (reduc_scalar_stmt != scalar_stmt)
    4591              :         {
    4592            4 :           slp_tree conv = vect_create_new_slp_node (1, ERROR_MARK);
    4593            4 :           SLP_TREE_REPRESENTATIVE (conv)
    4594            4 :             = vinfo->lookup_def (gimple_arg (reduc_scalar_stmt->stmt,
    4595            4 :                                              STMT_VINFO_REDUC_IDX
    4596              :                                                (reduc_scalar_stmt)));
    4597            4 :           SLP_TREE_CHILDREN (conv).quick_push (phis);
    4598            4 :           conv->cycle_info.id = cycle_id;
    4599            4 :           SLP_TREE_REDUC_IDX (conv) = 0;
    4600            4 :           SLP_TREE_LANES (conv) = group_size;
    4601            4 :           SLP_TREE_VECTYPE (conv) = SLP_TREE_VECTYPE (node);
    4602            4 :           SLP_TREE_SCALAR_STMTS (conv) = vNULL;
    4603            4 :           op_input = conv;
    4604              :         }
    4605              : 
    4606           78 :       slp_tree reduc = vect_create_new_slp_node (2, ERROR_MARK);
    4607           78 :       SLP_TREE_REPRESENTATIVE (reduc) = reduc_scalar_stmt;
    4608           78 :       SLP_TREE_CHILDREN (reduc).quick_push (op_input);
    4609           78 :       SLP_TREE_CHILDREN (reduc).quick_push (node);
    4610           78 :       reduc->cycle_info.id = cycle_id;
    4611           78 :       SLP_TREE_REDUC_IDX (reduc) = 0;
    4612           78 :       SLP_TREE_LANES (reduc) = group_size;
    4613           78 :       SLP_TREE_VECTYPE (reduc) = SLP_TREE_VECTYPE (node);
    4614              :       /* ???  For the reduction epilogue we need a live lane.  */
    4615           78 :       SLP_TREE_SCALAR_STMTS (reduc).create (group_size);
    4616           78 :       SLP_TREE_SCALAR_STMTS (reduc).quick_push (reduc_scalar_stmt);
    4617          315 :       for (unsigned i = 1; i < group_size; ++i)
    4618          237 :         SLP_TREE_SCALAR_STMTS (reduc).quick_push (NULL);
    4619              : 
    4620           78 :       if (reduc_scalar_stmt != scalar_stmt)
    4621              :         {
    4622            4 :           slp_tree conv = vect_create_new_slp_node (1, ERROR_MARK);
    4623            4 :           SLP_TREE_REPRESENTATIVE (conv) = scalar_stmt;
    4624            4 :           SLP_TREE_CHILDREN (conv).quick_push (reduc);
    4625            4 :           conv->cycle_info.id = cycle_id;
    4626            4 :           SLP_TREE_REDUC_IDX (conv) = 0;
    4627            4 :           SLP_TREE_LANES (conv) = group_size;
    4628            4 :           SLP_TREE_VECTYPE (conv) = SLP_TREE_VECTYPE (phis);
    4629              :           /* ???  For the reduction epilogue we need a live lane.  */
    4630            4 :           SLP_TREE_SCALAR_STMTS (conv).create (group_size);
    4631            4 :           SLP_TREE_SCALAR_STMTS (conv).quick_push (scalar_stmt);
    4632            8 :           for (unsigned i = 1; i < group_size; ++i)
    4633            4 :             SLP_TREE_SCALAR_STMTS (conv).quick_push (NULL);
    4634            4 :           reduc = conv;
    4635              :         }
    4636              : 
    4637           78 :       edge le = loop_latch_edge (LOOP_VINFO_LOOP (vinfo));
    4638           78 :       SLP_TREE_CHILDREN (phis).quick_push (NULL);
    4639           78 :       SLP_TREE_CHILDREN (phis).quick_push (NULL);
    4640           78 :       SLP_TREE_CHILDREN (phis)[le->dest_idx] = reduc;
    4641           78 :       SLP_TREE_REF_COUNT (reduc)++;
    4642              : 
    4643              :       /* Create a new SLP instance.  */
    4644           78 :       slp_instance new_instance = XNEW (class _slp_instance);
    4645           78 :       SLP_INSTANCE_TREE (new_instance) = reduc;
    4646           78 :       SLP_INSTANCE_LOADS (new_instance) = vNULL;
    4647           78 :       SLP_INSTANCE_ROOT_STMTS (new_instance) = vNULL;
    4648           78 :       SLP_INSTANCE_REMAIN_DEFS (new_instance) = vNULL;
    4649           78 :       SLP_INSTANCE_KIND (new_instance) = slp_inst_kind_reduc_chain;
    4650           78 :       new_instance->reduc_phis = NULL;
    4651           78 :       new_instance->cost_vec = vNULL;
    4652           78 :       new_instance->subgraph_entries = vNULL;
    4653              : 
    4654           78 :       vinfo->slp_instances.safe_push (new_instance);
    4655              : 
    4656           78 :       if (dump_enabled_p ())
    4657              :         {
    4658           24 :           dump_printf_loc (MSG_NOTE, vect_location,
    4659              :                            "Final SLP tree for instance %p:\n",
    4660              :                            (void *) new_instance);
    4661           24 :           vect_print_slp_graph (MSG_NOTE, vect_location,
    4662              :                                 SLP_INSTANCE_TREE (new_instance));
    4663              :         }
    4664              : 
    4665           78 :       return true;
    4666        57229 :     }
    4667              : 
    4668        13369 :   if (scalar_stmts.length () <= 1)
    4669              :     {
    4670        10746 :       scalar_stmts.release ();
    4671        10746 :       return false;
    4672              :     }
    4673              : 
    4674         2623 :   scalar_stmts.reverse ();
    4675         2623 :   stmt_vec_info reduc_phi_info = next_stmt;
    4676              : 
    4677              :   /* Build the tree for the SLP instance.  */
    4678         2623 :   vec<stmt_vec_info> root_stmt_infos = vNULL;
    4679         2623 :   vec<tree> remain = vNULL;
    4680              : 
    4681         2623 :   if (dump_enabled_p ())
    4682              :     {
    4683          196 :       dump_printf_loc (MSG_NOTE, vect_location,
    4684              :                        "Starting SLP discovery of reduction chain for\n");
    4685         1038 :       for (unsigned i = 0; i < scalar_stmts.length (); ++i)
    4686         1684 :         dump_printf_loc (MSG_NOTE, vect_location,
    4687          842 :                          "  %G", scalar_stmts[i]->stmt);
    4688              :     }
    4689              : 
    4690              :   /* Build the tree for the SLP instance.  */
    4691         2623 :   unsigned int group_size = scalar_stmts.length ();
    4692         2623 :   bool *matches = XALLOCAVEC (bool, group_size);
    4693         2623 :   poly_uint64 max_nunits = 1;
    4694         2623 :   unsigned tree_size = 0;
    4695              : 
    4696              :   /* ???  We need this only for SLP discovery.  */
    4697        10237 :   for (unsigned i = 0; i < scalar_stmts.length (); ++i)
    4698         7614 :     REDUC_GROUP_FIRST_ELEMENT (scalar_stmts[i]) = scalar_stmts[0];
    4699              : 
    4700         2623 :   slp_tree node = vect_build_slp_tree (vinfo, scalar_stmts,
    4701              :                                        &max_nunits, matches, limit,
    4702         2623 :                                        &tree_size, bst_map);
    4703              : 
    4704        10237 :   for (unsigned i = 0; i < scalar_stmts.length (); ++i)
    4705         7614 :     REDUC_GROUP_FIRST_ELEMENT (scalar_stmts[i]) = NULL;
    4706              : 
    4707         2623 :   if (node != NULL)
    4708              :     {
    4709              :       /* Create a new SLP instance.  */
    4710         2339 :       slp_instance new_instance = XNEW (class _slp_instance);
    4711         2339 :       SLP_INSTANCE_TREE (new_instance) = node;
    4712         2339 :       SLP_INSTANCE_LOADS (new_instance) = vNULL;
    4713         2339 :       SLP_INSTANCE_ROOT_STMTS (new_instance) = root_stmt_infos;
    4714         2339 :       SLP_INSTANCE_REMAIN_DEFS (new_instance) = remain;
    4715         2339 :       SLP_INSTANCE_KIND (new_instance) = slp_inst_kind_reduc_chain;
    4716         2339 :       new_instance->reduc_phis = NULL;
    4717         2339 :       new_instance->cost_vec = vNULL;
    4718         2339 :       new_instance->subgraph_entries = vNULL;
    4719              : 
    4720         2339 :       vect_reduc_info reduc_info = info_for_reduction (vinfo, node);
    4721         2339 :       reduc_info->is_reduc_chain = true;
    4722              : 
    4723         2339 :       if (dump_enabled_p ())
    4724          147 :         dump_printf_loc (MSG_NOTE, vect_location,
    4725              :                          "SLP size %u vs. limit %u.\n",
    4726              :                          tree_size, max_tree_size);
    4727              : 
    4728              :       /* Fixup SLP reduction chains.  If this is a reduction chain with
    4729              :          a conversion in front amend the SLP tree with a node for that.  */
    4730         2339 :       gimple *scalar_def = STMT_VINFO_REDUC_DEF (reduc_phi_info)->stmt;
    4731         2339 :       if (is_gimple_assign (scalar_def)
    4732         2339 :           && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (scalar_def)))
    4733              :         {
    4734           43 :           stmt_vec_info conv_info = vect_stmt_to_vectorize
    4735           43 :                                         (STMT_VINFO_REDUC_DEF (reduc_phi_info));
    4736           43 :           scalar_stmts = vNULL;
    4737           43 :           scalar_stmts.create (group_size);
    4738          135 :           for (unsigned i = 0; i < group_size; ++i)
    4739           92 :             scalar_stmts.quick_push (conv_info);
    4740           43 :           slp_tree conv = vect_create_new_slp_node (scalar_stmts, 1);
    4741           43 :           SLP_TREE_VECTYPE (conv)
    4742           43 :             = get_vectype_for_scalar_type (vinfo,
    4743           43 :                                            TREE_TYPE
    4744              :                                              (gimple_assign_lhs (scalar_def)),
    4745              :                                            group_size);
    4746           43 :           SLP_TREE_REDUC_IDX (conv) = 0;
    4747           43 :           conv->cycle_info.id = node->cycle_info.id;
    4748           43 :           SLP_TREE_CHILDREN (conv).quick_push (node);
    4749           43 :           SLP_INSTANCE_TREE (new_instance) = conv;
    4750              :         }
    4751              :       /* Fill the backedge child of the PHI SLP node.  The
    4752              :          general matching code cannot find it because the
    4753              :          scalar code does not reflect how we vectorize the
    4754              :          reduction.  */
    4755         2339 :       use_operand_p use_p;
    4756         2339 :       imm_use_iterator imm_iter;
    4757         2339 :       class loop *loop = LOOP_VINFO_LOOP (vinfo);
    4758        11235 :       FOR_EACH_IMM_USE_FAST (use_p, imm_iter,
    4759              :                              gimple_get_lhs (scalar_def))
    4760              :         /* There are exactly two non-debug uses, the reduction
    4761              :            PHI and the loop-closed PHI node.  */
    4762         6557 :         if (!is_gimple_debug (USE_STMT (use_p))
    4763         6557 :             && gimple_bb (USE_STMT (use_p)) == loop->header)
    4764              :           {
    4765         2339 :             auto_vec<stmt_vec_info, 64> phis (group_size);
    4766         2339 :             stmt_vec_info phi_info = vinfo->lookup_stmt (USE_STMT (use_p));
    4767         9223 :             for (unsigned i = 0; i < group_size; ++i)
    4768         6884 :               phis.quick_push (phi_info);
    4769         2339 :             slp_tree *phi_node = bst_map->get (phis);
    4770         2339 :             unsigned dest_idx = loop_latch_edge (loop)->dest_idx;
    4771         4678 :             SLP_TREE_CHILDREN (*phi_node)[dest_idx]
    4772         2339 :               = SLP_INSTANCE_TREE (new_instance);
    4773         2339 :             SLP_INSTANCE_TREE (new_instance)->refcnt++;
    4774         2339 :           }
    4775              : 
    4776         2339 :       vinfo->slp_instances.safe_push (new_instance);
    4777              : 
    4778              :       /* ???  We've replaced the old SLP_INSTANCE_GROUP_SIZE with
    4779              :          the number of SLP lanes of the root in a few places.
    4780              :          Verify that assumption holds.  */
    4781         2339 :       gcc_assert (SLP_TREE_LANES (SLP_INSTANCE_TREE (new_instance))
    4782              :                   == group_size);
    4783              : 
    4784         2339 :       if (dump_enabled_p ())
    4785              :         {
    4786          147 :           dump_printf_loc (MSG_NOTE, vect_location,
    4787              :                            "Final SLP tree for instance %p:\n",
    4788              :                            (void *) new_instance);
    4789          147 :           vect_print_slp_graph (MSG_NOTE, vect_location,
    4790              :                                 SLP_INSTANCE_TREE (new_instance));
    4791              :         }
    4792              : 
    4793         2339 :       return true;
    4794              :     }
    4795              : 
    4796              :   /* Failed to SLP.  */
    4797          284 :   scalar_stmts.release ();
    4798          284 :   if (dump_enabled_p ())
    4799           49 :     dump_printf_loc (MSG_NOTE, vect_location,
    4800              :                      "SLP discovery of reduction chain failed\n");
    4801              :   return false;
    4802              : }
    4803              : 
    4804              : /* Analyze an SLP instance starting from SCALAR_STMTS which are a group
    4805              :    of KIND.  Return true if successful.  */
    4806              : 
    4807              : static bool
    4808       100169 : vect_analyze_slp_reduction (loop_vec_info vinfo,
    4809              :                             stmt_vec_info scalar_stmt,
    4810              :                             unsigned max_tree_size, unsigned *limit,
    4811              :                             scalar_stmts_to_slp_tree_map_t *bst_map,
    4812              :                             bool force_single_lane)
    4813              : {
    4814       100169 :   slp_instance_kind kind = slp_inst_kind_reduc_group;
    4815              : 
    4816              :   /* Try to gather a reduction chain.  Only attempt if there's budget left
    4817              :      since chain analysis may build multi-lane trees that consume limit.  */
    4818       100169 :   if (! force_single_lane
    4819        73609 :       && *limit != 0
    4820        73609 :       && STMT_VINFO_DEF_TYPE (scalar_stmt) == vect_reduction_def
    4821       173493 :       && vect_analyze_slp_reduc_chain (vinfo, bst_map, scalar_stmt,
    4822              :                                        max_tree_size, limit))
    4823              :     return true;
    4824              : 
    4825        97752 :   vec<stmt_vec_info> scalar_stmts;
    4826        97752 :   scalar_stmts.create (1);
    4827        97752 :   scalar_stmts.quick_push (scalar_stmt);
    4828              : 
    4829        97752 :   if (dump_enabled_p ())
    4830              :     {
    4831         3908 :       dump_printf_loc (MSG_NOTE, vect_location,
    4832              :                        "Starting SLP discovery for\n");
    4833         7816 :       for (unsigned i = 0; i < scalar_stmts.length (); ++i)
    4834         7816 :         dump_printf_loc (MSG_NOTE, vect_location,
    4835         3908 :                          "  %G", scalar_stmts[i]->stmt);
    4836              :     }
    4837              : 
    4838              :   /* Build the tree for the SLP instance.  */
    4839        97752 :   unsigned int group_size = scalar_stmts.length ();
    4840        97752 :   bool *matches = XALLOCAVEC (bool, group_size);
    4841        97752 :   poly_uint64 max_nunits = 1;
    4842        97752 :   unsigned tree_size = 0;
    4843              : 
    4844        97752 :   slp_tree node = vect_build_slp_tree (vinfo, scalar_stmts,
    4845              :                                        &max_nunits, matches, limit,
    4846              :                                        &tree_size, bst_map);
    4847        97752 :   if (node != NULL)
    4848              :     {
    4849              :       /* Create a new SLP instance.  */
    4850        95852 :       slp_instance new_instance = XNEW (class _slp_instance);
    4851        95852 :       SLP_INSTANCE_TREE (new_instance) = node;
    4852        95852 :       SLP_INSTANCE_LOADS (new_instance) = vNULL;
    4853        95852 :       SLP_INSTANCE_ROOT_STMTS (new_instance) = vNULL;
    4854        95852 :       SLP_INSTANCE_REMAIN_DEFS (new_instance) = vNULL;
    4855        95852 :       SLP_INSTANCE_KIND (new_instance) = kind;
    4856        95852 :       new_instance->reduc_phis = NULL;
    4857        95852 :       new_instance->cost_vec = vNULL;
    4858        95852 :       new_instance->subgraph_entries = vNULL;
    4859              : 
    4860        95852 :       if (dump_enabled_p ())
    4861         3827 :         dump_printf_loc (MSG_NOTE, vect_location,
    4862              :                          "SLP size %u vs. limit %u.\n",
    4863              :                          tree_size, max_tree_size);
    4864              : 
    4865        95852 :       vinfo->slp_instances.safe_push (new_instance);
    4866              : 
    4867              :       /* ???  We've replaced the old SLP_INSTANCE_GROUP_SIZE with
    4868              :          the number of SLP lanes of the root in a few places.
    4869              :          Verify that assumption holds.  */
    4870        95852 :       gcc_assert (SLP_TREE_LANES (SLP_INSTANCE_TREE (new_instance))
    4871              :                   == group_size);
    4872              : 
    4873        95852 :       if (dump_enabled_p ())
    4874              :         {
    4875         3827 :           dump_printf_loc (MSG_NOTE, vect_location,
    4876              :                            "Final SLP tree for instance %p:\n",
    4877              :                            (void *) new_instance);
    4878         3827 :           vect_print_slp_graph (MSG_NOTE, vect_location,
    4879              :                                 SLP_INSTANCE_TREE (new_instance));
    4880              :         }
    4881              : 
    4882        95852 :       return true;
    4883              :     }
    4884              :   /* Failed to SLP.  */
    4885              : 
    4886              :   /* Free the allocated memory.  */
    4887         1900 :   scalar_stmts.release ();
    4888              : 
    4889              :   /* Failed to SLP.  */
    4890         1900 :   if (dump_enabled_p ())
    4891           81 :     dump_printf_loc (MSG_NOTE, vect_location, "SLP discovery failed\n");
    4892              :   return false;
    4893              : }
    4894              : 
    4895              : /* Analyze a single SLP reduction group.  If successful add a SLP instance
    4896              :    for it and return true, otherwise return false and have *MATCHES
    4897              :    populated.  */
    4898              : 
    4899              : static bool
    4900        24150 : vect_analyze_slp_reduction_group (loop_vec_info loop_vinfo,
    4901              :                                   vec<stmt_vec_info> scalar_stmts,
    4902              :                                   scalar_stmts_to_slp_tree_map_t *bst_map,
    4903              :                                   unsigned max_tree_size, unsigned *limit,
    4904              :                                   bool *matches)
    4905              : {
    4906              :   /* Try to form a reduction group.  Size-1 groups are not suitable
    4907              :      for SLP reduction and should fall back to single-lane reduction.  */
    4908        45536 :   unsigned int group_size = scalar_stmts.length ();
    4909        24150 :   if (group_size <= 1)
    4910              :     return false;
    4911        17471 :   if (!matches)
    4912         4550 :     matches = XALLOCAVEC (bool, group_size);
    4913        17471 :   poly_uint64 max_nunits = 1;
    4914        17471 :   unsigned tree_size = 0;
    4915        17471 :   slp_tree node = vect_build_slp_tree (loop_vinfo, scalar_stmts,
    4916              :                                        &max_nunits, matches, limit,
    4917              :                                        &tree_size, bst_map);
    4918        17471 :   if (!node)
    4919              :     return false;
    4920              : 
    4921              :   /* Create a new SLP instance.  */
    4922         2764 :   slp_instance new_instance = XNEW (class _slp_instance);
    4923         2764 :   SLP_INSTANCE_TREE (new_instance) = node;
    4924         2764 :   SLP_INSTANCE_LOADS (new_instance) = vNULL;
    4925         2764 :   SLP_INSTANCE_ROOT_STMTS (new_instance) = vNULL;
    4926         2764 :   SLP_INSTANCE_REMAIN_DEFS (new_instance) = vNULL;
    4927         2764 :   SLP_INSTANCE_KIND (new_instance) = slp_inst_kind_reduc_group;
    4928         2764 :   new_instance->reduc_phis = NULL;
    4929         2764 :   new_instance->cost_vec = vNULL;
    4930         2764 :   new_instance->subgraph_entries = vNULL;
    4931              : 
    4932         2764 :   if (dump_enabled_p ())
    4933          211 :     dump_printf_loc (MSG_NOTE, vect_location,
    4934              :                      "SLP size %u vs. limit %u.\n",
    4935              :                      tree_size, max_tree_size);
    4936              : 
    4937         2764 :   loop_vinfo->slp_instances.safe_push (new_instance);
    4938              : 
    4939              :   /* ???  We've replaced the old SLP_INSTANCE_GROUP_SIZE with
    4940              :      the number of SLP lanes of the root in a few places.
    4941              :      Verify that assumption holds.  */
    4942         2764 :   gcc_assert (SLP_TREE_LANES (SLP_INSTANCE_TREE (new_instance))
    4943              :               == group_size);
    4944              : 
    4945         2764 :   if (dump_enabled_p ())
    4946              :     {
    4947          211 :       dump_printf_loc (MSG_NOTE, vect_location,
    4948              :                        "SLP discovery of size %d reduction group "
    4949              :                        "succeeded\n", group_size);
    4950          211 :       dump_printf_loc (MSG_NOTE, vect_location,
    4951              :                        "Final SLP tree for instance %p:\n",
    4952              :                        (void *) new_instance);
    4953          211 :       vect_print_slp_graph (MSG_NOTE, vect_location,
    4954              :                             SLP_INSTANCE_TREE (new_instance));
    4955              :     }
    4956              : 
    4957              :   return true;
    4958              : }
    4959              : 
    4960              : /* Analyze reductions in LOOP_VINFO and populate SLP instances
    4961              :    accordingly.  Returns false if something fails.  */
    4962              : 
    4963              : static bool
    4964       511292 : vect_analyze_slp_reductions (loop_vec_info loop_vinfo,
    4965              :                              unsigned max_tree_size, unsigned *limit,
    4966              :                              scalar_stmts_to_slp_tree_map_t *bst_map,
    4967              :                              bool force_single_lane)
    4968              : {
    4969       582224 :   if (loop_vinfo->reductions.is_empty ())
    4970              :     return true;
    4971              : 
    4972              :   /* Collect reduction statements we can combine into
    4973              :      a SLP reduction.  */
    4974        74389 :   vec<stmt_vec_info> scalar_stmts;
    4975        74389 :   scalar_stmts.create (loop_vinfo->reductions.length ());
    4976       329726 :   for (auto next_info : loop_vinfo->reductions)
    4977              :     {
    4978       106559 :       next_info = vect_stmt_to_vectorize (next_info);
    4979       106559 :       if ((STMT_VINFO_RELEVANT_P (next_info)
    4980           14 :            || STMT_VINFO_LIVE_P (next_info))
    4981              :           /* ???  Make sure we didn't skip a conversion around a
    4982              :              reduction path.  In that case we'd have to reverse
    4983              :              engineer that conversion stmt following the chain using
    4984              :              reduc_idx and from the PHI using reduc_def.  */
    4985       106545 :           && (STMT_VINFO_DEF_TYPE (next_info) == vect_reduction_def
    4986       106545 :               || (STMT_VINFO_DEF_TYPE (next_info)
    4987              :                   == vect_double_reduction_def)))
    4988              :         {
    4989              :           /* Do not discover SLP reductions combining lane-reducing
    4990              :              ops, that will fail later.  */
    4991       106545 :           if (!force_single_lane
    4992       106545 :               && !lane_reducing_stmt_p (STMT_VINFO_STMT (next_info)))
    4993        79288 :             scalar_stmts.quick_push (next_info);
    4994              :           /* Do SLP discovery for single-lane reductions.  */
    4995        27257 :           else if (! vect_analyze_slp_reduction (loop_vinfo, next_info,
    4996              :                                                  max_tree_size, limit,
    4997              :                                                  bst_map,
    4998              :                                                  force_single_lane))
    4999              :             {
    5000            0 :               scalar_stmts.release ();
    5001            0 :               return false;
    5002              :             }
    5003              :         }
    5004              :     }
    5005              : 
    5006        74389 :   if (scalar_stmts.length () > 1)
    5007              :     {
    5008              :       /* Try to form a reduction group.  */
    5009         4644 :       unsigned int group_size = scalar_stmts.length ();
    5010         4644 :       bool *matches = XALLOCAVEC (bool, group_size);
    5011         4644 :       if (vect_analyze_slp_reduction_group (loop_vinfo, scalar_stmts, bst_map,
    5012              :                                             max_tree_size, limit, matches))
    5013         1579 :         return true;
    5014              : 
    5015              :       /* When analysis as a single SLP reduction group failed try to
    5016              :          form sub-groups by collecting matching lanes.  Do not recurse
    5017              :          that on failure (to limit compile-time costs), but recurse
    5018              :          for the initial non-matching parts.  Everything not covered
    5019              :          by a sub-group gets single-reduction treatment.  */
    5020         3517 :       vec<stmt_vec_info> cands = vNULL;
    5021        11364 :       while (matches[0])
    5022              :         {
    5023        11229 :           cands.truncate (0);
    5024        11229 :           cands.reserve (group_size, true);
    5025        88339 :           for (unsigned i = 0; i < group_size; ++i)
    5026        77110 :             if (matches[i])
    5027        19562 :               cands.quick_push (scalar_stmts[i]);
    5028              : 
    5029              :           /* Try to form a reduction group.  */
    5030        11229 :           if (vect_analyze_slp_reduction_group (loop_vinfo, cands, bst_map,
    5031              :                                                 max_tree_size, limit, NULL))
    5032         1207 :             cands = vNULL;
    5033              :           else
    5034              :             {
    5035              :               /* Do SLP discovery for single-lane reductions.  */
    5036        47164 :               for (auto stmt_info : cands)
    5037        17120 :                 if (! vect_analyze_slp_reduction (loop_vinfo,
    5038              :                                                   vect_stmt_to_vectorize
    5039              :                                                     (stmt_info),
    5040              :                                                   max_tree_size, limit,
    5041              :                                                   bst_map, force_single_lane))
    5042              :                   {
    5043           22 :                     scalar_stmts.release ();
    5044           22 :                     cands.release ();
    5045           22 :                     return false;
    5046              :                   }
    5047              :             }
    5048              :           /* Remove the handled stmts from scalar_stmts and try again,
    5049              :              possibly repeating the above with updated matches[].  */
    5050              :           unsigned j = 0;
    5051        88255 :           for (unsigned i = 0; i < group_size; ++i)
    5052        77048 :             if (!matches[i])
    5053              :               {
    5054        57521 :                 scalar_stmts[j] = scalar_stmts[i];
    5055        57521 :                 ++j;
    5056              :               }
    5057        11207 :           scalar_stmts.truncate (j);
    5058        11207 :           group_size = scalar_stmts.length ();
    5059        11207 :           if (group_size <= 1)
    5060              :             break;
    5061         8277 :           if (vect_analyze_slp_reduction_group (loop_vinfo, scalar_stmts,
    5062              :                                                 bst_map, max_tree_size, limit,
    5063              :                                                 matches))
    5064              :             return true;
    5065              :         }
    5066              :     }
    5067              :   /* Do SLP discovery for single-lane reductions.  */
    5068       272344 :   for (auto stmt_info : scalar_stmts)
    5069        55792 :     if (! vect_analyze_slp_reduction (loop_vinfo,
    5070              :                                       vect_stmt_to_vectorize (stmt_info),
    5071              :                                       max_tree_size, limit,
    5072              :                                       bst_map, force_single_lane))
    5073              :       {
    5074         1878 :         scalar_stmts.release ();
    5075         1878 :         return false;
    5076              :       }
    5077              : 
    5078        70932 :   scalar_stmts.release ();
    5079        70932 :   return true;
    5080              : }
    5081              : 
    5082              : /* Analyze an SLP instance starting from a group of grouped stores.  Call
    5083              :    vect_build_slp_tree to build a tree of packed stmts if possible.
    5084              :    Return FALSE if it's impossible to SLP any stmt in the group.  */
    5085              : 
    5086              : static bool
    5087      1117599 : vect_analyze_slp_instance (vec_info *vinfo,
    5088              :                            scalar_stmts_to_slp_tree_map_t *bst_map,
    5089              :                            stmt_vec_info stmt_info,
    5090              :                            slp_instance_kind kind,
    5091              :                            unsigned max_tree_size, unsigned *limit,
    5092              :                            bool force_single_lane)
    5093              : {
    5094      1117599 :   vec<stmt_vec_info> scalar_stmts;
    5095              : 
    5096      1117599 :   if (is_a <bb_vec_info> (vinfo))
    5097      1087438 :     vect_location = stmt_info->stmt;
    5098              : 
    5099      1117599 :   gcc_assert (kind == slp_inst_kind_store);
    5100              : 
    5101              :   /* Collect the stores and store them in scalar_stmts.  */
    5102      1117599 :   scalar_stmts.create (DR_GROUP_SIZE (stmt_info));
    5103      1117599 :   stmt_vec_info next_info = stmt_info;
    5104      5556294 :   while (next_info)
    5105              :     {
    5106      3321096 :       scalar_stmts.quick_push (vect_stmt_to_vectorize (next_info));
    5107      3321096 :       next_info = DR_GROUP_NEXT_ELEMENT (next_info);
    5108              :     }
    5109              : 
    5110      1117599 :   vec<stmt_vec_info> root_stmt_infos = vNULL;
    5111      1117599 :   vec<tree> remain = vNULL;
    5112              : 
    5113              :   /* Build the tree for the SLP instance.  */
    5114              : 
    5115              :   /* If there's no budget left bail out early.  */
    5116      1117599 :   if (*limit == 0)
    5117              :     return false;
    5118              : 
    5119      1117579 :   if (dump_enabled_p ())
    5120              :     {
    5121         4141 :       dump_printf_loc (MSG_NOTE, vect_location,
    5122              :                        "Starting SLP discovery for\n");
    5123        24251 :       for (unsigned i = 0; i < scalar_stmts.length (); ++i)
    5124        40220 :         dump_printf_loc (MSG_NOTE, vect_location,
    5125        20110 :                          "  %G", scalar_stmts[i]->stmt);
    5126              :     }
    5127              : 
    5128              :   /* Build the tree for the SLP instance.  */
    5129      1117579 :   unsigned int group_size = scalar_stmts.length ();
    5130      1117579 :   bool *matches = XALLOCAVEC (bool, group_size);
    5131      1117579 :   poly_uint64 max_nunits = 1;
    5132      1117579 :   unsigned tree_size = 0;
    5133      1117579 :   unsigned i;
    5134              : 
    5135      1117579 :   slp_tree node = NULL;
    5136      1117579 :   if (group_size > 1 && force_single_lane)
    5137              :     {
    5138         1771 :       matches[0] = true;
    5139         1771 :       matches[1] = false;
    5140              :     }
    5141              :   else
    5142      1115808 :     node = vect_build_slp_tree (vinfo, scalar_stmts,
    5143              :                                 &max_nunits, matches, limit,
    5144              :                                 &tree_size, bst_map);
    5145      1117579 :   if (node != NULL)
    5146              :     {
    5147              :       /* Calculate the unrolling factor based on the smallest type.  */
    5148       693101 :       poly_uint64 unrolling_factor
    5149       693101 :         = calculate_unrolling_factor (max_nunits, group_size);
    5150              : 
    5151       693101 :       if (maybe_ne (unrolling_factor, 1U)
    5152       693101 :           && is_a <bb_vec_info> (vinfo))
    5153              :         {
    5154            0 :           unsigned HOST_WIDE_INT const_max_nunits;
    5155            0 :           if (!max_nunits.is_constant (&const_max_nunits)
    5156            0 :               || const_max_nunits > group_size)
    5157              :             {
    5158            0 :               if (dump_enabled_p ())
    5159            0 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    5160              :                                  "Build SLP failed: store group "
    5161              :                                  "size not a multiple of the vector size "
    5162              :                                  "in basic block SLP\n");
    5163            0 :               vect_free_slp_tree (node);
    5164            0 :               return false;
    5165              :             }
    5166              :           /* Fatal mismatch.  */
    5167            0 :           if (dump_enabled_p ())
    5168            0 :             dump_printf_loc (MSG_NOTE, vect_location,
    5169              :                              "SLP discovery succeeded but node needs "
    5170              :                              "splitting\n");
    5171            0 :           memset (matches, true, group_size);
    5172            0 :           matches[group_size / const_max_nunits * const_max_nunits] = false;
    5173            0 :           vect_free_slp_tree (node);
    5174              :         }
    5175              :       else
    5176              :         {
    5177              :           /* Create a new SLP instance.  */
    5178       693101 :           slp_instance new_instance = XNEW (class _slp_instance);
    5179       693101 :           SLP_INSTANCE_TREE (new_instance) = node;
    5180       693101 :           SLP_INSTANCE_LOADS (new_instance) = vNULL;
    5181       693101 :           SLP_INSTANCE_ROOT_STMTS (new_instance) = root_stmt_infos;
    5182       693101 :           SLP_INSTANCE_REMAIN_DEFS (new_instance) = remain;
    5183       693101 :           SLP_INSTANCE_KIND (new_instance) = kind;
    5184       693101 :           new_instance->reduc_phis = NULL;
    5185       693101 :           new_instance->cost_vec = vNULL;
    5186       693101 :           new_instance->subgraph_entries = vNULL;
    5187              : 
    5188       693101 :           if (dump_enabled_p ())
    5189         3142 :             dump_printf_loc (MSG_NOTE, vect_location,
    5190              :                              "SLP size %u vs. limit %u.\n",
    5191              :                              tree_size, max_tree_size);
    5192              : 
    5193       693101 :           vinfo->slp_instances.safe_push (new_instance);
    5194              : 
    5195              :           /* ???  We've replaced the old SLP_INSTANCE_GROUP_SIZE with
    5196              :              the number of SLP lanes of the root in a few places.
    5197              :              Verify that assumption holds.  */
    5198       693101 :           gcc_assert (SLP_TREE_LANES (SLP_INSTANCE_TREE (new_instance))
    5199              :                       == group_size);
    5200              : 
    5201       693101 :           if (dump_enabled_p ())
    5202              :             {
    5203         3142 :               dump_printf_loc (MSG_NOTE, vect_location,
    5204              :                                "Final SLP tree for instance %p:\n",
    5205              :                                (void *) new_instance);
    5206         3142 :               vect_print_slp_graph (MSG_NOTE, vect_location,
    5207              :                                     SLP_INSTANCE_TREE (new_instance));
    5208              :             }
    5209              : 
    5210       693101 :           return true;
    5211              :         }
    5212              :     }
    5213              :   /* Failed to SLP.  */
    5214              : 
    5215              :   /* Try to break the group up into pieces.  */
    5216       424478 :   if (*limit > 0 && kind == slp_inst_kind_store)
    5217              :     {
    5218              :       /* ???  We could delay all the actual splitting of store-groups
    5219              :          until after SLP discovery of the original group completed.
    5220              :          Then we can recurse to vect_build_slp_instance directly.  */
    5221      1111127 :       for (i = 0; i < group_size; i++)
    5222      1111127 :         if (!matches[i])
    5223              :           break;
    5224              : 
    5225              :       /* For basic block SLP, try to break the group up into multiples of
    5226              :          a vector size.  */
    5227       424477 :       if (is_a <bb_vec_info> (vinfo)
    5228       424477 :           && (i > 1 && i < group_size))
    5229              :         {
    5230              :           /* Free the allocated memory.  */
    5231       159251 :           scalar_stmts.release ();
    5232              : 
    5233       159251 :           tree scalar_type
    5234       159251 :             = TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (stmt_info)));
    5235       318502 :           tree vectype = get_vectype_for_scalar_type (vinfo, scalar_type,
    5236       159251 :                                                       1 << floor_log2 (i));
    5237       159251 :           unsigned HOST_WIDE_INT const_nunits;
    5238       159251 :           if (vectype
    5239       159251 :               && TYPE_VECTOR_SUBPARTS (vectype).is_constant (&const_nunits))
    5240              :             {
    5241              :               /* Split into two groups at the first vector boundary.  */
    5242       159251 :               gcc_assert ((const_nunits & (const_nunits - 1)) == 0);
    5243       159251 :               unsigned group1_size = i & ~(const_nunits - 1);
    5244              : 
    5245       159251 :               if (dump_enabled_p ())
    5246           66 :                 dump_printf_loc (MSG_NOTE, vect_location,
    5247              :                                  "Splitting SLP group at stmt %u\n", i);
    5248       159251 :               stmt_vec_info rest = vect_split_slp_store_group (stmt_info,
    5249              :                                                                group1_size);
    5250       159251 :               bool res = vect_analyze_slp_instance (vinfo, bst_map, stmt_info,
    5251              :                                                     kind, max_tree_size,
    5252              :                                                     limit, false);
    5253              :               /* Split the rest at the failure point and possibly
    5254              :                  re-analyze the remaining matching part if it has
    5255              :                  at least two lanes.  */
    5256       159251 :               if (group1_size < i
    5257         5673 :                   && (i + 1 < group_size
    5258         3070 :                       || i - group1_size > 1))
    5259              :                 {
    5260         2631 :                   stmt_vec_info rest2 = rest;
    5261         2631 :                   rest = vect_split_slp_store_group (rest, i - group1_size);
    5262         2631 :                   if (i - group1_size > 1)
    5263           57 :                     res |= vect_analyze_slp_instance (vinfo, bst_map, rest2,
    5264              :                                                       kind, max_tree_size,
    5265              :                                                       limit, false);
    5266              :                 }
    5267              :               /* Re-analyze the non-matching tail if it has at least
    5268              :                  two lanes.  */
    5269       159251 :               if (i + 1 < group_size)
    5270        22489 :                 res |= vect_analyze_slp_instance (vinfo, bst_map,
    5271              :                                                   rest, kind, max_tree_size,
    5272              :                                                   limit, false);
    5273       159251 :               return res;
    5274              :             }
    5275              :         }
    5276              : 
    5277              :       /* For loop vectorization split the RHS into arbitrary pieces of
    5278              :          size >= 1.  */
    5279       265226 :       else if (is_a <loop_vec_info> (vinfo)
    5280       265226 :                && (group_size != 1 && i < group_size))
    5281              :         {
    5282         8360 :           gcall *call = dyn_cast <gcall *> (stmt_info->stmt);
    5283           28 :           bool masked_p = call
    5284           28 :               && gimple_call_internal_p (call)
    5285           28 :               && internal_fn_mask_index (gimple_call_internal_fn (call)) != -1;
    5286              :           /* There are targets that cannot do even/odd interleaving schemes
    5287              :              so they absolutely need to use load/store-lanes.  For now
    5288              :              force single-lane SLP for them - they would be happy with
    5289              :              uniform power-of-two lanes (but depending on element size),
    5290              :              but even if we can use 'i' as indicator we would need to
    5291              :              backtrack when later lanes fail to discover with the same
    5292              :              granularity.  We cannot turn any of strided or scatter store
    5293              :              into store-lanes.  */
    5294              :           /* ???  If this is not in sync with what get_load_store_type
    5295              :              later decides the SLP representation is not good for other
    5296              :              store vectorization methods.  */
    5297         8360 :           bool want_store_lanes
    5298         8360 :             = (! STMT_VINFO_GATHER_SCATTER_P (stmt_info)
    5299         8360 :                && ! STMT_VINFO_STRIDED_P (stmt_info)
    5300         6260 :                && ! STMT_VINFO_SLP_VECT_ONLY (stmt_info)
    5301         6256 :                && compare_step_with_zero (vinfo, stmt_info) > 0
    5302        14511 :                && vect_slp_prefer_store_lanes_p (vinfo, stmt_info, NULL_TREE,
    5303        16720 :                                                  masked_p, group_size, i));
    5304         8360 :           if (want_store_lanes || force_single_lane)
    5305              :             i = 1;
    5306              : 
    5307              :           /* A fatal discovery fail doesn't always mean single-lane SLP
    5308              :              isn't a possibility, so try.  */
    5309         6589 :           if (i == 0)
    5310              :             i = 1;
    5311              : 
    5312         8360 :           if (dump_enabled_p ())
    5313          891 :             dump_printf_loc (MSG_NOTE, vect_location,
    5314              :                              "Splitting SLP group at stmt %u\n", i);
    5315              : 
    5316              :           /* Analyze the stored values and pinch them together with
    5317              :              a permute node so we can preserve the whole store group.  */
    5318         8360 :           auto_vec<slp_tree> rhs_nodes;
    5319         8360 :           poly_uint64 max_nunits = 1;
    5320              : 
    5321         8360 :           unsigned int rhs_common_nlanes = 0;
    5322         8360 :           unsigned int start = 0, end = i;
    5323        37866 :           while (start < group_size)
    5324              :             {
    5325        29624 :               gcc_assert (end - start >= 1);
    5326        29624 :               vec<stmt_vec_info> substmts;
    5327        29624 :               substmts.create (end - start);
    5328        91760 :               for (unsigned j = start; j < end; ++j)
    5329        62136 :                 substmts.quick_push (scalar_stmts[j]);
    5330        29624 :               max_nunits = 1;
    5331        29624 :               node = vect_build_slp_tree (vinfo, substmts,
    5332              :                                           &max_nunits,
    5333              :                                           matches, limit, &tree_size, bst_map);
    5334        29624 :               if (node)
    5335              :                 {
    5336        23817 :                   rhs_nodes.safe_push (node);
    5337        23817 :                   vect_update_max_nunits (&max_nunits, node->max_nunits);
    5338        23817 :                   if (start == 0)
    5339         8242 :                     rhs_common_nlanes = SLP_TREE_LANES (node);
    5340        15575 :                   else if (rhs_common_nlanes != SLP_TREE_LANES (node))
    5341         1399 :                     rhs_common_nlanes = 0;
    5342        23817 :                   start = end;
    5343        23817 :                   if (want_store_lanes || force_single_lane)
    5344         5315 :                     end = start + 1;
    5345              :                   else
    5346              :                     end = group_size;
    5347              :                 }
    5348              :               else
    5349              :                 {
    5350         5807 :                   substmts.release ();
    5351         5807 :                   if (end - start == 1)
    5352              :                     {
    5353              :                       /* Single-lane discovery failed.  Free resources.  */
    5354          118 :                       for (auto node : rhs_nodes)
    5355            0 :                         vect_free_slp_tree (node);
    5356          118 :                       scalar_stmts.release ();
    5357          118 :                       if (dump_enabled_p ())
    5358           17 :                         dump_printf_loc (MSG_NOTE, vect_location,
    5359              :                                          "SLP discovery failed\n");
    5360          118 :                       return false;
    5361              :                     }
    5362              : 
    5363              :                   /* ???  It really happens that we soft-fail SLP
    5364              :                      build at a mismatch but the matching part hard-fails
    5365              :                      later.  As we know we arrived here with a group
    5366              :                      larger than one try a group of size one!  */
    5367         5689 :                   if (!matches[0])
    5368           12 :                     end = start + 1;
    5369              :                   else
    5370        12459 :                     for (unsigned j = start; j < end; j++)
    5371        12459 :                       if (!matches[j - start])
    5372              :                         {
    5373              :                           end = j;
    5374              :                           break;
    5375              :                         }
    5376              :                 }
    5377              :             }
    5378              : 
    5379              :           /* Now re-assess whether we want store lanes in case the
    5380              :              discovery ended up producing all single-lane RHSs.  */
    5381         8242 :           if (! want_store_lanes
    5382         8242 :               && rhs_common_nlanes == 1
    5383         7176 :               && ! STMT_VINFO_GATHER_SCATTER_P (stmt_info)
    5384         7176 :               && ! STMT_VINFO_STRIDED_P (stmt_info)
    5385         5441 :               && ! STMT_VINFO_SLP_VECT_ONLY (stmt_info)
    5386         5438 :               && compare_step_with_zero (vinfo, stmt_info) > 0
    5387        13593 :               && (vect_store_lanes_supported (SLP_TREE_VECTYPE (rhs_nodes[0]),
    5388              :                                               group_size, masked_p)
    5389              :                   != IFN_LAST))
    5390              :             want_store_lanes = true;
    5391              : 
    5392              :           /* Now we assume we can build the root SLP node from all stores.  */
    5393         8242 :           if (want_store_lanes)
    5394              :             {
    5395              :               /* For store-lanes feed the store node with all RHS nodes
    5396              :                  in order.  */
    5397            0 :               node = vect_create_new_slp_node (scalar_stmts,
    5398            0 :                                                SLP_TREE_CHILDREN
    5399              :                                                  (rhs_nodes[0]).length ());
    5400            0 :               SLP_TREE_VECTYPE (node) = SLP_TREE_VECTYPE (rhs_nodes[0]);
    5401            0 :               node->max_nunits = max_nunits;
    5402            0 :               node->ldst_lanes = true;
    5403            0 :               SLP_TREE_CHILDREN (node)
    5404            0 :                 .reserve_exact (SLP_TREE_CHILDREN (rhs_nodes[0]).length ()
    5405            0 :                                 + rhs_nodes.length () - 1);
    5406              :               /* First store value and possibly mask.  */
    5407            0 :               SLP_TREE_CHILDREN (node)
    5408            0 :                 .splice (SLP_TREE_CHILDREN (rhs_nodes[0]));
    5409              :               /* Rest of the store values.  All mask nodes are the same,
    5410              :                  this should be guaranteed by dataref group discovery.  */
    5411            0 :               for (unsigned j = 1; j < rhs_nodes.length (); ++j)
    5412            0 :                 SLP_TREE_CHILDREN (node)
    5413            0 :                   .quick_push (SLP_TREE_CHILDREN (rhs_nodes[j])[0]);
    5414            0 :               for (slp_tree child : SLP_TREE_CHILDREN (node))
    5415            0 :                 child->refcnt++;
    5416              :             }
    5417              :           else
    5418         8242 :             node = vect_build_slp_store_interleaving (rhs_nodes, scalar_stmts,
    5419              :                                                       max_nunits);
    5420              : 
    5421        32059 :           while (!rhs_nodes.is_empty ())
    5422        23817 :             vect_free_slp_tree (rhs_nodes.pop ());
    5423              : 
    5424              :           /* Create a new SLP instance.  */
    5425         8242 :           slp_instance new_instance = XNEW (class _slp_instance);
    5426         8242 :           SLP_INSTANCE_TREE (new_instance) = node;
    5427         8242 :           SLP_INSTANCE_LOADS (new_instance) = vNULL;
    5428         8242 :           SLP_INSTANCE_ROOT_STMTS (new_instance) = root_stmt_infos;
    5429         8242 :           SLP_INSTANCE_REMAIN_DEFS (new_instance) = remain;
    5430         8242 :           SLP_INSTANCE_KIND (new_instance) = kind;
    5431         8242 :           new_instance->reduc_phis = NULL;
    5432         8242 :           new_instance->cost_vec = vNULL;
    5433         8242 :           new_instance->subgraph_entries = vNULL;
    5434              : 
    5435         8242 :           if (dump_enabled_p ())
    5436          874 :             dump_printf_loc (MSG_NOTE, vect_location,
    5437              :                              "SLP size %u vs. limit %u.\n",
    5438              :                              tree_size, max_tree_size);
    5439              : 
    5440         8242 :           vinfo->slp_instances.safe_push (new_instance);
    5441              : 
    5442              :           /* ???  We've replaced the old SLP_INSTANCE_GROUP_SIZE with
    5443              :              the number of SLP lanes of the root in a few places.
    5444              :              Verify that assumption holds.  */
    5445         8242 :           gcc_assert (SLP_TREE_LANES (SLP_INSTANCE_TREE (new_instance))
    5446              :                       == group_size);
    5447              : 
    5448         8242 :           if (dump_enabled_p ())
    5449              :             {
    5450          874 :               dump_printf_loc (MSG_NOTE, vect_location,
    5451              :                                "Final SLP tree for instance %p:\n",
    5452              :                                (void *) new_instance);
    5453          874 :               vect_print_slp_graph (MSG_NOTE, vect_location,
    5454              :                                     SLP_INSTANCE_TREE (new_instance));
    5455              :             }
    5456         8242 :           return true;
    5457         8360 :         }
    5458              :       else
    5459              :         /* Free the allocated memory.  */
    5460       256866 :         scalar_stmts.release ();
    5461              : 
    5462              :       /* Even though the first vector did not all match, we might be able to SLP
    5463              :          (some) of the remainder.  FORNOW ignore this possibility.  */
    5464              :     }
    5465              :   else
    5466              :     /* Free the allocated memory.  */
    5467            1 :     scalar_stmts.release ();
    5468              : 
    5469              :   /* Failed to SLP.  */
    5470       256867 :   if (dump_enabled_p ())
    5471           42 :     dump_printf_loc (MSG_NOTE, vect_location, "SLP discovery failed\n");
    5472              :   return false;
    5473              : }
    5474              : 
    5475              : /* qsort comparator ordering SLP load nodes.  */
    5476              : 
    5477              : static int
    5478      2688446 : vllp_cmp (const void *a_, const void *b_)
    5479              : {
    5480      2688446 :   const slp_tree a = *(const slp_tree *)a_;
    5481      2688446 :   const slp_tree b = *(const slp_tree *)b_;
    5482      2688446 :   stmt_vec_info a0 = SLP_TREE_SCALAR_STMTS (a)[0];
    5483      2688446 :   stmt_vec_info b0 = SLP_TREE_SCALAR_STMTS (b)[0];
    5484      2688446 :   if (STMT_VINFO_GROUPED_ACCESS (a0)
    5485      1546893 :       && STMT_VINFO_GROUPED_ACCESS (b0)
    5486      4173422 :       && DR_GROUP_FIRST_ELEMENT (a0) == DR_GROUP_FIRST_ELEMENT (b0))
    5487              :     {
    5488              :       /* Same group, order after lanes used.  */
    5489       348476 :       if (SLP_TREE_LANES (a) < SLP_TREE_LANES (b))
    5490              :         return 1;
    5491       339497 :       else if (SLP_TREE_LANES (a) > SLP_TREE_LANES (b))
    5492              :         return -1;
    5493              :       else
    5494              :         {
    5495              :           /* Try to order loads using the same lanes together, breaking
    5496              :              the tie with the lane number that first differs.  */
    5497       329754 :           if (!SLP_TREE_LOAD_PERMUTATION (a).exists ()
    5498       329754 :               && !SLP_TREE_LOAD_PERMUTATION (b).exists ())
    5499              :             return 0;
    5500       329754 :           else if (SLP_TREE_LOAD_PERMUTATION (a).exists ()
    5501       329754 :                    && !SLP_TREE_LOAD_PERMUTATION (b).exists ())
    5502              :             return 1;
    5503       325691 :           else if (!SLP_TREE_LOAD_PERMUTATION (a).exists ()
    5504       325691 :                    && SLP_TREE_LOAD_PERMUTATION (b).exists ())
    5505              :             return -1;
    5506              :           else
    5507              :             {
    5508       318205 :               for (unsigned i = 0; i < SLP_TREE_LANES (a); ++i)
    5509       318205 :                 if (SLP_TREE_LOAD_PERMUTATION (a)[i]
    5510       318205 :                     != SLP_TREE_LOAD_PERMUTATION (b)[i])
    5511              :                   {
    5512              :                     /* In-order lane first, that's what the above case for
    5513              :                        no permutation does.  */
    5514       316893 :                     if (SLP_TREE_LOAD_PERMUTATION (a)[i] == i)
    5515              :                       return -1;
    5516       194237 :                     else if (SLP_TREE_LOAD_PERMUTATION (b)[i] == i)
    5517              :                       return 1;
    5518       102102 :                     else if (SLP_TREE_LOAD_PERMUTATION (a)[i]
    5519       102102 :                              < SLP_TREE_LOAD_PERMUTATION (b)[i])
    5520              :                       return -1;
    5521              :                     else
    5522              :                       return 1;
    5523              :                   }
    5524              :               return 0;
    5525              :             }
    5526              :         }
    5527              :     }
    5528              :   else /* Different groups or non-groups.  */
    5529              :     {
    5530              :       /* Order groups as their first element to keep them together.  */
    5531      2339970 :       if (STMT_VINFO_GROUPED_ACCESS (a0))
    5532      2339970 :         a0 = DR_GROUP_FIRST_ELEMENT (a0);
    5533      2339970 :       if (STMT_VINFO_GROUPED_ACCESS (b0))
    5534      2339970 :         b0 = DR_GROUP_FIRST_ELEMENT (b0);
    5535      2339970 :       if (a0 == b0)
    5536              :         return 0;
    5537              :       /* Tie using UID.  */
    5538      2339850 :       else if (gimple_uid (STMT_VINFO_STMT (a0))
    5539      2339850 :                < gimple_uid (STMT_VINFO_STMT (b0)))
    5540              :         return -1;
    5541              :       else
    5542              :         {
    5543      1040223 :           gcc_assert (gimple_uid (STMT_VINFO_STMT (a0))
    5544              :                       != gimple_uid (STMT_VINFO_STMT (b0)));
    5545              :           return 1;
    5546              :         }
    5547              :     }
    5548              : }
    5549              : 
    5550              : /* Return whether if the load permutation of NODE is consecutive starting
    5551              :    with value START_VAL in the first element.  If START_VAL is not given
    5552              :    the first element's value is used.  */
    5553              : 
    5554              : bool
    5555       644582 : vect_load_perm_consecutive_p (slp_tree node, unsigned start_val)
    5556              : {
    5557       644582 :   load_permutation_t perm = SLP_TREE_LOAD_PERMUTATION (node);
    5558              : 
    5559       644582 :   if (!perm.exists () || !perm.length ())
    5560              :     return false;
    5561              : 
    5562       644582 :   if (start_val == UINT_MAX)
    5563        79890 :     start_val = perm[0];
    5564              : 
    5565      1273012 :   for (unsigned int i = 0; i < perm.length (); i++)
    5566       651917 :     if (perm[i] != start_val + (unsigned int) i)
    5567              :       return false;
    5568              : 
    5569              :   return true;
    5570              : }
    5571              : 
    5572              : /* Process the set of LOADS that are all from the same dataref group.  */
    5573              : 
    5574              : static void
    5575       161864 : vect_lower_load_permutations (loop_vec_info loop_vinfo,
    5576              :                               scalar_stmts_to_slp_tree_map_t *bst_map,
    5577              :                               const array_slice<slp_tree> &loads,
    5578              :                               bool force_single_lane)
    5579              : {
    5580              :   /* We at this point want to lower without a fixed VF or vector
    5581              :      size in mind which means we cannot actually compute whether we
    5582              :      need three or more vectors for a load permutation yet.  So always
    5583              :      lower.  */
    5584       161864 :   stmt_vec_info first
    5585       161864 :     = DR_GROUP_FIRST_ELEMENT (SLP_TREE_SCALAR_STMTS (loads[0])[0]);
    5586       161864 :   unsigned group_lanes = DR_GROUP_SIZE (first);
    5587              : 
    5588              :   /* Verify if all load permutations can be implemented with a suitably
    5589              :      large element load-lanes operation.  */
    5590       161864 :   unsigned ld_lanes_lanes = SLP_TREE_LANES (loads[0]);
    5591       161864 :   if (STMT_VINFO_STRIDED_P (first)
    5592       159411 :       || compare_step_with_zero (loop_vinfo, first) <= 0
    5593       156723 :       || exact_log2 (ld_lanes_lanes) == -1
    5594              :       /* ???  For now only support the single-lane case as there is
    5595              :          missing support on the store-lane side and code generation
    5596              :          isn't up to the task yet.  */
    5597       153920 :       || ld_lanes_lanes != 1
    5598       304757 :       || vect_load_lanes_supported (SLP_TREE_VECTYPE (loads[0]),
    5599              :                                     group_lanes / ld_lanes_lanes,
    5600              :                                     false) == IFN_LAST)
    5601              :     ld_lanes_lanes = 0;
    5602              :   else
    5603              :     /* Verify the loads access the same number of lanes aligned to
    5604              :        ld_lanes_lanes.  */
    5605            0 :     for (slp_tree load : loads)
    5606              :       {
    5607            0 :         if (SLP_TREE_LANES (load) != ld_lanes_lanes)
    5608              :           {
    5609              :             ld_lanes_lanes = 0;
    5610              :             break;
    5611              :           }
    5612            0 :         unsigned first = SLP_TREE_LOAD_PERMUTATION (load)[0];
    5613            0 :         if (first % ld_lanes_lanes != 0)
    5614              :           {
    5615              :             ld_lanes_lanes = 0;
    5616              :             break;
    5617              :           }
    5618            0 :         if (!vect_load_perm_consecutive_p (load))
    5619              :           {
    5620              :             ld_lanes_lanes = 0;
    5621              :             break;
    5622              :           }
    5623              :       }
    5624              : 
    5625              :   /* Only a power-of-two number of lanes matches interleaving with N levels.
    5626              :      ???  An even number of lanes could be reduced to 1<<ceil_log2(N)-1 lanes
    5627              :      at each step.  */
    5628       262529 :   if (ld_lanes_lanes == 0 && exact_log2 (group_lanes) == -1 && group_lanes != 3)
    5629              :     return;
    5630              : 
    5631       266550 :   for (slp_tree load : loads)
    5632              :     {
    5633              :       /* Leave masked or gather loads alone for now.  */
    5634       188133 :       if (!SLP_TREE_CHILDREN (load).is_empty ())
    5635        60950 :         continue;
    5636              : 
    5637              :       /* For single-element interleaving spanning multiple vectors avoid
    5638              :          lowering, we want to use VMAT_ELEMENTWISE later.  */
    5639       188127 :       if (ld_lanes_lanes == 0
    5640       188127 :           && SLP_TREE_LANES (load) == 1
    5641       168652 :           && !DR_GROUP_NEXT_ELEMENT (first)
    5642       267826 :           && maybe_gt (group_lanes,
    5643              :                        TYPE_VECTOR_SUBPARTS (SLP_TREE_VECTYPE (load))))
    5644        51309 :         return;
    5645              : 
    5646              :       /* We want to pattern-match special cases here and keep those
    5647              :          alone.  Candidates are splats and load-lane.  */
    5648              : 
    5649              :       /* We need to lower only loads of less than half of the groups
    5650              :          lanes, including duplicate lanes.  Note this leaves nodes
    5651              :          with a non-1:1 load permutation around instead of canonicalizing
    5652              :          those into a load and a permute node.  Removing this early
    5653              :          check would do such canonicalization.  */
    5654       136818 :       if (SLP_TREE_LANES (load) >= (group_lanes + 1) / 2
    5655        57361 :           && ld_lanes_lanes == 0)
    5656        57361 :         continue;
    5657              : 
    5658              :       /* Build the permute to get the original load permutation order.  */
    5659        79457 :       bool contiguous = vect_load_perm_consecutive_p (load);
    5660        79457 :       lane_permutation_t final_perm;
    5661        79457 :       final_perm.create (SLP_TREE_LANES (load));
    5662       159858 :       for (unsigned i = 0; i < SLP_TREE_LANES (load); ++i)
    5663       160802 :         final_perm.quick_push (
    5664        80401 :           std::make_pair (0, SLP_TREE_LOAD_PERMUTATION (load)[i]));
    5665              : 
    5666              :       /* When the load permutation accesses a contiguous unpermuted,
    5667              :          power-of-two aligned and sized chunk leave the load alone.
    5668              :          We can likely (re-)load it more efficiently rather than
    5669              :          extracting it from the larger load.
    5670              :          ???  Long-term some of the lowering should move to where
    5671              :          the vector types involved are fixed.  */
    5672        83040 :       if (!force_single_lane
    5673        79457 :           && ld_lanes_lanes == 0
    5674        53582 :           && contiguous
    5675        53322 :           && (SLP_TREE_LANES (load) > 1 || loads.size () == 1)
    5676         6579 :           && pow2p_hwi (SLP_TREE_LANES (load))
    5677         6543 :           && pow2p_hwi (group_lanes)
    5678         3583 :           && SLP_TREE_LOAD_PERMUTATION (load)[0] % SLP_TREE_LANES (load) == 0
    5679        83040 :           && group_lanes % SLP_TREE_LANES (load) == 0)
    5680              :         {
    5681         3583 :           final_perm.release ();
    5682         3583 :           continue;
    5683              :         }
    5684              : 
    5685              :       /* First build (and possibly re-use) a load node for the
    5686              :          unpermuted group.  Gaps in the middle and on the end are
    5687              :          represented with NULL stmts.  */
    5688        75874 :       vec<stmt_vec_info> stmts;
    5689        75874 :       stmts.create (group_lanes);
    5690       270839 :       for (stmt_vec_info s = first; s; s = DR_GROUP_NEXT_ELEMENT (s))
    5691              :         {
    5692       194965 :           if (s != first)
    5693       124202 :             for (unsigned i = 1; i < DR_GROUP_GAP (s); ++i)
    5694         5111 :               stmts.quick_push (NULL);
    5695       194965 :           stmts.quick_push (s);
    5696              :         }
    5697       139813 :       for (unsigned i = 0; i < DR_GROUP_GAP (first); ++i)
    5698        63939 :         stmts.quick_push (NULL);
    5699        75874 :       poly_uint64 max_nunits = 1;
    5700        75874 :       bool *matches = XALLOCAVEC (bool, group_lanes);
    5701        75874 :       unsigned limit = 1;
    5702        75874 :       unsigned tree_size = 0;
    5703        75874 :       slp_tree l0 = vect_build_slp_tree (loop_vinfo, stmts,
    5704              :                                          &max_nunits, matches, &limit,
    5705        75874 :                                          &tree_size, bst_map);
    5706        75874 :       gcc_assert (!SLP_TREE_LOAD_PERMUTATION (l0).exists ());
    5707              : 
    5708        75874 :       if (ld_lanes_lanes != 0)
    5709              :         {
    5710              :           /* ???  If this is not in sync with what get_load_store_type
    5711              :              later decides the SLP representation is not good for other
    5712              :              store vectorization methods.  */
    5713            0 :           l0->ldst_lanes = true;
    5714            0 :           load->ldst_lanes = true;
    5715              :         }
    5716              : 
    5717       236320 :       while (1)
    5718              :         {
    5719       156097 :           unsigned group_lanes = SLP_TREE_LANES (l0);
    5720       156097 :           if (ld_lanes_lanes != 0
    5721       156097 :               || SLP_TREE_LANES (load) >= (group_lanes + 1) / 2)
    5722              :             break;
    5723              : 
    5724              :           /* Try to lower by reducing the group to half its size using an
    5725              :              interleaving scheme.  For this try to compute whether all
    5726              :              elements needed for this load are in even or odd elements of
    5727              :              an even/odd decomposition with N consecutive elements.
    5728              :              Thus { e, e, o, o, e, e, o, o } would be an even/odd decomposition
    5729              :              with N == 2.  */
    5730              :           /* ???  Only an even number of lanes can be handed this way, but the
    5731              :              fallback below could work for any number.  We have to make sure
    5732              :              to round up in that case.  */
    5733        80223 :           gcc_assert ((group_lanes & 1) == 0 || group_lanes == 3);
    5734        12150 :           unsigned even = 0, odd = 0;
    5735        12150 :           if ((group_lanes & 1) == 0)
    5736              :             {
    5737        12150 :               even = (1 << ceil_log2 (group_lanes)) - 1;
    5738        12150 :               odd = even;
    5739        49349 :               for (auto l : final_perm)
    5740              :                 {
    5741        12899 :                   even &= ~l.second;
    5742        12899 :                   odd &= l.second;
    5743              :                 }
    5744              :             }
    5745              : 
    5746              :           /* Now build an even or odd extraction from the unpermuted load.  */
    5747        80223 :           lane_permutation_t perm;
    5748        80223 :           perm.create ((group_lanes + 1) / 2);
    5749        80223 :           unsigned even_level = even ? 1 << ctz_hwi (even) : 0;
    5750        80223 :           unsigned odd_level = odd ? 1 << ctz_hwi (odd) : 0;
    5751        80223 :           if (even_level
    5752        11168 :               && group_lanes % (2 * even_level) == 0
    5753              :               /* ???  When code generating permutes we do not try to pun
    5754              :                  to larger component modes so level != 1 isn't a natural
    5755              :                  even/odd extract.  Prefer one if possible.  */
    5756        11168 :               && (even_level == 1 || !odd_level || odd_level != 1))
    5757              :             {
    5758              :               /* { 0, 1, ... 4, 5 ..., } */
    5759        39574 :               for (unsigned i = 0; i < group_lanes / 2 / even_level; ++i)
    5760        62465 :                 for (unsigned j = 0; j < even_level; ++j)
    5761        31428 :                   perm.quick_push (std::make_pair (0, 2 * i * even_level + j));
    5762              :             }
    5763        69055 :           else if (odd_level)
    5764              :             {
    5765              :               /* { ..., 2, 3, ... 6, 7 } */
    5766         3583 :               gcc_assert (group_lanes % (2 * odd_level) == 0);
    5767        15451 :               for (unsigned i = 0; i < group_lanes / 2 / odd_level; ++i)
    5768        23790 :                 for (unsigned j = 0; j < odd_level; ++j)
    5769        11922 :                   perm.quick_push
    5770        11922 :                     (std::make_pair (0, (2 * i + 1) * odd_level + j));
    5771              :             }
    5772              :           else
    5773              :             {
    5774              :               /* As fallback extract all used lanes and fill to half the
    5775              :                  group size by repeating the last element.
    5776              :                  ???  This is quite a bad strathegy for re-use - we could
    5777              :                  brute force our way to find more optimal filling lanes to
    5778              :                  maximize re-use when looking at all loads from the group.  */
    5779        68103 :               auto_bitmap l;
    5780       272468 :               for (auto p : final_perm)
    5781        68159 :                 bitmap_set_bit (l, p.second);
    5782        68103 :               unsigned i = 0;
    5783        68103 :               bitmap_iterator bi;
    5784       136262 :               EXECUTE_IF_SET_IN_BITMAP (l, 0, i, bi)
    5785        68159 :                   perm.quick_push (std::make_pair (0, i));
    5786       272564 :               while (perm.length () < (group_lanes + 1) / 2)
    5787        68179 :                 perm.quick_push (perm.last ());
    5788        68103 :             }
    5789              : 
    5790              :           /* Update final_perm with the intermediate permute.  */
    5791       161195 :           for (unsigned i = 0; i < final_perm.length (); ++i)
    5792              :             {
    5793        80972 :               unsigned l = final_perm[i].second;
    5794        80972 :               unsigned j;
    5795        90537 :               for (j = 0; j < perm.length (); ++j)
    5796        90537 :                 if (perm[j].second == l)
    5797              :                   {
    5798        80972 :                     final_perm[i].second = j;
    5799        80972 :                     break;
    5800              :                   }
    5801        80972 :               gcc_assert (j < perm.length ());
    5802              :             }
    5803              : 
    5804              :           /* And create scalar stmts.  */
    5805        80223 :           vec<stmt_vec_info> perm_stmts;
    5806        80223 :           perm_stmts.create (perm.length ());
    5807       259911 :           for (unsigned i = 0; i < perm.length (); ++i)
    5808       179688 :             perm_stmts.quick_push (SLP_TREE_SCALAR_STMTS (l0)[perm[i].second]);
    5809              : 
    5810        80223 :           slp_tree p = vect_create_new_slp_node (1, VEC_PERM_EXPR);
    5811        80223 :           SLP_TREE_CHILDREN (p).quick_push (l0);
    5812        80223 :           SLP_TREE_LANE_PERMUTATION (p) = perm;
    5813        80223 :           SLP_TREE_VECTYPE (p) = SLP_TREE_VECTYPE (load);
    5814        80223 :           SLP_TREE_LANES (p) = perm.length ();
    5815        80223 :           SLP_TREE_REPRESENTATIVE (p) = SLP_TREE_REPRESENTATIVE (load);
    5816              :           /* ???  As we have scalar stmts for this intermediate permute we
    5817              :              could CSE it via bst_map but we do not want to pick up
    5818              :              another SLP node with a load permutation.  We instead should
    5819              :              have a "local" CSE map here.  */
    5820        80223 :           SLP_TREE_SCALAR_STMTS (p) = perm_stmts;
    5821              : 
    5822              :           /* We now have a node for (group_lanes + 1) / 2 lanes.  */
    5823        80223 :           l0 = p;
    5824        80223 :         }
    5825              : 
    5826              :       /* And finally from the ordered reduction node create the
    5827              :          permute to shuffle the lanes into the original load-permutation
    5828              :          order.  We replace the original load node with this.  */
    5829        75874 :       SLP_TREE_CODE (load) = VEC_PERM_EXPR;
    5830        75874 :       SLP_TREE_LOAD_PERMUTATION (load).release ();
    5831        75874 :       SLP_TREE_LANE_PERMUTATION (load) = final_perm;
    5832        75874 :       SLP_TREE_CHILDREN (load).create (1);
    5833        75874 :       SLP_TREE_CHILDREN (load).quick_push (l0);
    5834              :     }
    5835              : }
    5836              : 
    5837              : /* Transform SLP loads in the SLP graph created by SLP discovery to
    5838              :    group loads from the same group and lower load permutations that
    5839              :    are unlikely to be supported into a series of permutes.
    5840              :    In the degenerate case of having only single-lane SLP instances
    5841              :    this should result in a series of permute nodes emulating an
    5842              :    interleaving scheme.  */
    5843              : 
    5844              : static void
    5845       497099 : vect_lower_load_permutations (loop_vec_info loop_vinfo,
    5846              :                               scalar_stmts_to_slp_tree_map_t *bst_map,
    5847              :                               bool force_single_lane)
    5848              : {
    5849              :   /* Gather and sort loads across all instances.  */
    5850       497099 :   hash_set<slp_tree> visited;
    5851       497099 :   auto_vec<slp_tree> loads;
    5852      2281435 :   for (auto inst : loop_vinfo->slp_instances)
    5853       792086 :     vect_gather_slp_loads (loads, SLP_INSTANCE_TREE (inst), visited);
    5854       497099 :   if (loads.is_empty ())
    5855        93364 :     return;
    5856       403735 :   loads.qsort (vllp_cmp);
    5857              : 
    5858              :   /* Now process each dataref group separately.  */
    5859       403735 :   unsigned firsti = 0;
    5860       747521 :   for (unsigned i = 1; i < loads.length (); ++i)
    5861              :     {
    5862       343786 :       slp_tree first = loads[firsti];
    5863       343786 :       slp_tree next = loads[i];
    5864       343786 :       stmt_vec_info a0 = SLP_TREE_SCALAR_STMTS (first)[0];
    5865       343786 :       stmt_vec_info b0 = SLP_TREE_SCALAR_STMTS (next)[0];
    5866       343786 :       if (STMT_VINFO_GROUPED_ACCESS (a0)
    5867       158736 :           && STMT_VINFO_GROUPED_ACCESS (b0)
    5868       489412 :           && DR_GROUP_FIRST_ELEMENT (a0) == DR_GROUP_FIRST_ELEMENT (b0))
    5869        63482 :         continue;
    5870              :       /* Now we have one or multiple SLP loads of the same group from
    5871              :          firsti to i - 1.  */
    5872       280304 :       if (STMT_VINFO_GROUPED_ACCESS (a0))
    5873        95254 :         vect_lower_load_permutations (loop_vinfo, bst_map,
    5874        95254 :                                       make_array_slice (&loads[firsti],
    5875              :                                                         i - firsti),
    5876              :                                       force_single_lane);
    5877              :       firsti = i;
    5878              :     }
    5879       807470 :   if (firsti < loads.length ()
    5880       807470 :       && STMT_VINFO_GROUPED_ACCESS (SLP_TREE_SCALAR_STMTS (loads[firsti])[0]))
    5881        66610 :     vect_lower_load_permutations (loop_vinfo, bst_map,
    5882        66610 :                                   make_array_slice (&loads[firsti],
    5883        66610 :                                                     loads.length () - firsti),
    5884              :                                   force_single_lane);
    5885       497099 : }
    5886              : 
    5887              : /* Check if there are stmts in the loop can be vectorized using SLP.  Build SLP
    5888              :    trees of packed scalar stmts if SLP is possible.  */
    5889              : 
    5890              : opt_result
    5891      1178419 : vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size,
    5892              :                   bool force_single_lane)
    5893              : {
    5894      1178419 :   loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo);
    5895      1178419 :   unsigned int i;
    5896      1178419 :   stmt_vec_info first_element;
    5897      1178419 :   slp_instance instance;
    5898              : 
    5899      1178419 :   DUMP_VECT_SCOPE ("vect_analyze_slp");
    5900              : 
    5901      1178419 :   unsigned limit = max_tree_size;
    5902              : 
    5903      1178419 :   scalar_stmts_to_slp_tree_map_t *bst_map
    5904      1178419 :     = new scalar_stmts_to_slp_tree_map_t ();
    5905              : 
    5906              :   /* Find SLP sequences starting from groups of grouped stores.  */
    5907      3292514 :   FOR_EACH_VEC_ELT (vinfo->grouped_stores, i, first_element)
    5908       935802 :     if (! vect_analyze_slp_instance (vinfo, bst_map, first_element,
    5909              :                                      slp_inst_kind_store, max_tree_size, &limit,
    5910              :                                      force_single_lane)
    5911       935802 :         && loop_vinfo)
    5912              :       {
    5913          126 :         release_scalar_stmts_to_slp_tree_map (bst_map);
    5914          126 :         return opt_result::failure_at (vect_location, "SLP build failed.\n");
    5915              :       }
    5916              : 
    5917              :   /* For loops also start SLP discovery from non-grouped stores.  */
    5918      1178293 :   if (loop_vinfo)
    5919              :     {
    5920              :       data_reference_p dr;
    5921      1678416 :       FOR_EACH_VEC_ELT (vinfo->shared->datarefs, i, dr)
    5922      1167124 :         if (DR_IS_WRITE (dr))
    5923              :           {
    5924       378480 :             stmt_vec_info stmt_info = vinfo->lookup_dr (dr)->stmt;
    5925              :             /* Grouped stores are already handled above.  */
    5926       378480 :             if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
    5927       102733 :               continue;
    5928       275747 :             vec<stmt_vec_info> stmts;
    5929       275747 :             vec<stmt_vec_info> roots = vNULL;
    5930       275747 :             vec<tree> remain = vNULL;
    5931       275747 :             stmts.create (1);
    5932       275747 :             stmts.quick_push (stmt_info);
    5933       275747 :             if (! vect_build_slp_instance (vinfo, slp_inst_kind_store,
    5934              :                                            stmts, roots, remain, max_tree_size,
    5935              :                                            &limit, bst_map, force_single_lane))
    5936              :               {
    5937         3559 :                 release_scalar_stmts_to_slp_tree_map (bst_map);
    5938         3559 :                 return opt_result::failure_at (vect_location,
    5939              :                                                "SLP build failed.\n");
    5940              :               }
    5941              :           }
    5942              : 
    5943              :       stmt_vec_info stmt_info;
    5944       511332 :       FOR_EACH_VEC_ELT (LOOP_VINFO_ALTERNATE_DEFS (loop_vinfo), i, stmt_info)
    5945              :         {
    5946           20 :           vec<stmt_vec_info> stmts;
    5947           20 :           vec<stmt_vec_info> roots = vNULL;
    5948           20 :           vec<tree> remain = vNULL;
    5949           20 :           stmts.create (1);
    5950           20 :           stmts.quick_push (stmt_info);
    5951           20 :           if (! vect_build_slp_instance (vinfo, slp_inst_kind_store,
    5952              :                                          stmts, roots, remain, max_tree_size,
    5953              :                                          &limit, bst_map, force_single_lane))
    5954              :             {
    5955            0 :               release_scalar_stmts_to_slp_tree_map (bst_map);
    5956            0 :               return opt_result::failure_at (vect_location,
    5957              :                                              "SLP build failed.\n");
    5958              :             }
    5959              :         }
    5960              :     }
    5961              : 
    5962      1174734 :   if (bb_vec_info bb_vinfo = dyn_cast <bb_vec_info> (vinfo))
    5963              :     {
    5964      2043380 :       for (unsigned i = 0; i < bb_vinfo->roots.length (); ++i)
    5965              :         {
    5966      1379938 :           vect_location = bb_vinfo->roots[i].roots[0]->stmt;
    5967              :           /* Apply patterns.  */
    5968      4521544 :           for (unsigned j = 0; j < bb_vinfo->roots[i].stmts.length (); ++j)
    5969      6283212 :             bb_vinfo->roots[i].stmts[j]
    5970      3235846 :               = vect_stmt_to_vectorize (bb_vinfo->roots[i].stmts[j]);
    5971      1379938 :           if (vect_build_slp_instance (bb_vinfo, bb_vinfo->roots[i].kind,
    5972      1379938 :                                        bb_vinfo->roots[i].stmts,
    5973      1379938 :                                        bb_vinfo->roots[i].roots,
    5974      1379938 :                                        bb_vinfo->roots[i].remain,
    5975              :                                        max_tree_size, &limit, bst_map, false))
    5976              :             {
    5977       154635 :               bb_vinfo->roots[i].roots = vNULL;
    5978       154635 :               bb_vinfo->roots[i].remain = vNULL;
    5979              :             }
    5980      1379938 :           bb_vinfo->roots[i].stmts = vNULL;
    5981              :         }
    5982              :     }
    5983              : 
    5984      1174734 :   if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
    5985              :     {
    5986              :       /* Find SLP sequences starting from groups of reductions.  */
    5987       511292 :       if (!vect_analyze_slp_reductions (loop_vinfo, max_tree_size, &limit,
    5988              :                                         bst_map, force_single_lane))
    5989              :         {
    5990         1900 :           release_scalar_stmts_to_slp_tree_map (bst_map);
    5991         1900 :           return opt_result::failure_at (vect_location, "SLP build failed.\n");
    5992              :         }
    5993              : 
    5994              :       /* Make sure to vectorize only-live stmts, usually inductions.  */
    5995      2294805 :       for (edge e : get_loop_exit_edges (LOOP_VINFO_LOOP (loop_vinfo)))
    5996      1482870 :         for (auto gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi);
    5997       706562 :              gsi_next (&gsi))
    5998              :           {
    5999       716241 :             gphi *lc_phi = *gsi;
    6000       716241 :             tree def = gimple_phi_arg_def_from_edge (lc_phi, e);
    6001       716241 :             stmt_vec_info stmt_info;
    6002       716241 :             if (TREE_CODE (def) == SSA_NAME
    6003       601364 :                 && !virtual_operand_p (def)
    6004       308250 :                 && (stmt_info = loop_vinfo->lookup_def (def))
    6005       276513 :                 && ((stmt_info = vect_stmt_to_vectorize (stmt_info)), true)
    6006       276513 :                 && STMT_VINFO_RELEVANT (stmt_info) == vect_used_only_live
    6007       215538 :                 && STMT_VINFO_LIVE_P (stmt_info)
    6008       215538 :                 && !VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))
    6009       827781 :                 && STMT_VINFO_REDUC_IDX (stmt_info) == -1)
    6010              :               {
    6011       111452 :                 vec<stmt_vec_info> stmts;
    6012       111452 :                 vec<stmt_vec_info> roots = vNULL;
    6013       111452 :                 vec<tree> remain = vNULL;
    6014       111452 :                 stmts.create (1);
    6015       111452 :                 stmts.quick_push (vect_stmt_to_vectorize (stmt_info));
    6016       111452 :                 if (! vect_build_slp_instance (vinfo,
    6017              :                                                slp_inst_kind_reduc_group,
    6018              :                                                stmts, roots, remain,
    6019              :                                                max_tree_size, &limit,
    6020              :                                                bst_map, force_single_lane))
    6021              :                   {
    6022         9679 :                     release_scalar_stmts_to_slp_tree_map (bst_map);
    6023         9679 :                     return opt_result::failure_at (vect_location,
    6024              :                                                    "SLP build failed.\n");
    6025              :                   }
    6026              :               }
    6027         9679 :           }
    6028              : 
    6029              :       /* Find SLP sequences starting from gconds.  */
    6030      1249946 :       for (auto cond : LOOP_VINFO_LOOP_CONDS (loop_vinfo))
    6031              :         {
    6032       291793 :           auto cond_info = loop_vinfo->lookup_stmt (cond);
    6033              : 
    6034       291793 :           cond_info = vect_stmt_to_vectorize (cond_info);
    6035       291793 :           vec<stmt_vec_info> roots = vNULL;
    6036       291793 :           roots.safe_push (cond_info);
    6037       291793 :           gimple *stmt = STMT_VINFO_STMT (cond_info);
    6038       291793 :           tree args0 = gimple_cond_lhs (stmt);
    6039       291793 :           tree args1 = gimple_cond_rhs (stmt);
    6040              : 
    6041              :           /* These should be enforced by cond lowering, but if it failed
    6042              :              bail.  */
    6043       291793 :           if (gimple_cond_code (stmt) != NE_EXPR
    6044       290653 :               || TREE_TYPE (args0) != boolean_type_node
    6045       581870 :               || !integer_zerop (args1))
    6046              :             {
    6047         1716 :               roots.release ();
    6048         1716 :               release_scalar_stmts_to_slp_tree_map (bst_map);
    6049         1716 :               return opt_result::failure_at (vect_location,
    6050              :                                              "SLP build failed.\n");
    6051              :             }
    6052              : 
    6053              :           /* An argument without a loop def will be codegened from vectorizing the
    6054              :              root gcond itself.  As such we don't need to try to build an SLP tree
    6055              :              from them.  It's highly likely that the resulting SLP tree here if both
    6056              :              arguments have a def will be incompatible, but we rely on it being split
    6057              :              later on.  */
    6058       290077 :           auto varg = loop_vinfo->lookup_def (args0);
    6059       290077 :           vec<stmt_vec_info> stmts;
    6060       290077 :           vec<tree> remain = vNULL;
    6061       290077 :           stmts.create (1);
    6062       290077 :           stmts.quick_push (vect_stmt_to_vectorize (varg));
    6063              : 
    6064       290077 :           if (! vect_build_slp_instance (vinfo, slp_inst_kind_gcond,
    6065              :                                          stmts, roots, remain,
    6066              :                                          max_tree_size, &limit,
    6067              :                                          bst_map, force_single_lane))
    6068              :             {
    6069          898 :               roots.release ();
    6070          898 :               release_scalar_stmts_to_slp_tree_map (bst_map);
    6071          898 :               return opt_result::failure_at (vect_location,
    6072              :                                              "SLP build failed.\n");
    6073              :             }
    6074              :         }
    6075              :     }
    6076              : 
    6077      1160541 :   hash_set<slp_tree> visited_patterns;
    6078      1160541 :   slp_tree_to_load_perm_map_t perm_cache;
    6079      1160541 :   slp_compat_nodes_map_t compat_cache;
    6080              : 
    6081              :   /* See if any patterns can be found in the SLP tree.  */
    6082      1160541 :   bool pattern_found = false;
    6083      3939111 :   FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (vinfo), i, instance)
    6084      1618029 :     pattern_found |= vect_match_slp_patterns (instance, vinfo,
    6085              :                                               &visited_patterns, &perm_cache,
    6086              :                                               &compat_cache);
    6087              : 
    6088              :   /* If any were found optimize permutations of loads.  */
    6089      1160541 :   if (pattern_found)
    6090              :     {
    6091          265 :       hash_map<slp_tree, slp_tree> load_map;
    6092         4705 :       FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (vinfo), i, instance)
    6093              :         {
    6094         4175 :           slp_tree root = SLP_INSTANCE_TREE (instance);
    6095         4175 :           optimize_load_redistribution (bst_map, vinfo, SLP_TREE_LANES (root),
    6096              :                                         &load_map, root);
    6097              :         }
    6098          265 :     }
    6099              : 
    6100              :   /* Check whether we should force some SLP instances to use load/store-lanes
    6101              :      and do so by forcing SLP re-discovery with single lanes.  We used
    6102              :      to cancel SLP when this applied to all instances in a loop but now
    6103              :      we decide this per SLP instance.  It's important to do this only
    6104              :      after SLP pattern recognition.  */
    6105      1160541 :   if (is_a <loop_vec_info> (vinfo))
    6106      1289185 :     FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (vinfo), i, instance)
    6107       792086 :       if (SLP_INSTANCE_KIND (instance) == slp_inst_kind_store
    6108       300767 :           && !SLP_INSTANCE_TREE (instance)->ldst_lanes)
    6109              :         {
    6110       300767 :           slp_tree slp_root = SLP_INSTANCE_TREE (instance);
    6111       300767 :           unsigned int group_size = SLP_TREE_LANES (slp_root);
    6112       300767 :           tree vectype = SLP_TREE_VECTYPE (slp_root);
    6113              : 
    6114       300767 :           stmt_vec_info rep_info = SLP_TREE_REPRESENTATIVE (slp_root);
    6115       300767 :           gimple *rep = STMT_VINFO_STMT (rep_info);
    6116       300767 :           bool masked = (is_gimple_call (rep)
    6117         2446 :                          && gimple_call_internal_p (rep)
    6118       303193 :                          && internal_fn_mask_index
    6119         2426 :                               (gimple_call_internal_fn (rep)) != -1);
    6120       300747 :           if (!STMT_VINFO_GROUPED_ACCESS (rep_info)
    6121        30000 :               || slp_root->ldst_lanes
    6122       330767 :               || (vect_store_lanes_supported (vectype, group_size, masked)
    6123              :                   == IFN_LAST))
    6124       300767 :             continue;
    6125              : 
    6126            0 :           auto_vec<slp_tree> loads;
    6127            0 :           hash_set<slp_tree> visited;
    6128            0 :           vect_gather_slp_loads (loads, slp_root, visited);
    6129              : 
    6130              :           /* Check whether any load in the SLP instance is possibly
    6131              :              permuted.  */
    6132            0 :           bool loads_permuted = false;
    6133            0 :           slp_tree load_node;
    6134            0 :           unsigned j;
    6135            0 :           FOR_EACH_VEC_ELT (loads, j, load_node)
    6136              :             {
    6137            0 :               if (!SLP_TREE_LOAD_PERMUTATION (load_node).exists ())
    6138            0 :                 continue;
    6139            0 :               for (unsigned k = 0; k < SLP_TREE_LANES (load_node); k++)
    6140            0 :                 if (SLP_TREE_LOAD_PERMUTATION (load_node)[k] != k)
    6141              :                   {
    6142              :                     loads_permuted = true;
    6143              :                     break;
    6144              :                   }
    6145              :             }
    6146              : 
    6147              :           /* If the loads and stores can use load/store-lanes force re-discovery
    6148              :              with single lanes.  */
    6149            0 :           if (loads_permuted)
    6150              :             {
    6151            0 :               bool can_use_lanes = true;
    6152              :               bool prefer_load_lanes = false;
    6153            0 :               FOR_EACH_VEC_ELT (loads, j, load_node)
    6154            0 :                 if (STMT_VINFO_GROUPED_ACCESS
    6155              :                       (SLP_TREE_REPRESENTATIVE (load_node)))
    6156              :                   {
    6157            0 :                     stmt_vec_info stmt_vinfo = DR_GROUP_FIRST_ELEMENT
    6158              :                         (SLP_TREE_REPRESENTATIVE (load_node));
    6159            0 :                     rep = STMT_VINFO_STMT (stmt_vinfo);
    6160            0 :                     masked = (is_gimple_call (rep)
    6161            0 :                               && gimple_call_internal_p (rep)
    6162            0 :                               && internal_fn_mask_index
    6163            0 :                                    (gimple_call_internal_fn (rep)));
    6164              :                     /* Use SLP for strided accesses (or if we can't
    6165              :                        load-lanes).  */
    6166            0 :                     if (STMT_VINFO_STRIDED_P (stmt_vinfo)
    6167            0 :                         || compare_step_with_zero (vinfo, stmt_vinfo) <= 0
    6168            0 :                         || vect_load_lanes_supported
    6169            0 :                              (SLP_TREE_VECTYPE (load_node),
    6170            0 :                               DR_GROUP_SIZE (stmt_vinfo), masked) == IFN_LAST
    6171              :                         /* ???  During SLP re-discovery with a single lane
    6172              :                            a masked grouped load will appear permuted and
    6173              :                            discovery will fail.  We have to rework this
    6174              :                            on the discovery side - for now avoid ICEing.  */
    6175            0 :                         || masked)
    6176              :                       {
    6177              :                         can_use_lanes = false;
    6178              :                         break;
    6179              :                       }
    6180              :                     /* Make sure that the target would prefer store-lanes
    6181              :                        for at least one of the loads.
    6182              : 
    6183              :                        ??? Perhaps we should instead require this for
    6184              :                        all loads?  */
    6185            0 :                     prefer_load_lanes
    6186              :                       = (prefer_load_lanes
    6187            0 :                          || SLP_TREE_LANES (load_node) == group_size
    6188            0 :                          || (vect_slp_prefer_store_lanes_p
    6189            0 :                              (vinfo, stmt_vinfo,
    6190              :                               SLP_TREE_VECTYPE (load_node), masked,
    6191              :                               group_size, SLP_TREE_LANES (load_node))));
    6192              :                   }
    6193              : 
    6194            0 :               if (can_use_lanes && prefer_load_lanes)
    6195              :                 {
    6196            0 :                   if (dump_enabled_p ())
    6197            0 :                     dump_printf_loc (MSG_NOTE, vect_location,
    6198              :                                      "SLP instance %p can use load/store-lanes,"
    6199              :                                      " re-discovering with single-lanes\n",
    6200              :                                      (void *) instance);
    6201              : 
    6202            0 :                   stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (slp_root);
    6203              : 
    6204            0 :                   vect_free_slp_instance (instance);
    6205            0 :                   limit = max_tree_size;
    6206            0 :                   bool res = vect_analyze_slp_instance (vinfo, bst_map,
    6207              :                                                         stmt_info,
    6208              :                                                         slp_inst_kind_store,
    6209              :                                                         max_tree_size, &limit,
    6210              :                                                         true);
    6211            0 :                   gcc_assert (res);
    6212            0 :                   auto new_inst = LOOP_VINFO_SLP_INSTANCES (vinfo).pop ();
    6213            0 :                   LOOP_VINFO_SLP_INSTANCES (vinfo)[i] = new_inst;
    6214              :                 }
    6215              :             }
    6216            0 :         }
    6217              : 
    6218              :   /* When we end up with load permutations that we cannot possibly handle,
    6219              :      like those requiring three vector inputs, lower them using interleaving
    6220              :      like schemes.  */
    6221      1160541 :   if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
    6222              :     {
    6223       497099 :       vect_lower_load_permutations (loop_vinfo, bst_map, force_single_lane);
    6224       497099 :       if (dump_enabled_p ())
    6225              :         {
    6226        20590 :           dump_printf_loc (MSG_NOTE, vect_location,
    6227              :                            "SLP graph after lowering permutations:\n");
    6228        20590 :           hash_set<slp_tree> visited;
    6229        91611 :           FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (vinfo), i, instance)
    6230        29866 :             vect_print_slp_graph (MSG_NOTE, vect_location,
    6231              :                                   SLP_INSTANCE_TREE (instance), visited);
    6232        20590 :         }
    6233              :     }
    6234              : 
    6235      1160541 :   release_scalar_stmts_to_slp_tree_map (bst_map);
    6236              : 
    6237      1160541 :   if (pattern_found && dump_enabled_p ())
    6238              :     {
    6239           18 :       dump_printf_loc (MSG_NOTE, vect_location,
    6240              :                        "Pattern matched SLP tree\n");
    6241           18 :       hash_set<slp_tree> visited;
    6242           91 :       FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (vinfo), i, instance)
    6243           37 :         vect_print_slp_graph (MSG_NOTE, vect_location,
    6244              :                               SLP_INSTANCE_TREE (instance), visited);
    6245           18 :     }
    6246              : 
    6247      1160541 :   return opt_result::success ();
    6248      1160541 : }
    6249              : 
    6250              : /* Estimates the cost of inserting layout changes into the SLP graph.
    6251              :    It can also say that the insertion is impossible.  */
    6252              : 
    6253              : struct slpg_layout_cost
    6254              : {
    6255     11181218 :   slpg_layout_cost () = default;
    6256              :   slpg_layout_cost (sreal, bool);
    6257              : 
    6258       535279 :   static slpg_layout_cost impossible () { return { sreal::max (), 0 }; }
    6259      5706051 :   bool is_possible () const { return depth != sreal::max (); }
    6260              : 
    6261              :   bool operator== (const slpg_layout_cost &) const;
    6262              :   bool operator!= (const slpg_layout_cost &) const;
    6263              : 
    6264              :   bool is_better_than (const slpg_layout_cost &, bool) const;
    6265              : 
    6266              :   void add_parallel_cost (const slpg_layout_cost &);
    6267              :   void add_serial_cost (const slpg_layout_cost &);
    6268              :   void split (unsigned int);
    6269              : 
    6270              :   /* The longest sequence of layout changes needed during any traversal
    6271              :      of the partition dag, weighted by execution frequency.
    6272              : 
    6273              :      This is the most important metric when optimizing for speed, since
    6274              :      it helps to ensure that we keep the number of operations on
    6275              :      critical paths to a minimum.  */
    6276              :   sreal depth = 0;
    6277              : 
    6278              :   /* An estimate of the total number of operations needed.  It is weighted by
    6279              :      execution frequency when optimizing for speed but not when optimizing for
    6280              :      size.  In order to avoid double-counting, a node with a fanout of N will
    6281              :      distribute 1/N of its total cost to each successor.
    6282              : 
    6283              :      This is the most important metric when optimizing for size, since
    6284              :      it helps to keep the total number of operations to a minimum,  */
    6285              :   sreal total = 0;
    6286              : };
    6287              : 
    6288              : /* Construct costs for a node with weight WEIGHT.  A higher weight
    6289              :    indicates more frequent execution.  IS_FOR_SIZE is true if we are
    6290              :    optimizing for size rather than speed.  */
    6291              : 
    6292      1345231 : slpg_layout_cost::slpg_layout_cost (sreal weight, bool is_for_size)
    6293      1346350 :   : depth (weight), total (is_for_size && weight > 0 ? 1 : weight)
    6294              : {
    6295      1345231 : }
    6296              : 
    6297              : bool
    6298            0 : slpg_layout_cost::operator== (const slpg_layout_cost &other) const
    6299              : {
    6300            0 :   return depth == other.depth && total == other.total;
    6301              : }
    6302              : 
    6303              : bool
    6304            0 : slpg_layout_cost::operator!= (const slpg_layout_cost &other) const
    6305              : {
    6306            0 :   return !operator== (other);
    6307              : }
    6308              : 
    6309              : /* Return true if these costs are better than OTHER.  IS_FOR_SIZE is
    6310              :    true if we are optimizing for size rather than speed.  */
    6311              : 
    6312              : bool
    6313       326727 : slpg_layout_cost::is_better_than (const slpg_layout_cost &other,
    6314              :                                   bool is_for_size) const
    6315              : {
    6316       326727 :   if (is_for_size)
    6317              :     {
    6318          528 :       if (total != other.total)
    6319          236 :         return total < other.total;
    6320          292 :       return depth < other.depth;
    6321              :     }
    6322              :   else
    6323              :     {
    6324       326199 :       if (depth != other.depth)
    6325       134573 :         return depth < other.depth;
    6326       191626 :       return total < other.total;
    6327              :     }
    6328              : }
    6329              : 
    6330              : /* Increase the costs to account for something with cost INPUT_COST
    6331              :    happening in parallel with the current costs.  */
    6332              : 
    6333              : void
    6334       389894 : slpg_layout_cost::add_parallel_cost (const slpg_layout_cost &input_cost)
    6335              : {
    6336       389894 :   depth = std::max (depth, input_cost.depth);
    6337       389894 :   total += input_cost.total;
    6338       389894 : }
    6339              : 
    6340              : /* Increase the costs to account for something with cost INPUT_COST
    6341              :    happening in series with the current costs.  */
    6342              : 
    6343              : void
    6344      1600819 : slpg_layout_cost::add_serial_cost (const slpg_layout_cost &other)
    6345              : {
    6346      1600819 :   depth += other.depth;
    6347      1600819 :   total += other.total;
    6348      1600819 : }
    6349              : 
    6350              : /* Split the total cost among TIMES successors or predecessors.  */
    6351              : 
    6352              : void
    6353      1299260 : slpg_layout_cost::split (unsigned int times)
    6354              : {
    6355      1299260 :   if (times > 1)
    6356       607052 :     total /= times;
    6357      1299260 : }
    6358              : 
    6359              : /* Information about one node in the SLP graph, for use during
    6360              :    vect_optimize_slp_pass.  */
    6361              : 
    6362              : struct slpg_vertex
    6363              : {
    6364     10449829 :   slpg_vertex (slp_tree node_) : node (node_) {}
    6365              : 
    6366              :   /* The node itself.  */
    6367              :   slp_tree node;
    6368              : 
    6369              :   /* Which partition the node belongs to, or -1 if none.  Nodes outside of
    6370              :      partitions are flexible; they can have whichever layout consumers
    6371              :      want them to have.  */
    6372              :   int partition = -1;
    6373              : 
    6374              :   /* The number of nodes that directly use the result of this one
    6375              :      (i.e. the number of nodes that count this one as a child).  */
    6376              :   unsigned int out_degree = 0;
    6377              : 
    6378              :   /* The execution frequency of the node.  */
    6379              :   sreal weight = 0;
    6380              : 
    6381              :   /* The total execution frequency of all nodes that directly use the
    6382              :      result of this one.  */
    6383              :   sreal out_weight = 0;
    6384              : };
    6385              : 
    6386              : /* Information about one partition of the SLP graph, for use during
    6387              :    vect_optimize_slp_pass.  */
    6388              : 
    6389              : struct slpg_partition_info
    6390              : {
    6391              :   /* The nodes in the partition occupy indices [NODE_BEGIN, NODE_END)
    6392              :      of m_partitioned_nodes.  */
    6393              :   unsigned int node_begin = 0;
    6394              :   unsigned int node_end = 0;
    6395              : 
    6396              :   /* Which layout we've chosen to use for this partition, or -1 if
    6397              :      we haven't picked one yet.  */
    6398              :   int layout = -1;
    6399              : 
    6400              :   /* The number of predecessors and successors in the partition dag.
    6401              :      The predecessors always have lower partition numbers and the
    6402              :      successors always have higher partition numbers.
    6403              : 
    6404              :      Note that the directions of these edges are not necessarily the
    6405              :      same as in the data flow graph.  For example, if an SCC has separate
    6406              :      partitions for an inner loop and an outer loop, the inner loop's
    6407              :      partition will have at least two incoming edges from the outer loop's
    6408              :      partition: one for a live-in value and one for a live-out value.
    6409              :      In data flow terms, one of these edges would also be from the outer loop
    6410              :      to the inner loop, but the other would be in the opposite direction.  */
    6411              :   unsigned int in_degree = 0;
    6412              :   unsigned int out_degree = 0;
    6413              : };
    6414              : 
    6415              : /* Information about the costs of using a particular layout for a
    6416              :    particular partition.  It can also say that the combination is
    6417              :    impossible.  */
    6418              : 
    6419              : struct slpg_partition_layout_costs
    6420              : {
    6421      1669832 :   bool is_possible () const { return internal_cost.is_possible (); }
    6422        67581 :   void mark_impossible () { internal_cost = slpg_layout_cost::impossible (); }
    6423              : 
    6424              :   /* The costs inherited from predecessor partitions.  */
    6425              :   slpg_layout_cost in_cost;
    6426              : 
    6427              :   /* The inherent cost of the layout within the node itself.  For example,
    6428              :      this is nonzero for a load if choosing a particular layout would require
    6429              :      the load to permute the loaded elements.  It is nonzero for a
    6430              :      VEC_PERM_EXPR if the permutation cannot be eliminated or converted
    6431              :      to full-vector moves.  */
    6432              :   slpg_layout_cost internal_cost;
    6433              : 
    6434              :   /* The costs inherited from successor partitions.  */
    6435              :   slpg_layout_cost out_cost;
    6436              : };
    6437              : 
    6438              : /* This class tries to optimize the layout of vectors in order to avoid
    6439              :    unnecessary shuffling.  At the moment, the set of possible layouts are
    6440              :    restricted to bijective permutations.
    6441              : 
    6442              :    The goal of the pass depends on whether we're optimizing for size or
    6443              :    for speed.  When optimizing for size, the goal is to reduce the overall
    6444              :    number of layout changes (including layout changes implied by things
    6445              :    like load permutations).  When optimizing for speed, the goal is to
    6446              :    reduce the maximum latency attributable to layout changes on any
    6447              :    non-cyclical path through the data flow graph.
    6448              : 
    6449              :    For example, when optimizing a loop nest for speed, we will prefer
    6450              :    to make layout changes outside of a loop rather than inside of a loop,
    6451              :    and will prefer to make layout changes in parallel rather than serially,
    6452              :    even if that increases the overall number of layout changes.
    6453              : 
    6454              :    The high-level procedure is:
    6455              : 
    6456              :    (1) Build a graph in which edges go from uses (parents) to definitions
    6457              :        (children).
    6458              : 
    6459              :    (2) Divide the graph into a dag of strongly-connected components (SCCs).
    6460              : 
    6461              :    (3) When optimizing for speed, partition the nodes in each SCC based
    6462              :        on their containing cfg loop.  When optimizing for size, treat
    6463              :        each SCC as a single partition.
    6464              : 
    6465              :        This gives us a dag of partitions.  The goal is now to assign a
    6466              :        layout to each partition.
    6467              : 
    6468              :    (4) Construct a set of vector layouts that are worth considering.
    6469              :        Record which nodes must keep their current layout.
    6470              : 
    6471              :    (5) Perform a forward walk over the partition dag (from loads to stores)
    6472              :        accumulating the "forward" cost of using each layout.  When visiting
    6473              :        each partition, assign a tentative choice of layout to the partition
    6474              :        and use that choice when calculating the cost of using a different
    6475              :        layout in successor partitions.
    6476              : 
    6477              :    (6) Perform a backward walk over the partition dag (from stores to loads),
    6478              :        accumulating the "backward" cost of using each layout.  When visiting
    6479              :        each partition, make a final choice of layout for that partition based
    6480              :        on the accumulated forward costs (from (5)) and backward costs
    6481              :        (from (6)).
    6482              : 
    6483              :    (7) Apply the chosen layouts to the SLP graph.
    6484              : 
    6485              :    For example, consider the SLP statements:
    6486              : 
    6487              :    S1:      a_1 = load
    6488              :        loop:
    6489              :    S2:      a_2 = PHI<a_1, a_3>
    6490              :    S3:      b_1 = load
    6491              :    S4:      a_3 = a_2 + b_1
    6492              :        exit:
    6493              :    S5:      a_4 = PHI<a_3>
    6494              :    S6:      store a_4
    6495              : 
    6496              :    S2 and S4 form an SCC and are part of the same loop.  Every other
    6497              :    statement is in a singleton SCC.  In this example there is a one-to-one
    6498              :    mapping between SCCs and partitions and the partition dag looks like this;
    6499              : 
    6500              :         S1     S3
    6501              :          \     /
    6502              :           S2+S4
    6503              :             |
    6504              :            S5
    6505              :             |
    6506              :            S6
    6507              : 
    6508              :    S2, S3 and S4 will have a higher execution frequency than the other
    6509              :    statements, so when optimizing for speed, the goal is to avoid any
    6510              :    layout changes:
    6511              : 
    6512              :    - within S3
    6513              :    - within S2+S4
    6514              :    - on the S3->S2+S4 edge
    6515              : 
    6516              :    For example, if S3 was originally a reversing load, the goal of the
    6517              :    pass is to make it an unreversed load and change the layout on the
    6518              :    S1->S2+S4 and S2+S4->S5 edges to compensate.  (Changing the layout
    6519              :    on S1->S2+S4 and S5->S6 would also be acceptable.)
    6520              : 
    6521              :    The difference between SCCs and partitions becomes important if we
    6522              :    add an outer loop:
    6523              : 
    6524              :    S1:      a_1 = ...
    6525              :        loop1:
    6526              :    S2:      a_2 = PHI<a_1, a_6>
    6527              :    S3:      b_1 = load
    6528              :    S4:      a_3 = a_2 + b_1
    6529              :        loop2:
    6530              :    S5:      a_4 = PHI<a_3, a_5>
    6531              :    S6:      c_1 = load
    6532              :    S7:      a_5 = a_4 + c_1
    6533              :        exit2:
    6534              :    S8:      a_6 = PHI<a_5>
    6535              :    S9:      store a_6
    6536              :        exit1:
    6537              : 
    6538              :    Here, S2, S4, S5, S7 and S8 form a single SCC.  However, when optimizing
    6539              :    for speed, we usually do not want restrictions in the outer loop to "infect"
    6540              :    the decision for the inner loop.  For example, if an outer-loop node
    6541              :    in the SCC contains a statement with a fixed layout, that should not
    6542              :    prevent the inner loop from using a different layout.  Conversely,
    6543              :    the inner loop should not dictate a layout to the outer loop: if the
    6544              :    outer loop does a lot of computation, then it may not be efficient to
    6545              :    do all of that computation in the inner loop's preferred layout.
    6546              : 
    6547              :    So when optimizing for speed, we partition the SCC into S2+S4+S8 (outer)
    6548              :    and S5+S7 (inner).  We also try to arrange partitions so that:
    6549              : 
    6550              :    - the partition for an outer loop comes before the partition for
    6551              :      an inner loop
    6552              : 
    6553              :    - if a sibling loop A dominates a sibling loop B, A's partition
    6554              :      comes before B's
    6555              : 
    6556              :    This gives the following partition dag for the example above:
    6557              : 
    6558              :         S1        S3
    6559              :          \        /
    6560              :           S2+S4+S8   S6
    6561              :            |   \\    /
    6562              :            |    S5+S7
    6563              :            |
    6564              :           S9
    6565              : 
    6566              :    There are two edges from S2+S4+S8 to S5+S7: one for the edge S4->S5 and
    6567              :    one for a reversal of the edge S7->S8.
    6568              : 
    6569              :    The backward walk picks a layout for S5+S7 before S2+S4+S8.  The choice
    6570              :    for S2+S4+S8 therefore has to balance the cost of using the outer loop's
    6571              :    preferred layout against the cost of changing the layout on entry to the
    6572              :    inner loop (S4->S5) and on exit from the inner loop (S7->S8 reversed).
    6573              : 
    6574              :    Although this works well when optimizing for speed, it has the downside
    6575              :    when optimizing for size that the choice of layout for S5+S7 is completely
    6576              :    independent of S9, which lessens the chance of reducing the overall number
    6577              :    of permutations.  We therefore do not partition SCCs when optimizing
    6578              :    for size.
    6579              : 
    6580              :    To give a concrete example of the difference between optimizing
    6581              :    for size and speed, consider:
    6582              : 
    6583              :    a[0] = (b[1] << c[3]) - d[1];
    6584              :    a[1] = (b[0] << c[2]) - d[0];
    6585              :    a[2] = (b[3] << c[1]) - d[3];
    6586              :    a[3] = (b[2] << c[0]) - d[2];
    6587              : 
    6588              :    There are three different layouts here: one for a, one for b and d,
    6589              :    and one for c.  When optimizing for speed it is better to permute each
    6590              :    of b, c and d into the order required by a, since those permutations
    6591              :    happen in parallel.  But when optimizing for size, it is better to:
    6592              : 
    6593              :    - permute c into the same order as b
    6594              :    - do the arithmetic
    6595              :    - permute the result into the order required by a
    6596              : 
    6597              :    This gives 2 permutations rather than 3.  */
    6598              : 
    6599              : class vect_optimize_slp_pass
    6600              : {
    6601              : public:
    6602       709983 :   vect_optimize_slp_pass (vec_info *vinfo) : m_vinfo (vinfo) {}
    6603              :   void run ();
    6604              : 
    6605              : private:
    6606              :   /* Graph building.  */
    6607              :   struct loop *containing_loop (slp_tree);
    6608              :   bool is_cfg_latch_edge (graph_edge *);
    6609              :   void build_vertices (hash_set<slp_tree> &, slp_tree);
    6610              :   void build_vertices ();
    6611              :   void build_graph ();
    6612              : 
    6613              :   /* Partitioning.  */
    6614              :   void create_partitions ();
    6615              :   template<typename T> void for_each_partition_edge (unsigned int, T);
    6616              : 
    6617              :   /* Layout selection.  */
    6618              :   bool is_compatible_layout (slp_tree, unsigned int);
    6619              :   bool is_compatible_layout (const slpg_partition_info &, unsigned int);
    6620              :   int change_layout_cost (slp_tree, unsigned int, unsigned int);
    6621              :   slpg_partition_layout_costs &partition_layout_costs (unsigned int,
    6622              :                                                        unsigned int);
    6623              :   void change_vec_perm_layout (slp_tree, lane_permutation_t &,
    6624              :                                int, unsigned int);
    6625              :   int internal_node_cost (slp_tree, int, unsigned int);
    6626              :   void start_choosing_layouts ();
    6627              :   bool legitimize ();
    6628              : 
    6629              :   /* Cost propagation.  */
    6630              :   slpg_layout_cost edge_layout_cost (graph_edge *, unsigned int,
    6631              :                                      unsigned int, unsigned int);
    6632              :   slpg_layout_cost total_in_cost (unsigned int);
    6633              :   slpg_layout_cost forward_cost (graph_edge *, unsigned int, unsigned int);
    6634              :   slpg_layout_cost backward_cost (graph_edge *, unsigned int, unsigned int);
    6635              :   void forward_pass ();
    6636              :   void backward_pass ();
    6637              : 
    6638              :   /* Rematerialization.  */
    6639              :   slp_tree get_result_with_layout (slp_tree, unsigned int);
    6640              :   void materialize ();
    6641              : 
    6642              :   /* Clean-up.  */
    6643              :   void remove_redundant_permutations ();
    6644              : 
    6645              :   /* Masked load lanes discovery.  */
    6646              :   void decide_masked_load_lanes ();
    6647              : 
    6648              :   void dump ();
    6649              : 
    6650              :   vec_info *m_vinfo;
    6651              : 
    6652              :   /* True if we should optimize the graph for size, false if we should
    6653              :      optimize it for speed.  (It wouldn't be easy to make this decision
    6654              :      more locally.)  */
    6655              :   bool m_optimize_size;
    6656              : 
    6657              :   /* A graph of all SLP nodes, with edges leading from uses to definitions.
    6658              :      In other words, a node's predecessors are its slp_tree parents and
    6659              :      a node's successors are its slp_tree children.  */
    6660              :   graph *m_slpg = nullptr;
    6661              : 
    6662              :   /* The vertices of M_SLPG, indexed by slp_tree::vertex.  */
    6663              :   auto_vec<slpg_vertex> m_vertices;
    6664              : 
    6665              :   /* The list of all leaves of M_SLPG. such as external definitions, constants,
    6666              :      and loads.  */
    6667              :   auto_vec<int> m_leafs;
    6668              : 
    6669              :   /* This array has one entry for every vector layout that we're considering.
    6670              :      Element 0 is null and indicates "no change".  Other entries describe
    6671              :      permutations that are inherent in the current graph and that we would
    6672              :      like to reverse if possible.
    6673              : 
    6674              :      For example, a permutation { 1, 2, 3, 0 } means that something has
    6675              :      effectively been permuted in that way, such as a load group
    6676              :      { a[1], a[2], a[3], a[0] } (viewed as a permutation of a[0:3]).
    6677              :      We'd then like to apply the reverse permutation { 3, 0, 1, 2 }
    6678              :      in order to put things "back" in order.  */
    6679              :   auto_vec<vec<unsigned> > m_perms;
    6680              : 
    6681              :   /* A partitioning of the nodes for which a layout must be chosen.
    6682              :      Each partition represents an <SCC, cfg loop> pair; that is,
    6683              :      nodes in different SCCs belong to different partitions, and nodes
    6684              :      within an SCC can be further partitioned according to a containing
    6685              :      cfg loop.  Partition <SCC1, L1> comes before <SCC2, L2> if:
    6686              : 
    6687              :      - SCC1 != SCC2 and SCC1 is a predecessor of SCC2 in a forward walk
    6688              :        from leaves (such as loads) to roots (such as stores).
    6689              : 
    6690              :      - SCC1 == SCC2 and L1's header strictly dominates L2's header.  */
    6691              :   auto_vec<slpg_partition_info> m_partitions;
    6692              : 
    6693              :   /* The list of all nodes for which a layout must be chosen.  Nodes for
    6694              :      partition P come before the nodes for partition P+1.  Nodes within a
    6695              :      partition are in reverse postorder.  */
    6696              :   auto_vec<unsigned int> m_partitioned_nodes;
    6697              : 
    6698              :   /* Index P * num-layouts + L contains the cost of using layout L
    6699              :      for partition P.  */
    6700              :   auto_vec<slpg_partition_layout_costs> m_partition_layout_costs;
    6701              : 
    6702              :   /* Index N * num-layouts + L, if nonnull, is a node that provides the
    6703              :      original output of node N adjusted to have layout L.  */
    6704              :   auto_vec<slp_tree> m_node_layouts;
    6705              : };
    6706              : 
    6707              : /* Fill the vertices and leafs vector with all nodes in the SLP graph.
    6708              :    Also record whether we should optimize anything for speed rather
    6709              :    than size.  */
    6710              : 
    6711              : void
    6712     11290499 : vect_optimize_slp_pass::build_vertices (hash_set<slp_tree> &visited,
    6713              :                                         slp_tree node)
    6714              : {
    6715     11290499 :   unsigned i;
    6716     11290499 :   slp_tree child;
    6717              : 
    6718     11290499 :   if (visited.add (node))
    6719     11290499 :     return;
    6720              : 
    6721     10449829 :   if (stmt_vec_info rep = SLP_TREE_REPRESENTATIVE (node))
    6722              :     {
    6723      8253048 :       basic_block bb = gimple_bb (vect_orig_stmt (rep)->stmt);
    6724      7312102 :       if (optimize_bb_for_speed_p (bb))
    6725      7181954 :         m_optimize_size = false;
    6726              :     }
    6727              : 
    6728     10449829 :   node->vertex = m_vertices.length ();
    6729     10449829 :   m_vertices.safe_push (slpg_vertex (node));
    6730              : 
    6731     10449829 :   bool leaf = true;
    6732     10449829 :   bool force_leaf = false;
    6733     19599890 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    6734      9150061 :     if (child)
    6735              :       {
    6736      8239777 :         leaf = false;
    6737      8239777 :         build_vertices (visited, child);
    6738              :       }
    6739              :     else
    6740              :       force_leaf = true;
    6741              :   /* Since SLP discovery works along use-def edges all cycles have an
    6742              :      entry - but there's the exception of cycles where we do not handle
    6743              :      the entry explicitly (but with a NULL SLP node), like some reductions
    6744              :      and inductions.  Force those SLP PHIs to act as leafs to make them
    6745              :      backwards reachable.  */
    6746     10449829 :   if (leaf || force_leaf)
    6747      5175264 :     m_leafs.safe_push (node->vertex);
    6748              : }
    6749              : 
    6750              : /* Fill the vertices and leafs vector with all nodes in the SLP graph.  */
    6751              : 
    6752              : void
    6753      1419966 : vect_optimize_slp_pass::build_vertices ()
    6754              : {
    6755      1419966 :   hash_set<slp_tree> visited;
    6756      1419966 :   unsigned i;
    6757      1419966 :   slp_instance instance;
    6758      1419966 :   m_vertices.truncate (0);
    6759      1419966 :   m_leafs.truncate (0);
    6760      7310620 :   FOR_EACH_VEC_ELT (m_vinfo->slp_instances, i, instance)
    6761      3050722 :     build_vertices (visited, SLP_INSTANCE_TREE (instance));
    6762      1419966 : }
    6763              : 
    6764              : /* Apply (reverse) bijectite PERM to VEC.  */
    6765              : 
    6766              : template <class T>
    6767              : static void
    6768       226657 : vect_slp_permute (vec<unsigned> perm,
    6769              :                   vec<T> &vec, bool reverse)
    6770              : {
    6771       226657 :   auto_vec<T, 64> saved;
    6772       226657 :   saved.create (vec.length ());
    6773       755853 :   for (unsigned i = 0; i < vec.length (); ++i)
    6774       529196 :     saved.quick_push (vec[i]);
    6775              : 
    6776       226657 :   if (reverse)
    6777              :     {
    6778      1495825 :       for (unsigned i = 0; i < vec.length (); ++i)
    6779       527236 :         vec[perm[i]] = saved[i];
    6780       752993 :       for (unsigned i = 0; i < vec.length (); ++i)
    6781       907885 :         gcc_assert (vec[perm[i]] == saved[i]);
    6782              :     }
    6783              :   else
    6784              :     {
    6785         5720 :       for (unsigned i = 0; i < vec.length (); ++i)
    6786         1960 :         vec[i] = saved[perm[i]];
    6787       228617 :       for (unsigned i = 0; i < vec.length (); ++i)
    6788         2940 :         gcc_assert (vec[i] == saved[perm[i]]);
    6789              :     }
    6790       226657 : }
    6791              : 
    6792              : /* Return the cfg loop that contains NODE.  */
    6793              : 
    6794              : struct loop *
    6795      4069839 : vect_optimize_slp_pass::containing_loop (slp_tree node)
    6796              : {
    6797      4069839 :   stmt_vec_info rep = SLP_TREE_REPRESENTATIVE (node);
    6798      4069839 :   if (!rep)
    6799         6294 :     return ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father;
    6800      4547131 :   return gimple_bb (vect_orig_stmt (rep)->stmt)->loop_father;
    6801              : }
    6802              : 
    6803              : /* Return true if UD (an edge from a use to a definition) is associated
    6804              :    with a loop latch edge in the cfg.  */
    6805              : 
    6806              : bool
    6807      8239777 : vect_optimize_slp_pass::is_cfg_latch_edge (graph_edge *ud)
    6808              : {
    6809      8239777 :   slp_tree use = m_vertices[ud->src].node;
    6810      8239777 :   slp_tree def = m_vertices[ud->dest].node;
    6811      8239777 :   if ((SLP_TREE_DEF_TYPE (use) != vect_internal_def
    6812      8239777 :        || SLP_TREE_PERMUTE_P (use))
    6813      7919804 :       || SLP_TREE_DEF_TYPE (def) != vect_internal_def)
    6814              :     return false;
    6815              : 
    6816      4797114 :   stmt_vec_info use_rep = vect_orig_stmt (SLP_TREE_REPRESENTATIVE (use));
    6817      4797114 :   return (is_a<gphi *> (use_rep->stmt)
    6818       388448 :           && bb_loop_header_p (gimple_bb (use_rep->stmt))
    6819      5014852 :           && containing_loop (def) == containing_loop (use));
    6820              : }
    6821              : 
    6822              : /* Build the graph.  Mark edges that correspond to cfg loop latch edges with
    6823              :    a nonnull data field.  */
    6824              : 
    6825              : void
    6826      1419966 : vect_optimize_slp_pass::build_graph ()
    6827              : {
    6828      1419966 :   m_optimize_size = true;
    6829      1419966 :   build_vertices ();
    6830              : 
    6831      2839932 :   m_slpg = new_graph (m_vertices.length ());
    6832     14709727 :   for (slpg_vertex &v : m_vertices)
    6833     31243864 :     for (slp_tree child : SLP_TREE_CHILDREN (v.node))
    6834      9150061 :       if (child)
    6835              :         {
    6836      8239777 :           graph_edge *ud = add_edge (m_slpg, v.node->vertex, child->vertex);
    6837      8239777 :           if (is_cfg_latch_edge (ud))
    6838       207974 :             ud->data = this;
    6839              :         }
    6840      1419966 : }
    6841              : 
    6842              : /* Return true if E corresponds to a loop latch edge in the cfg.  */
    6843              : 
    6844              : static bool
    6845      4223338 : skip_cfg_latch_edges (graph_edge *e)
    6846              : {
    6847      4223338 :   return e->data;
    6848              : }
    6849              : 
    6850              : /* Create the node partitions.  */
    6851              : 
    6852              : void
    6853       709983 : vect_optimize_slp_pass::create_partitions ()
    6854              : {
    6855              :   /* Calculate a postorder of the graph, ignoring edges that correspond
    6856              :      to natural latch edges in the cfg.  Reading the vector from the end
    6857              :      to the beginning gives the reverse postorder.  */
    6858       709983 :   auto_vec<int> initial_rpo;
    6859      1419966 :   graphds_dfs (m_slpg, &m_leafs[0], m_leafs.length (), &initial_rpo,
    6860              :                false, NULL, skip_cfg_latch_edges);
    6861      2129949 :   gcc_assert (initial_rpo.length () == m_vertices.length ());
    6862              : 
    6863              :   /* Calculate the strongly connected components of the graph.  */
    6864       709983 :   auto_vec<int> scc_grouping;
    6865       709983 :   unsigned int num_sccs = graphds_scc (m_slpg, NULL, NULL, &scc_grouping);
    6866              : 
    6867              :   /* Create a new index order in which all nodes from the same SCC are
    6868              :      consecutive.  Use scc_pos to record the index of the first node in
    6869              :      each SCC.  */
    6870       709983 :   auto_vec<unsigned int> scc_pos (num_sccs);
    6871       709983 :   int last_component = -1;
    6872       709983 :   unsigned int node_count = 0;
    6873      7354328 :   for (unsigned int node_i : scc_grouping)
    6874              :     {
    6875      5224379 :       if (last_component != m_slpg->vertices[node_i].component)
    6876              :         {
    6877      5093849 :           last_component = m_slpg->vertices[node_i].component;
    6878     10187698 :           gcc_assert (last_component == int (scc_pos.length ()));
    6879      5093849 :           scc_pos.quick_push (node_count);
    6880              :         }
    6881      5224379 :       node_count += 1;
    6882              :     }
    6883      1419966 :   gcc_assert (node_count == initial_rpo.length ()
    6884              :               && last_component + 1 == int (num_sccs));
    6885              : 
    6886              :   /* Use m_partitioned_nodes to group nodes into SCC order, with the nodes
    6887              :      inside each SCC following the RPO we calculated above.  The fact that
    6888              :      we ignored natural latch edges when calculating the RPO should ensure
    6889              :      that, for natural loop nests:
    6890              : 
    6891              :      - the first node that we encounter in a cfg loop is the loop header phi
    6892              :      - the loop header phis are in dominance order
    6893              : 
    6894              :      Arranging for this is an optimization (see below) rather than a
    6895              :      correctness issue.  Unnatural loops with a tangled mess of backedges
    6896              :      will still work correctly, but might give poorer results.
    6897              : 
    6898              :      Also update scc_pos so that it gives 1 + the index of the last node
    6899              :      in the SCC.  */
    6900       709983 :   m_partitioned_nodes.safe_grow (node_count);
    6901      6644345 :   for (unsigned int old_i = initial_rpo.length (); old_i-- > 0;)
    6902              :     {
    6903      5224379 :       unsigned int node_i = initial_rpo[old_i];
    6904      5224379 :       unsigned int new_i = scc_pos[m_slpg->vertices[node_i].component]++;
    6905      5224379 :       m_partitioned_nodes[new_i] = node_i;
    6906              :     }
    6907              : 
    6908              :   /* When optimizing for speed, partition each SCC based on the containing
    6909              :      cfg loop. The order we constructed above should ensure that, for natural
    6910              :      cfg loops, we'll create sub-SCC partitions for outer loops before
    6911              :      the corresponding sub-SCC partitions for inner loops.  Similarly,
    6912              :      when one sibling loop A dominates another sibling loop B, we should
    6913              :      create a sub-SCC partition for A before a sub-SCC partition for B.
    6914              : 
    6915              :      As above, nothing depends for correctness on whether this achieves
    6916              :      a natural nesting, but we should get better results when it does.  */
    6917      1419966 :   m_partitions.reserve (m_vertices.length ());
    6918       709983 :   unsigned int next_partition_i = 0;
    6919       709983 :   hash_map<struct loop *, int> loop_partitions;
    6920       709983 :   unsigned int rpo_begin = 0;
    6921       709983 :   unsigned int num_partitioned_nodes = 0;
    6922      7223798 :   for (unsigned int rpo_end : scc_pos)
    6923              :     {
    6924      5093849 :       loop_partitions.empty ();
    6925              :       unsigned int partition_i = next_partition_i;
    6926     10318228 :       for (unsigned int rpo_i = rpo_begin; rpo_i < rpo_end; ++rpo_i)
    6927              :         {
    6928              :           /* Handle externals and constants optimistically throughout.
    6929              :              But treat existing vectors as fixed since we do not handle
    6930              :              permuting them.  */
    6931      5224379 :           unsigned int node_i = m_partitioned_nodes[rpo_i];
    6932      5224379 :           auto &vertex = m_vertices[node_i];
    6933      5224379 :           if ((SLP_TREE_DEF_TYPE (vertex.node) == vect_external_def
    6934       529607 :                && !SLP_TREE_VEC_DEFS (vertex.node).exists ())
    6935      5227590 :               || SLP_TREE_DEF_TYPE (vertex.node) == vect_constant_def)
    6936      1562552 :             vertex.partition = -1;
    6937              :           else
    6938              :             {
    6939      3661827 :               bool existed;
    6940      3661827 :               if (m_optimize_size)
    6941        27464 :                 existed = next_partition_i > partition_i;
    6942              :               else
    6943              :                 {
    6944      3634363 :                   struct loop *loop = containing_loop (vertex.node);
    6945      3634363 :                   auto &entry = loop_partitions.get_or_insert (loop, &existed);
    6946      3634363 :                   if (!existed)
    6947      3504990 :                     entry = next_partition_i;
    6948      3634363 :                   partition_i = entry;
    6949              :                 }
    6950      3661827 :               if (!existed)
    6951              :                 {
    6952      3532362 :                   m_partitions.quick_push (slpg_partition_info ());
    6953      3532362 :                   next_partition_i += 1;
    6954              :                 }
    6955      3661827 :               vertex.partition = partition_i;
    6956      3661827 :               num_partitioned_nodes += 1;
    6957      3661827 :               m_partitions[partition_i].node_end += 1;
    6958              :             }
    6959              :         }
    6960      5093849 :       rpo_begin = rpo_end;
    6961              :     }
    6962              : 
    6963              :   /* Assign ranges of consecutive node indices to each partition,
    6964              :      in partition order.  Start with node_end being the same as
    6965              :      node_begin so that the next loop can use it as a counter.  */
    6966       709983 :   unsigned int node_begin = 0;
    6967      5662311 :   for (auto &partition : m_partitions)
    6968              :     {
    6969      3532362 :       partition.node_begin = node_begin;
    6970      3532362 :       node_begin += partition.node_end;
    6971      3532362 :       partition.node_end = partition.node_begin;
    6972              :     }
    6973       709983 :   gcc_assert (node_begin == num_partitioned_nodes);
    6974              : 
    6975              :   /* Finally build the list of nodes in partition order.  */
    6976       709983 :   m_partitioned_nodes.truncate (num_partitioned_nodes);
    6977      5934362 :   for (unsigned int node_i = 0; node_i < m_vertices.length (); ++node_i)
    6978              :     {
    6979      5224379 :       int partition_i = m_vertices[node_i].partition;
    6980      5224379 :       if (partition_i >= 0)
    6981              :         {
    6982      3661827 :           unsigned int order_i = m_partitions[partition_i].node_end++;
    6983      3661827 :           m_partitioned_nodes[order_i] = node_i;
    6984              :         }
    6985              :     }
    6986       709983 : }
    6987              : 
    6988              : /* Look for edges from earlier partitions into node NODE_I and edges from
    6989              :    node NODE_I into later partitions.  Call:
    6990              : 
    6991              :       FN (ud, other_node_i)
    6992              : 
    6993              :    for each such use-to-def edge ud, where other_node_i is the node at the
    6994              :    other end of the edge.  */
    6995              : 
    6996              : template<typename T>
    6997              : void
    6998      4130791 : vect_optimize_slp_pass::for_each_partition_edge (unsigned int node_i, T fn)
    6999              : {
    7000      4130791 :   int partition_i = m_vertices[node_i].partition;
    7001      4130791 :   for (graph_edge *pred = m_slpg->vertices[node_i].pred;
    7002      7148940 :        pred; pred = pred->pred_next)
    7003              :     {
    7004      3018149 :       int src_partition_i = m_vertices[pred->src].partition;
    7005      3018149 :       if (src_partition_i >= 0 && src_partition_i != partition_i)
    7006      2688251 :         fn (pred, pred->src);
    7007              :     }
    7008      4130791 :   for (graph_edge *succ = m_slpg->vertices[node_i].succ;
    7009      8889986 :        succ; succ = succ->succ_next)
    7010              :     {
    7011      4759195 :       int dest_partition_i = m_vertices[succ->dest].partition;
    7012      4759195 :       if (dest_partition_i >= 0 && dest_partition_i != partition_i)
    7013      2724916 :         fn (succ, succ->dest);
    7014              :     }
    7015      4130791 : }
    7016              : 
    7017              : /* Return true if layout LAYOUT_I is compatible with the number of SLP lanes
    7018              :    that NODE would operate on.  This test is independent of NODE's actual
    7019              :    operation.  */
    7020              : 
    7021              : bool
    7022      1804549 : vect_optimize_slp_pass::is_compatible_layout (slp_tree node,
    7023              :                                               unsigned int layout_i)
    7024              : {
    7025      1804549 :   if (layout_i == 0)
    7026              :     return true;
    7027              : 
    7028      1055560 :   if (SLP_TREE_LANES (node) != m_perms[layout_i].length ())
    7029        18439 :     return false;
    7030              : 
    7031              :   return true;
    7032              : }
    7033              : 
    7034              : /* Return true if layout LAYOUT_I is compatible with the number of SLP lanes
    7035              :    that NODE would operate on for each NODE in PARTITION.
    7036              :    This test is independent of NODE's actual operations.  */
    7037              : 
    7038              : bool
    7039        23836 : vect_optimize_slp_pass::is_compatible_layout (const slpg_partition_info
    7040              :                                                 &partition,
    7041              :                                               unsigned int layout_i)
    7042              : {
    7043        48102 :   for (unsigned int order_i = partition.node_begin;
    7044        48102 :        order_i < partition.node_end; ++order_i)
    7045              :     {
    7046        24370 :       unsigned int node_i = m_partitioned_nodes[order_i];
    7047        24370 :       auto &vertex = m_vertices[node_i];
    7048              : 
    7049              :       /* The layout is incompatible if it is individually incompatible
    7050              :          with any node in the partition.  */
    7051        24370 :       if (!is_compatible_layout (vertex.node, layout_i))
    7052              :         return false;
    7053              :     }
    7054              :   return true;
    7055              : }
    7056              : 
    7057              : /* Return the cost (in arbitrary units) of going from layout FROM_LAYOUT_I
    7058              :    to layout TO_LAYOUT_I for a node like NODE.  Return -1 if either of the
    7059              :    layouts is incompatible with NODE or if the change is not possible for
    7060              :    some other reason.
    7061              : 
    7062              :    The properties taken from NODE include the number of lanes and the
    7063              :    vector type.  The actual operation doesn't matter.  */
    7064              : 
    7065              : int
    7066       762302 : vect_optimize_slp_pass::change_layout_cost (slp_tree node,
    7067              :                                             unsigned int from_layout_i,
    7068              :                                             unsigned int to_layout_i)
    7069              : {
    7070       762302 :   if (!is_compatible_layout (node, from_layout_i)
    7071       762302 :       || !is_compatible_layout (node, to_layout_i))
    7072          623 :     return -1;
    7073              : 
    7074       761679 :   if (from_layout_i == to_layout_i)
    7075              :     return 0;
    7076              : 
    7077       317012 :   auto_vec<slp_tree, 1> children (1);
    7078       317012 :   children.quick_push (node);
    7079       317012 :   auto_lane_permutation_t perm (SLP_TREE_LANES (node));
    7080       317012 :   if (from_layout_i > 0)
    7081       890641 :     for (unsigned int i : m_perms[from_layout_i])
    7082       394375 :       perm.quick_push ({ 0, i });
    7083              :   else
    7084       496511 :     for (unsigned int i = 0; i < SLP_TREE_LANES (node); ++i)
    7085       344921 :       perm.quick_push ({ 0, i });
    7086       317012 :   if (to_layout_i > 0)
    7087       152333 :     vect_slp_permute (m_perms[to_layout_i], perm, true);
    7088       317012 :   auto count = vectorizable_slp_permutation_1 (m_vinfo, nullptr, node, perm,
    7089              :                                                children, false);
    7090       317012 :   if (count >= 0)
    7091       311253 :     return MAX (count, 1);
    7092              : 
    7093              :   /* ??? In principle we could try changing via layout 0, giving two
    7094              :      layout changes rather than 1.  Doing that would require
    7095              :      corresponding support in get_result_with_layout.  */
    7096              :   return -1;
    7097       317012 : }
    7098              : 
    7099              : /* Return the costs of assigning layout LAYOUT_I to partition PARTITION_I.  */
    7100              : 
    7101              : inline slpg_partition_layout_costs &
    7102      1136746 : vect_optimize_slp_pass::partition_layout_costs (unsigned int partition_i,
    7103              :                                                 unsigned int layout_i)
    7104              : {
    7105      2273492 :   return m_partition_layout_costs[partition_i * m_perms.length () + layout_i];
    7106              : }
    7107              : 
    7108              : /* Change PERM in one of two ways:
    7109              : 
    7110              :    - if IN_LAYOUT_I < 0, accept input operand I in the layout that has been
    7111              :      chosen for child I of NODE.
    7112              : 
    7113              :    - if IN_LAYOUT >= 0, accept all inputs operands with that layout.
    7114              : 
    7115              :    In both cases, arrange for the output to have layout OUT_LAYOUT_I  */
    7116              : 
    7117              : void
    7118        39085 : vect_optimize_slp_pass::
    7119              : change_vec_perm_layout (slp_tree node, lane_permutation_t &perm,
    7120              :                         int in_layout_i, unsigned int out_layout_i)
    7121              : {
    7122       229327 :   for (auto &entry : perm)
    7123              :     {
    7124       112072 :       int this_in_layout_i = in_layout_i;
    7125       112072 :       if (this_in_layout_i < 0)
    7126              :         {
    7127        76473 :           slp_tree in_node = SLP_TREE_CHILDREN (node)[entry.first];
    7128        76473 :           unsigned int in_partition_i = m_vertices[in_node->vertex].partition;
    7129        76473 :           if (in_partition_i == -1u)
    7130          329 :             continue;
    7131        76144 :           this_in_layout_i = m_partitions[in_partition_i].layout;
    7132              :         }
    7133       111743 :       if (this_in_layout_i > 0)
    7134        25087 :         entry.second = m_perms[this_in_layout_i][entry.second];
    7135              :     }
    7136        39085 :   if (out_layout_i > 0)
    7137        11305 :     vect_slp_permute (m_perms[out_layout_i], perm, true);
    7138        39085 : }
    7139              : 
    7140              : /* Check whether the target allows NODE to be rearranged so that the node's
    7141              :    output has layout OUT_LAYOUT_I.  Return the cost of the change if so,
    7142              :    in the same arbitrary units as for change_layout_cost.  Return -1 otherwise.
    7143              : 
    7144              :    If NODE is a VEC_PERM_EXPR and IN_LAYOUT_I < 0, also check whether
    7145              :    NODE can adapt to the layout changes that have (perhaps provisionally)
    7146              :    been chosen for NODE's children, so that no extra permutations are
    7147              :    needed on either the input or the output of NODE.
    7148              : 
    7149              :    If NODE is a VEC_PERM_EXPR and IN_LAYOUT_I >= 0, instead assume
    7150              :    that all inputs will be forced into layout IN_LAYOUT_I beforehand.
    7151              : 
    7152              :    IN_LAYOUT_I has no meaning for other types of node.
    7153              : 
    7154              :    Keeping the node as-is is always valid.  If the target doesn't appear
    7155              :    to support the node as-is, but might realistically support other layouts,
    7156              :    then layout 0 instead has the cost of a worst-case permutation.  On the
    7157              :    one hand, this ensures that every node has at least one valid layout,
    7158              :    avoiding what would otherwise be an awkward special case.  On the other,
    7159              :    it still encourages the pass to change an invalid pre-existing layout
    7160              :    choice into a valid one.  */
    7161              : 
    7162              : int
    7163       251321 : vect_optimize_slp_pass::internal_node_cost (slp_tree node, int in_layout_i,
    7164              :                                             unsigned int out_layout_i)
    7165              : {
    7166       251321 :   const int fallback_cost = 1;
    7167              : 
    7168       251321 :   if (SLP_TREE_PERMUTE_P (node))
    7169              :     {
    7170        32398 :       auto_lane_permutation_t tmp_perm;
    7171        32398 :       tmp_perm.safe_splice (SLP_TREE_LANE_PERMUTATION (node));
    7172              : 
    7173              :       /* Check that the child nodes support the chosen layout.  Checking
    7174              :          the first child is enough, since any second child would have the
    7175              :          same shape.  */
    7176        32398 :       auto first_child = SLP_TREE_CHILDREN (node)[0];
    7177        32398 :       if (in_layout_i > 0
    7178        32398 :           && !is_compatible_layout (first_child, in_layout_i))
    7179              :         return -1;
    7180              : 
    7181        31780 :       change_vec_perm_layout (node, tmp_perm, in_layout_i, out_layout_i);
    7182        63560 :       int count = vectorizable_slp_permutation_1 (m_vinfo, nullptr,
    7183              :                                                   node, tmp_perm,
    7184        31780 :                                                   SLP_TREE_CHILDREN (node),
    7185              :                                                   false);
    7186        31780 :       if (count < 0)
    7187              :         {
    7188         2593 :           if (in_layout_i == 0 && out_layout_i == 0)
    7189              :             {
    7190              :               /* Use the fallback cost if the node could in principle support
    7191              :                  some nonzero layout for both the inputs and the outputs.
    7192              :                  Otherwise assume that the node will be rejected later
    7193              :                  and rebuilt from scalars.  */
    7194          641 :               if (SLP_TREE_LANES (node) == SLP_TREE_LANES (first_child))
    7195              :                 return fallback_cost;
    7196          319 :               return 0;
    7197              :             }
    7198              :           return -1;
    7199              :         }
    7200              : 
    7201              :       /* We currently have no way of telling whether the new layout is cheaper
    7202              :          or more expensive than the old one.  But at least in principle,
    7203              :          it should be worth making zero permutations (whole-vector shuffles)
    7204              :          cheaper than real permutations, in case the pass is able to remove
    7205              :          the latter.  */
    7206        29187 :       return count == 0 ? 0 : 1;
    7207        32398 :     }
    7208              : 
    7209       218923 :   stmt_vec_info rep = SLP_TREE_REPRESENTATIVE (node);
    7210       218923 :   if (rep
    7211       216973 :       && STMT_VINFO_DATA_REF (rep)
    7212        71331 :       && DR_IS_READ (STMT_VINFO_DATA_REF (rep))
    7213       266509 :       && SLP_TREE_LOAD_PERMUTATION (node).exists ())
    7214              :     {
    7215        39334 :       auto_load_permutation_t tmp_perm;
    7216        39334 :       tmp_perm.safe_splice (SLP_TREE_LOAD_PERMUTATION (node));
    7217        39334 :       if (out_layout_i > 0)
    7218        15080 :         vect_slp_permute (m_perms[out_layout_i], tmp_perm, true);
    7219              : 
    7220        39334 :       poly_uint64 vf = 1;
    7221        39334 :       if (auto loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo))
    7222        12152 :         vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
    7223        39334 :       unsigned int n_perms;
    7224        39334 :       if (!vect_transform_slp_perm_load_1 (m_vinfo, node, tmp_perm, vNULL,
    7225              :                                            nullptr, vf, true, false, &n_perms))
    7226              :         {
    7227         2367 :           auto rep = SLP_TREE_REPRESENTATIVE (node);
    7228         2367 :           if (out_layout_i == 0)
    7229              :             {
    7230              :               /* Use the fallback cost if the load is an N-to-N permutation.
    7231              :                  Otherwise assume that the node will be rejected later
    7232              :                  and rebuilt from scalars.  */
    7233         1734 :               if (STMT_VINFO_GROUPED_ACCESS (rep)
    7234         3468 :                   && (DR_GROUP_SIZE (DR_GROUP_FIRST_ELEMENT (rep))
    7235         1734 :                       == SLP_TREE_LANES (node)))
    7236          684 :                 return fallback_cost;
    7237              :               return 0;
    7238              :             }
    7239              :           return -1;
    7240              :         }
    7241              : 
    7242              :       /* See the comment above the corresponding VEC_PERM_EXPR handling.  */
    7243        36967 :       return n_perms == 0 ? 0 : 1;
    7244        39334 :     }
    7245              : 
    7246              :   return 0;
    7247              : }
    7248              : 
    7249              : /* Decide which element layouts we should consider using.  Calculate the
    7250              :    weights associated with inserting layout changes on partition edges.
    7251              :    Also mark partitions that cannot change layout, by setting their
    7252              :    layout to zero.  */
    7253              : 
    7254              : void
    7255       709983 : vect_optimize_slp_pass::start_choosing_layouts ()
    7256              : {
    7257              :   /* Used to assign unique permutation indices.  */
    7258       709983 :   using perm_hash = unbounded_hashmap_traits<
    7259              :     vec_free_hash_base<int_hash_base<unsigned>>,
    7260              :     int_hash<int, -1, -2>
    7261              :   >;
    7262       709983 :   hash_map<vec<unsigned>, int, perm_hash> layout_ids;
    7263              : 
    7264              :   /* Layout 0 is "no change".  */
    7265       709983 :   m_perms.safe_push (vNULL);
    7266              : 
    7267              :   /* Create layouts from existing permutations.  */
    7268       709983 :   auto_load_permutation_t tmp_perm;
    7269      5791776 :   for (unsigned int node_i : m_partitioned_nodes)
    7270              :     {
    7271              :       /* Leafs also double as entries to the reverse graph.  Allow the
    7272              :          layout of those to be changed.  */
    7273      3661827 :       auto &vertex = m_vertices[node_i];
    7274      3661827 :       auto &partition = m_partitions[vertex.partition];
    7275      3661827 :       if (!m_slpg->vertices[node_i].succ)
    7276       932800 :         partition.layout = 0;
    7277              : 
    7278              :       /* Loads and VEC_PERM_EXPRs are the only things generating permutes.  */
    7279      3661827 :       slp_tree node = vertex.node;
    7280      3661827 :       stmt_vec_info dr_stmt = SLP_TREE_REPRESENTATIVE (node);
    7281      3661827 :       slp_tree child;
    7282      3661827 :       unsigned HOST_WIDE_INT imin, imax = 0;
    7283      3661827 :       bool any_permute = false;
    7284      3661827 :       tmp_perm.truncate (0);
    7285      3661827 :       if (SLP_TREE_LOAD_PERMUTATION (node).exists ())
    7286              :         {
    7287              :           /* If splitting out a SLP_TREE_LANE_PERMUTATION can make the node
    7288              :              unpermuted, record a layout that reverses this permutation.
    7289              : 
    7290              :              We would need more work to cope with loads that are internally
    7291              :              permuted and also have inputs (such as masks for
    7292              :              IFN_MASK_LOADs).  */
    7293       628274 :           gcc_assert (partition.layout == 0 && !m_slpg->vertices[node_i].succ);
    7294       628274 :           if (!STMT_VINFO_GROUPED_ACCESS (dr_stmt))
    7295              :             {
    7296       443344 :               partition.layout = -1;
    7297      3640804 :               continue;
    7298              :             }
    7299       184930 :           dr_stmt = DR_GROUP_FIRST_ELEMENT (dr_stmt);
    7300       184930 :           imin = DR_GROUP_SIZE (dr_stmt) + 1;
    7301       184930 :           tmp_perm.safe_splice (SLP_TREE_LOAD_PERMUTATION (node));
    7302              :         }
    7303      5946795 :       else if (SLP_TREE_PERMUTE_P (node)
    7304       139880 :                && SLP_TREE_CHILDREN (node).length () == 1
    7305       120311 :                && (child = SLP_TREE_CHILDREN (node)[0])
    7306      3153864 :                && (TYPE_VECTOR_SUBPARTS (SLP_TREE_VECTYPE (child))
    7307       120311 :                    .is_constant (&imin)))
    7308              :         {
    7309              :           /* If the child has the same vector size as this node,
    7310              :              reversing the permutation can make the permutation a no-op.
    7311              :              In other cases it can change a true permutation into a
    7312              :              full-vector extract.  */
    7313       120311 :           tmp_perm.reserve (SLP_TREE_LANES (node));
    7314       325420 :           for (unsigned j = 0; j < SLP_TREE_LANES (node); ++j)
    7315       205109 :             tmp_perm.quick_push (SLP_TREE_LANE_PERMUTATION (node)[j].second);
    7316              :         }
    7317              :       else
    7318      2913242 :         continue;
    7319              : 
    7320       818694 :       for (unsigned j = 0; j < SLP_TREE_LANES (node); ++j)
    7321              :         {
    7322       513453 :           unsigned idx = tmp_perm[j];
    7323       513453 :           imin = MIN (imin, idx);
    7324       513453 :           imax = MAX (imax, idx);
    7325       513453 :           if (idx - tmp_perm[0] != j)
    7326       160613 :             any_permute = true;
    7327              :         }
    7328              :       /* If the span doesn't match we'd disrupt VF computation, avoid
    7329              :          that for now.  */
    7330       305241 :       if (imax - imin + 1 != SLP_TREE_LANES (node))
    7331        91478 :         continue;
    7332              :       /* If there's no permute no need to split one out.  In this case
    7333              :          we can consider turning a load into a permuted load, if that
    7334              :          turns out to be cheaper than alternatives.  */
    7335       213763 :       if (!any_permute)
    7336              :         {
    7337       192585 :           partition.layout = -1;
    7338       192585 :           continue;
    7339              :         }
    7340              : 
    7341              :       /* For now only handle true permutes, like
    7342              :          vect_attempt_slp_rearrange_stmts did.  This allows us to be lazy
    7343              :          when permuting constants and invariants keeping the permute
    7344              :          bijective.  */
    7345        21178 :       auto_sbitmap load_index (SLP_TREE_LANES (node));
    7346        21178 :       bitmap_clear (load_index);
    7347        84622 :       for (unsigned j = 0; j < SLP_TREE_LANES (node); ++j)
    7348        63444 :         bitmap_set_bit (load_index, tmp_perm[j] - imin);
    7349              :       unsigned j;
    7350        83779 :       for (j = 0; j < SLP_TREE_LANES (node); ++j)
    7351        62756 :         if (!bitmap_bit_p (load_index, j))
    7352              :           break;
    7353        21178 :       if (j != SLP_TREE_LANES (node))
    7354          155 :         continue;
    7355              : 
    7356        21023 :       vec<unsigned> perm = vNULL;
    7357        21023 :       perm.safe_grow (SLP_TREE_LANES (node), true);
    7358        83500 :       for (unsigned j = 0; j < SLP_TREE_LANES (node); ++j)
    7359        62477 :         perm[j] = tmp_perm[j] - imin;
    7360              : 
    7361        42046 :       if (int (m_perms.length ()) >= param_vect_max_layout_candidates)
    7362              :         {
    7363              :           /* Continue to use existing layouts, but don't add any more.  */
    7364            0 :           int *entry = layout_ids.get (perm);
    7365            0 :           partition.layout = entry ? *entry : 0;
    7366            0 :           perm.release ();
    7367              :         }
    7368              :       else
    7369              :         {
    7370        21023 :           bool existed;
    7371        21023 :           int &layout_i = layout_ids.get_or_insert (perm, &existed);
    7372        21023 :           if (existed)
    7373         7920 :             perm.release ();
    7374              :           else
    7375              :             {
    7376        13103 :               layout_i = m_perms.length ();
    7377        13103 :               m_perms.safe_push (perm);
    7378              :             }
    7379        21023 :           partition.layout = layout_i;
    7380              :         }
    7381        21178 :     }
    7382              : 
    7383              :   /* Initially assume that every layout is possible and has zero cost
    7384              :      in every partition.  */
    7385       709983 :   m_partition_layout_costs.safe_grow_cleared (m_partitions.length ()
    7386      1419966 :                                               * m_perms.length ());
    7387              : 
    7388              :   /* We have to mark outgoing permutations facing non-associating-reduction
    7389              :      graph entries that are not represented as to be materialized.
    7390              :      slp_inst_kind_bb_reduc currently only covers associatable reductions.  */
    7391      3655310 :   for (slp_instance instance : m_vinfo->slp_instances)
    7392      1525361 :     if (SLP_INSTANCE_KIND (instance) == slp_inst_kind_ctor)
    7393              :       {
    7394         6900 :         unsigned int node_i = SLP_INSTANCE_TREE (instance)->vertex;
    7395         6900 :         m_partitions[m_vertices[node_i].partition].layout = 0;
    7396              :       }
    7397      1518461 :     else if (SLP_INSTANCE_KIND (instance) == slp_inst_kind_reduc_chain)
    7398              :       {
    7399         2306 :         stmt_vec_info stmt_info
    7400         2306 :           = SLP_TREE_REPRESENTATIVE (SLP_INSTANCE_TREE (instance));
    7401         2306 :         vect_reduc_info reduc_info
    7402         2306 :           = info_for_reduction (as_a <loop_vec_info> (m_vinfo),
    7403              :                                 SLP_INSTANCE_TREE (instance));
    7404         2306 :         if (needs_fold_left_reduction_p (TREE_TYPE
    7405              :                                            (gimple_get_lhs (stmt_info->stmt)),
    7406              :                                          VECT_REDUC_INFO_CODE (reduc_info)))
    7407              :           {
    7408          100 :             unsigned int node_i = SLP_INSTANCE_TREE (instance)->vertex;
    7409          100 :             m_partitions[m_vertices[node_i].partition].layout = 0;
    7410              :           }
    7411              :       }
    7412              : 
    7413              :   /* Check which layouts each node and partition can handle.  Calculate the
    7414              :      weights associated with inserting layout changes on edges.  */
    7415      5791776 :   for (unsigned int node_i : m_partitioned_nodes)
    7416              :     {
    7417      3661827 :       auto &vertex = m_vertices[node_i];
    7418      3661827 :       auto &partition = m_partitions[vertex.partition];
    7419      3661827 :       slp_tree node = vertex.node;
    7420              : 
    7421      3661827 :       if (stmt_vec_info rep = SLP_TREE_REPRESENTATIVE (node))
    7422              :         {
    7423      3655518 :           vertex.weight = vect_slp_node_weight (node);
    7424              : 
    7425              :           /* We do not handle stores with a permutation, so all
    7426              :              incoming permutations must have been materialized.
    7427              : 
    7428              :              We also don't handle masked grouped loads, which lack a
    7429              :              permutation vector.  In this case the memory locations
    7430              :              form an implicit second input to the loads, on top of the
    7431              :              explicit mask input, and the memory input's layout cannot
    7432              :              be changed.
    7433              : 
    7434              :              On the other hand, we do support permuting gather loads and
    7435              :              masked gather loads, where each scalar load is independent
    7436              :              of the others.  This can be useful if the address/index input
    7437              :              benefits from permutation.  */
    7438      3655518 :           if (STMT_VINFO_DATA_REF (rep)
    7439      1812684 :               && STMT_VINFO_GROUPED_ACCESS (rep)
    7440      4773243 :               && !SLP_TREE_LOAD_PERMUTATION (node).exists ())
    7441       932795 :             partition.layout = 0;
    7442              : 
    7443              :           /* We cannot change the layout of an operation that is
    7444              :              not independent on lanes.  Note this is an explicit
    7445              :              negative list since that's much shorter than the respective
    7446              :              positive one but it's critical to keep maintaining it.  */
    7447      3655518 :           if (is_gimple_call (STMT_VINFO_STMT (rep)))
    7448        33483 :             switch (gimple_call_combined_fn (STMT_VINFO_STMT (rep)))
    7449              :               {
    7450         1092 :               case CFN_COMPLEX_ADD_ROT90:
    7451         1092 :               case CFN_COMPLEX_ADD_ROT270:
    7452         1092 :               case CFN_COMPLEX_MUL:
    7453         1092 :               case CFN_COMPLEX_MUL_CONJ:
    7454         1092 :               case CFN_VEC_ADDSUB:
    7455         1092 :               case CFN_VEC_FMADDSUB:
    7456         1092 :               case CFN_VEC_FMSUBADD:
    7457         1092 :                 partition.layout = 0;
    7458              :               default:;
    7459              :               }
    7460              :         }
    7461              : 
    7462      8281475 :       auto process_edge = [&](graph_edge *ud, unsigned int other_node_i)
    7463              :         {
    7464      4619648 :           auto &other_vertex = m_vertices[other_node_i];
    7465              : 
    7466              :           /* Count the number of edges from earlier partitions and the number
    7467              :              of edges to later partitions.  */
    7468      4619648 :           if (other_vertex.partition < vertex.partition)
    7469      2309824 :             partition.in_degree += 1;
    7470              :           else
    7471      2309824 :             partition.out_degree += 1;
    7472              : 
    7473              :           /* If the current node uses the result of OTHER_NODE_I, accumulate
    7474              :              the effects of that.  */
    7475      4619648 :           if (ud->src == int (node_i))
    7476              :             {
    7477      2309824 :               other_vertex.out_weight += vertex.weight;
    7478      2309824 :               other_vertex.out_degree += 1;
    7479              :             }
    7480      8281475 :         };
    7481      3661827 :       for_each_partition_edge (node_i, process_edge);
    7482              :     }
    7483       709983 : }
    7484              : 
    7485              : /* Return the incoming costs for node NODE_I, assuming that each input keeps
    7486              :    its current (provisional) choice of layout.  The inputs do not necessarily
    7487              :    have the same layout as each other.  */
    7488              : 
    7489              : slpg_layout_cost
    7490         4457 : vect_optimize_slp_pass::total_in_cost (unsigned int node_i)
    7491              : {
    7492         4457 :   auto &vertex = m_vertices[node_i];
    7493         4457 :   slpg_layout_cost cost;
    7494        14547 :   auto add_cost = [&](graph_edge *, unsigned int other_node_i)
    7495              :     {
    7496        10090 :       auto &other_vertex = m_vertices[other_node_i];
    7497        10090 :       if (other_vertex.partition < vertex.partition)
    7498              :         {
    7499         6887 :           auto &other_partition = m_partitions[other_vertex.partition];
    7500        13774 :           auto &other_costs = partition_layout_costs (other_vertex.partition,
    7501         6887 :                                                       other_partition.layout);
    7502         6887 :           slpg_layout_cost this_cost = other_costs.in_cost;
    7503         6887 :           this_cost.add_serial_cost (other_costs.internal_cost);
    7504         6887 :           this_cost.split (other_partition.out_degree);
    7505         6887 :           cost.add_parallel_cost (this_cost);
    7506              :         }
    7507        14547 :     };
    7508         4457 :   for_each_partition_edge (node_i, add_cost);
    7509         4457 :   return cost;
    7510              : }
    7511              : 
    7512              : /* Return the cost of switching between layout LAYOUT1_I (at node NODE1_I)
    7513              :    and layout LAYOUT2_I on cross-partition use-to-def edge UD.  Return
    7514              :    slpg_layout_cost::impossible () if the change isn't possible.  */
    7515              : 
    7516              : slpg_layout_cost
    7517       762302 : vect_optimize_slp_pass::
    7518              : edge_layout_cost (graph_edge *ud, unsigned int node1_i, unsigned int layout1_i,
    7519              :                   unsigned int layout2_i)
    7520              : {
    7521       762302 :   auto &def_vertex = m_vertices[ud->dest];
    7522       762302 :   auto &use_vertex = m_vertices[ud->src];
    7523       762302 :   auto def_layout_i = ud->dest == int (node1_i) ? layout1_i : layout2_i;
    7524       762302 :   auto use_layout_i = ud->dest == int (node1_i) ? layout2_i : layout1_i;
    7525       762302 :   auto factor = change_layout_cost (def_vertex.node, def_layout_i,
    7526              :                                     use_layout_i);
    7527       762302 :   if (factor < 0)
    7528         6382 :     return slpg_layout_cost::impossible ();
    7529              : 
    7530              :   /* We have a choice of putting the layout change at the site of the
    7531              :      definition or at the site of the use.  Prefer the former when
    7532              :      optimizing for size or when the execution frequency of the
    7533              :      definition is no greater than the combined execution frequencies of
    7534              :      the uses.  When putting the layout change at the site of the definition,
    7535              :      divvy up the cost among all consumers.  */
    7536       755920 :   if (m_optimize_size || def_vertex.weight <= def_vertex.out_weight)
    7537              :     {
    7538       733238 :       slpg_layout_cost cost = { def_vertex.weight * factor, m_optimize_size };
    7539       733238 :       cost.split (def_vertex.out_degree);
    7540       733238 :       return cost;
    7541              :     }
    7542        22682 :   return { use_vertex.weight * factor, m_optimize_size };
    7543              : }
    7544              : 
    7545              : /* UD represents a use-def link between FROM_NODE_I and a node in a later
    7546              :    partition; FROM_NODE_I could be the definition node or the use node.
    7547              :    The node at the other end of the link wants to use layout TO_LAYOUT_I.
    7548              :    Return the cost of any necessary fix-ups on edge UD, or return
    7549              :    slpg_layout_cost::impossible () if the change isn't possible.
    7550              : 
    7551              :    At this point, FROM_NODE_I's partition has chosen the cheapest
    7552              :    layout based on the information available so far, but this choice
    7553              :    is only provisional.  */
    7554              : 
    7555              : slpg_layout_cost
    7556       203388 : vect_optimize_slp_pass::forward_cost (graph_edge *ud, unsigned int from_node_i,
    7557              :                                       unsigned int to_layout_i)
    7558              : {
    7559       203388 :   auto &from_vertex = m_vertices[from_node_i];
    7560       203388 :   unsigned int from_partition_i = from_vertex.partition;
    7561       203388 :   slpg_partition_info &from_partition = m_partitions[from_partition_i];
    7562       203388 :   gcc_assert (from_partition.layout >= 0);
    7563              : 
    7564              :   /* First calculate the cost on the assumption that FROM_PARTITION sticks
    7565              :      with its current layout preference.  */
    7566       203388 :   slpg_layout_cost cost = slpg_layout_cost::impossible ();
    7567       203388 :   auto edge_cost = edge_layout_cost (ud, from_node_i,
    7568       203388 :                                      from_partition.layout, to_layout_i);
    7569       203388 :   if (edge_cost.is_possible ())
    7570              :     {
    7571       400058 :       auto &from_costs = partition_layout_costs (from_partition_i,
    7572       200029 :                                                  from_partition.layout);
    7573       200029 :       cost = from_costs.in_cost;
    7574       200029 :       cost.add_serial_cost (from_costs.internal_cost);
    7575       200029 :       cost.split (from_partition.out_degree);
    7576       200029 :       cost.add_serial_cost (edge_cost);
    7577              :     }
    7578         3359 :   else if (from_partition.layout == 0)
    7579              :     /* We must allow the source partition to have layout 0 as a fallback,
    7580              :        in case all other options turn out to be impossible.  */
    7581         3359 :     return cost;
    7582              : 
    7583              :   /* Take the minimum of that cost and the cost that applies if
    7584              :      FROM_PARTITION instead switches to TO_LAYOUT_I.  */
    7585       200029 :   auto &direct_layout_costs = partition_layout_costs (from_partition_i,
    7586              :                                                       to_layout_i);
    7587       200029 :   if (direct_layout_costs.is_possible ())
    7588              :     {
    7589       176128 :       slpg_layout_cost direct_cost = direct_layout_costs.in_cost;
    7590       176128 :       direct_cost.add_serial_cost (direct_layout_costs.internal_cost);
    7591       176128 :       direct_cost.split (from_partition.out_degree);
    7592       176128 :       if (!cost.is_possible ()
    7593       176128 :           || direct_cost.is_better_than (cost, m_optimize_size))
    7594        40187 :         cost = direct_cost;
    7595              :     }
    7596              : 
    7597       200029 :   return cost;
    7598              : }
    7599              : 
    7600              : /* UD represents a use-def link between TO_NODE_I and a node in an earlier
    7601              :    partition; TO_NODE_I could be the definition node or the use node.
    7602              :    The node at the other end of the link wants to use layout FROM_LAYOUT_I;
    7603              :    return the cost of any necessary fix-ups on edge UD, or
    7604              :    slpg_layout_cost::impossible () if the choice cannot be made.
    7605              : 
    7606              :    At this point, TO_NODE_I's partition has a fixed choice of layout.  */
    7607              : 
    7608              : slpg_layout_cost
    7609       182978 : vect_optimize_slp_pass::backward_cost (graph_edge *ud, unsigned int to_node_i,
    7610              :                                        unsigned int from_layout_i)
    7611              : {
    7612       182978 :   auto &to_vertex = m_vertices[to_node_i];
    7613       182978 :   unsigned int to_partition_i = to_vertex.partition;
    7614       182978 :   slpg_partition_info &to_partition = m_partitions[to_partition_i];
    7615       182978 :   gcc_assert (to_partition.layout >= 0);
    7616              : 
    7617              :   /* If TO_NODE_I is a VEC_PERM_EXPR consumer, see whether it can be
    7618              :      adjusted for this input having layout FROM_LAYOUT_I.  Assume that
    7619              :      any other inputs keep their current choice of layout.  */
    7620       182978 :   auto &to_costs = partition_layout_costs (to_partition_i,
    7621              :                                            to_partition.layout);
    7622       182978 :   if (ud->src == int (to_node_i)
    7623       182776 :       && SLP_TREE_PERMUTE_P (to_vertex.node))
    7624              :     {
    7625        11525 :       auto &from_partition = m_partitions[m_vertices[ud->dest].partition];
    7626        11525 :       auto old_layout = from_partition.layout;
    7627        11525 :       from_partition.layout = from_layout_i;
    7628        23050 :       int factor = internal_node_cost (to_vertex.node, -1,
    7629        11525 :                                        to_partition.layout);
    7630        11525 :       from_partition.layout = old_layout;
    7631        11525 :       if (factor >= 0)
    7632              :         {
    7633        10621 :           slpg_layout_cost cost = to_costs.out_cost;
    7634        21242 :           cost.add_serial_cost ({ to_vertex.weight * factor,
    7635        10621 :                                   m_optimize_size });
    7636        10621 :           cost.split (to_partition.in_degree);
    7637        10621 :           return cost;
    7638              :         }
    7639              :     }
    7640              : 
    7641              :   /* Compute the cost if we insert any necessary layout change on edge UD.  */
    7642       172357 :   auto edge_cost = edge_layout_cost (ud, to_node_i,
    7643       172357 :                                      to_partition.layout, from_layout_i);
    7644       172357 :   if (edge_cost.is_possible ())
    7645              :     {
    7646       172357 :       slpg_layout_cost cost = to_costs.out_cost;
    7647       172357 :       cost.add_serial_cost (to_costs.internal_cost);
    7648       172357 :       cost.split (to_partition.in_degree);
    7649       172357 :       cost.add_serial_cost (edge_cost);
    7650       172357 :       return cost;
    7651              :     }
    7652              : 
    7653            0 :   return slpg_layout_cost::impossible ();
    7654              : }
    7655              : 
    7656              : /* Make a forward pass through the partitions, accumulating input costs.
    7657              :    Make a tentative (provisional) choice of layout for each partition,
    7658              :    ensuring that this choice still allows later partitions to keep
    7659              :    their original layout.  */
    7660              : 
    7661              : void
    7662         6595 : vect_optimize_slp_pass::forward_pass ()
    7663              : {
    7664       135559 :   for (unsigned int partition_i = 0; partition_i < m_partitions.length ();
    7665              :        ++partition_i)
    7666              :     {
    7667       128964 :       auto &partition = m_partitions[partition_i];
    7668              : 
    7669              :       /* If the partition consists of a single VEC_PERM_EXPR, precompute
    7670              :          the incoming cost that would apply if every predecessor partition
    7671              :          keeps its current layout.  This is used within the loop below.  */
    7672       128964 :       slpg_layout_cost in_cost;
    7673       128964 :       slp_tree single_node = nullptr;
    7674       128964 :       if (partition.node_end == partition.node_begin + 1)
    7675              :         {
    7676       122589 :           unsigned int node_i = m_partitioned_nodes[partition.node_begin];
    7677       122589 :           single_node = m_vertices[node_i].node;
    7678       122589 :           if (SLP_TREE_PERMUTE_P (single_node))
    7679         4457 :             in_cost = total_in_cost (node_i);
    7680              :         }
    7681              : 
    7682              :       /* Go through the possible layouts.  Decide which ones are valid
    7683              :          for this partition and record which of the valid layouts has
    7684              :          the lowest cost.  */
    7685       128964 :       unsigned int min_layout_i = 0;
    7686       128964 :       slpg_layout_cost min_layout_cost = slpg_layout_cost::impossible ();
    7687       397289 :       for (unsigned int layout_i = 0; layout_i < m_perms.length (); ++layout_i)
    7688              :         {
    7689       268325 :           auto &layout_costs = partition_layout_costs (partition_i, layout_i);
    7690       268325 :           if (!layout_costs.is_possible ())
    7691        67581 :             continue;
    7692              : 
    7693              :           /* If the recorded layout is already 0 then the layout cannot
    7694              :              change.  */
    7695       268325 :           if (partition.layout == 0 && layout_i != 0)
    7696              :             {
    7697        45736 :               layout_costs.mark_impossible ();
    7698        45736 :               continue;
    7699              :             }
    7700              : 
    7701       222589 :           bool is_possible = true;
    7702       453047 :           for (unsigned int order_i = partition.node_begin;
    7703       453047 :                order_i < partition.node_end; ++order_i)
    7704              :             {
    7705       249128 :               unsigned int node_i = m_partitioned_nodes[order_i];
    7706       249128 :               auto &vertex = m_vertices[node_i];
    7707              : 
    7708              :               /* Reject the layout if it is individually incompatible
    7709              :                  with any node in the partition.  */
    7710       249128 :               if (!is_compatible_layout (vertex.node, layout_i))
    7711              :                 {
    7712        17094 :                   is_possible = false;
    7713        18670 :                   break;
    7714              :                 }
    7715              : 
    7716       622415 :               auto add_cost = [&](graph_edge *ud, unsigned int other_node_i)
    7717              :                 {
    7718       390381 :                   auto &other_vertex = m_vertices[other_node_i];
    7719       390381 :                   if (other_vertex.partition < vertex.partition)
    7720              :                     {
    7721              :                       /* Accumulate the incoming costs from earlier
    7722              :                          partitions, plus the cost of any layout changes
    7723              :                          on UD itself.  */
    7724       203388 :                       auto cost = forward_cost (ud, other_node_i, layout_i);
    7725       203388 :                       if (!cost.is_possible ())
    7726         3359 :                         is_possible = false;
    7727              :                       else
    7728       200029 :                         layout_costs.in_cost.add_parallel_cost (cost);
    7729              :                     }
    7730              :                   else
    7731              :                     /* Reject the layout if it would make layout 0 impossible
    7732              :                        for later partitions.  This amounts to testing that the
    7733              :                        target supports reversing the layout change on edges
    7734              :                        to later partitions.
    7735              : 
    7736              :                        In principle, it might be possible to push a layout
    7737              :                        change all the way down a graph, so that it never
    7738              :                        needs to be reversed and so that the target doesn't
    7739              :                        need to support the reverse operation.  But it would
    7740              :                        be awkward to bail out if we hit a partition that
    7741              :                        does not support the new layout, especially since
    7742              :                        we are not dealing with a lattice.  */
    7743       186993 :                     is_possible &= edge_layout_cost (ud, other_node_i, 0,
    7744       186993 :                                                      layout_i).is_possible ();
    7745       622415 :                 };
    7746       232034 :               for_each_partition_edge (node_i, add_cost);
    7747              : 
    7748              :               /* Accumulate the cost of using LAYOUT_I within NODE,
    7749              :                  both for the inputs and the outputs.  */
    7750       232034 :               int factor = internal_node_cost (vertex.node, layout_i,
    7751              :                                                layout_i);
    7752       232034 :               if (factor < 0)
    7753              :                 {
    7754         1576 :                   is_possible = false;
    7755         1576 :                   break;
    7756              :                 }
    7757       230458 :               else if (factor)
    7758        36372 :                 layout_costs.internal_cost.add_serial_cost
    7759        36372 :                   ({ vertex.weight * factor, m_optimize_size });
    7760              :             }
    7761       222589 :           if (!is_possible)
    7762              :             {
    7763        21845 :               layout_costs.mark_impossible ();
    7764        21845 :               continue;
    7765              :             }
    7766              : 
    7767              :           /* Combine the incoming and partition-internal costs.  */
    7768       200744 :           slpg_layout_cost combined_cost = layout_costs.in_cost;
    7769       200744 :           combined_cost.add_serial_cost (layout_costs.internal_cost);
    7770              : 
    7771              :           /* If this partition consists of a single VEC_PERM_EXPR, see
    7772              :              if the VEC_PERM_EXPR can be changed to support output layout
    7773              :              LAYOUT_I while keeping all the provisional choices of input
    7774              :              layout.  */
    7775       200744 :           if (single_node && SLP_TREE_PERMUTE_P (single_node))
    7776              :             {
    7777         7762 :               int factor = internal_node_cost (single_node, -1, layout_i);
    7778         7762 :               if (factor >= 0)
    7779              :                 {
    7780         7039 :                   auto weight = m_vertices[single_node->vertex].weight;
    7781         7039 :                   slpg_layout_cost internal_cost
    7782         7039 :                     = { weight * factor, m_optimize_size };
    7783              : 
    7784         7039 :                   slpg_layout_cost alt_cost = in_cost;
    7785         7039 :                   alt_cost.add_serial_cost (internal_cost);
    7786         7039 :                   if (alt_cost.is_better_than (combined_cost, m_optimize_size))
    7787              :                     {
    7788         2650 :                       combined_cost = alt_cost;
    7789         2650 :                       layout_costs.in_cost = in_cost;
    7790         2650 :                       layout_costs.internal_cost = internal_cost;
    7791              :                     }
    7792              :                 }
    7793              :             }
    7794              : 
    7795              :           /* Record the layout with the lowest cost.  Prefer layout 0 in
    7796              :              the event of a tie between it and another layout.  */
    7797       200744 :           if (!min_layout_cost.is_possible ()
    7798        71780 :               || combined_cost.is_better_than (min_layout_cost,
    7799        71780 :                                                m_optimize_size))
    7800              :             {
    7801       145977 :               min_layout_i = layout_i;
    7802       145977 :               min_layout_cost = combined_cost;
    7803              :             }
    7804              :         }
    7805              : 
    7806              :       /* This loop's handling of earlier partitions should ensure that
    7807              :          choosing the original layout for the current partition is no
    7808              :          less valid than it was in the original graph, even with the
    7809              :          provisional layout choices for those earlier partitions.  */
    7810       128964 :       gcc_assert (min_layout_cost.is_possible ());
    7811       128964 :       partition.layout = min_layout_i;
    7812              :     }
    7813         6595 : }
    7814              : 
    7815              : /* Make a backward pass through the partitions, accumulating output costs.
    7816              :    Make a final choice of layout for each partition.  */
    7817              : 
    7818              : void
    7819         6595 : vect_optimize_slp_pass::backward_pass ()
    7820              : {
    7821       142154 :   for (unsigned int partition_i = m_partitions.length (); partition_i-- > 0;)
    7822              :     {
    7823       128964 :       auto &partition = m_partitions[partition_i];
    7824              : 
    7825       128964 :       unsigned int min_layout_i = 0;
    7826       128964 :       slpg_layout_cost min_layout_cost = slpg_layout_cost::impossible ();
    7827       397289 :       for (unsigned int layout_i = 0; layout_i < m_perms.length (); ++layout_i)
    7828              :         {
    7829       268325 :           auto &layout_costs = partition_layout_costs (partition_i, layout_i);
    7830       268325 :           if (!layout_costs.is_possible ())
    7831        67581 :             continue;
    7832              : 
    7833              :           /* Accumulate the costs from successor partitions.  */
    7834       200744 :           bool is_possible = true;
    7835       427996 :           for (unsigned int order_i = partition.node_begin;
    7836       427996 :                order_i < partition.node_end; ++order_i)
    7837              :             {
    7838       227252 :               unsigned int node_i = m_partitioned_nodes[order_i];
    7839       227252 :               auto &vertex = m_vertices[node_i];
    7840       609794 :               auto add_cost = [&](graph_edge *ud, unsigned int other_node_i)
    7841              :                 {
    7842       382542 :                   auto &other_vertex = m_vertices[other_node_i];
    7843       382542 :                   auto &other_partition = m_partitions[other_vertex.partition];
    7844       382542 :                   if (other_vertex.partition > vertex.partition)
    7845              :                     {
    7846              :                       /* Accumulate the incoming costs from later
    7847              :                          partitions, plus the cost of any layout changes
    7848              :                          on UD itself.  */
    7849       182978 :                       auto cost = backward_cost (ud, other_node_i, layout_i);
    7850       182978 :                       if (!cost.is_possible ())
    7851            0 :                         is_possible = false;
    7852              :                       else
    7853       182978 :                         layout_costs.out_cost.add_parallel_cost (cost);
    7854              :                     }
    7855              :                   else
    7856              :                     /* Make sure that earlier partitions can (if necessary
    7857              :                        or beneficial) keep the layout that they chose in
    7858              :                        the forward pass.  This ensures that there is at
    7859              :                        least one valid choice of layout.  */
    7860       199564 :                     is_possible &= edge_layout_cost (ud, other_node_i,
    7861       199564 :                                                      other_partition.layout,
    7862       199564 :                                                      layout_i).is_possible ();
    7863       609794 :                 };
    7864       227252 :               for_each_partition_edge (node_i, add_cost);
    7865              :             }
    7866       200744 :           if (!is_possible)
    7867              :             {
    7868            0 :               layout_costs.mark_impossible ();
    7869            0 :               continue;
    7870              :             }
    7871              : 
    7872              :           /* Locally combine the costs from the forward and backward passes.
    7873              :              (This combined cost is not passed on, since that would lead
    7874              :              to double counting.)  */
    7875       200744 :           slpg_layout_cost combined_cost = layout_costs.in_cost;
    7876       200744 :           combined_cost.add_serial_cost (layout_costs.internal_cost);
    7877       200744 :           combined_cost.add_serial_cost (layout_costs.out_cost);
    7878              : 
    7879              :           /* Record the layout with the lowest cost.  Prefer layout 0 in
    7880              :              the event of a tie between it and another layout.  */
    7881       200744 :           if (!min_layout_cost.is_possible ()
    7882        71780 :               || combined_cost.is_better_than (min_layout_cost,
    7883        71780 :                                                m_optimize_size))
    7884              :             {
    7885       139559 :               min_layout_i = layout_i;
    7886       139559 :               min_layout_cost = combined_cost;
    7887              :             }
    7888              :         }
    7889              : 
    7890       128964 :       gcc_assert (min_layout_cost.is_possible ());
    7891       128964 :       partition.layout = min_layout_i;
    7892              :     }
    7893         6595 : }
    7894              : 
    7895              : /* Return a node that applies layout TO_LAYOUT_I to the original form of NODE.
    7896              :    NODE already has the layout that was selected for its partition.  */
    7897              : 
    7898              : slp_tree
    7899       177904 : vect_optimize_slp_pass::get_result_with_layout (slp_tree node,
    7900              :                                                 unsigned int to_layout_i)
    7901              : {
    7902       177904 :   unsigned int result_i = node->vertex * m_perms.length () + to_layout_i;
    7903       177904 :   slp_tree result = m_node_layouts[result_i];
    7904       177904 :   if (result)
    7905              :     return result;
    7906              : 
    7907       177052 :   if (SLP_TREE_DEF_TYPE (node) == vect_constant_def
    7908       177052 :       || (SLP_TREE_DEF_TYPE (node) == vect_external_def
    7909              :           /* We can't permute vector defs in place.  */
    7910        21728 :           && SLP_TREE_VEC_DEFS (node).is_empty ()))
    7911              :     {
    7912              :       /* If the vector is uniform or unchanged, there's nothing to do.  */
    7913        45216 :       if (to_layout_i == 0 || vect_slp_tree_uniform_p (node))
    7914              :         result = node;
    7915              :       else
    7916              :         {
    7917         2700 :           auto scalar_ops = SLP_TREE_SCALAR_OPS (node).copy ();
    7918         2700 :           result = vect_create_new_slp_node (scalar_ops);
    7919         2700 :           vect_slp_permute (m_perms[to_layout_i], scalar_ops, true);
    7920              :         }
    7921              :     }
    7922              :   else
    7923              :     {
    7924       131836 :       unsigned int partition_i = m_vertices[node->vertex].partition;
    7925       131836 :       unsigned int from_layout_i = m_partitions[partition_i].layout;
    7926       131836 :       if (from_layout_i == to_layout_i)
    7927       130763 :         return node;
    7928              : 
    7929              :       /* If NODE is itself a VEC_PERM_EXPR, try to create a parallel
    7930              :          permutation instead of a serial one.  Leave the new permutation
    7931              :          in TMP_PERM on success.  */
    7932         1073 :       auto_lane_permutation_t tmp_perm;
    7933         1073 :       unsigned int num_inputs = 1;
    7934         1073 :       if (SLP_TREE_PERMUTE_P (node))
    7935              :         {
    7936            7 :           tmp_perm.safe_splice (SLP_TREE_LANE_PERMUTATION (node));
    7937            7 :           if (from_layout_i != 0)
    7938            7 :             vect_slp_permute (m_perms[from_layout_i], tmp_perm, false);
    7939            7 :           if (to_layout_i != 0)
    7940            4 :             vect_slp_permute (m_perms[to_layout_i], tmp_perm, true);
    7941            7 :           if (vectorizable_slp_permutation_1 (m_vinfo, nullptr, node,
    7942              :                                               tmp_perm,
    7943            7 :                                               SLP_TREE_CHILDREN (node),
    7944              :                                               false) >= 0)
    7945            7 :             num_inputs = SLP_TREE_CHILDREN (node).length ();
    7946              :           else
    7947            0 :             tmp_perm.truncate (0);
    7948              :         }
    7949              : 
    7950         1073 :       if (dump_enabled_p ())
    7951              :         {
    7952           70 :           if (tmp_perm.length () > 0)
    7953            6 :             dump_printf_loc (MSG_NOTE, vect_location,
    7954              :                              "duplicating permutation node %p with"
    7955              :                              " layout %d\n",
    7956              :                              (void *) node, to_layout_i);
    7957              :           else
    7958           64 :             dump_printf_loc (MSG_NOTE, vect_location,
    7959              :                              "inserting permutation node in place of %p\n",
    7960              :                              (void *) node);
    7961              :         }
    7962              : 
    7963         1073 :       unsigned int num_lanes = SLP_TREE_LANES (node);
    7964         1073 :       result = vect_create_new_slp_node (num_inputs, VEC_PERM_EXPR);
    7965         1073 :       if (SLP_TREE_SCALAR_STMTS (node).exists ())
    7966              :         {
    7967         1068 :           auto &stmts = SLP_TREE_SCALAR_STMTS (result);
    7968         1068 :           stmts.safe_splice (SLP_TREE_SCALAR_STMTS (node));
    7969         1068 :           if (from_layout_i != 0)
    7970          450 :             vect_slp_permute (m_perms[from_layout_i], stmts, false);
    7971         1068 :           if (to_layout_i != 0)
    7972          628 :             vect_slp_permute (m_perms[to_layout_i], stmts, true);
    7973              :         }
    7974         1073 :       SLP_TREE_REPRESENTATIVE (result) = SLP_TREE_REPRESENTATIVE (node);
    7975         1073 :       SLP_TREE_LANES (result) = num_lanes;
    7976         1073 :       SLP_TREE_VECTYPE (result) = SLP_TREE_VECTYPE (node);
    7977         1073 :       result->vertex = -1;
    7978              : 
    7979         1073 :       auto &lane_perm = SLP_TREE_LANE_PERMUTATION (result);
    7980         1073 :       if (tmp_perm.length ())
    7981              :         {
    7982            7 :           lane_perm.safe_splice (tmp_perm);
    7983            7 :           SLP_TREE_CHILDREN (result).safe_splice (SLP_TREE_CHILDREN (node));
    7984              :         }
    7985              :       else
    7986              :         {
    7987         1066 :           lane_perm.create (num_lanes);
    7988         3300 :           for (unsigned j = 0; j < num_lanes; ++j)
    7989         2234 :             lane_perm.quick_push ({ 0, j });
    7990         1066 :           if (from_layout_i != 0)
    7991          443 :             vect_slp_permute (m_perms[from_layout_i], lane_perm, false);
    7992         1066 :           if (to_layout_i != 0)
    7993          629 :             vect_slp_permute (m_perms[to_layout_i], lane_perm, true);
    7994         1066 :           SLP_TREE_CHILDREN (result).safe_push (node);
    7995              :         }
    7996         4296 :       for (slp_tree child : SLP_TREE_CHILDREN (result))
    7997         1077 :         child->refcnt++;
    7998         1073 :     }
    7999        46289 :   m_node_layouts[result_i] = result;
    8000        46289 :   return result;
    8001              : }
    8002              : 
    8003              : /* Apply the chosen vector layouts to the SLP graph.  */
    8004              : 
    8005              : void
    8006        12525 : vect_optimize_slp_pass::materialize ()
    8007              : {
    8008              :   /* We no longer need the costs, so avoid having two O(N * P) arrays
    8009              :      live at the same time.  */
    8010        12525 :   m_partition_layout_costs.release ();
    8011        37575 :   m_node_layouts.safe_grow_cleared (m_vertices.length () * m_perms.length ());
    8012              : 
    8013        25050 :   auto_sbitmap fully_folded (m_vertices.length ());
    8014        12525 :   bitmap_clear (fully_folded);
    8015       192889 :   for (unsigned int node_i : m_partitioned_nodes)
    8016              :     {
    8017       155314 :       auto &vertex = m_vertices[node_i];
    8018       155314 :       slp_tree node = vertex.node;
    8019       155314 :       int layout_i = m_partitions[vertex.partition].layout;
    8020       155314 :       gcc_assert (layout_i >= 0);
    8021              : 
    8022              :       /* Rearrange the scalar statements to match the chosen layout.  */
    8023       155314 :       if (layout_i > 0)
    8024        22011 :         vect_slp_permute (m_perms[layout_i],
    8025        22011 :                           SLP_TREE_SCALAR_STMTS (node), true);
    8026              : 
    8027              :       /* Update load and lane permutations.  */
    8028       155314 :       if (SLP_TREE_PERMUTE_P (node))
    8029              :         {
    8030              :           /* First try to absorb the input vector layouts.  If that fails,
    8031              :              force the inputs to have layout LAYOUT_I too.  We checked that
    8032              :              that was possible before deciding to use nonzero output layouts.
    8033              :              (Note that at this stage we don't really have any guarantee that
    8034              :              the target supports the original VEC_PERM_EXPR.)  */
    8035         6664 :           auto &perm = SLP_TREE_LANE_PERMUTATION (node);
    8036         6664 :           auto_lane_permutation_t tmp_perm;
    8037         6664 :           tmp_perm.safe_splice (perm);
    8038         6664 :           change_vec_perm_layout (node, tmp_perm, -1, layout_i);
    8039         6664 :           if (vectorizable_slp_permutation_1 (m_vinfo, nullptr, node,
    8040              :                                               tmp_perm,
    8041         6664 :                                               SLP_TREE_CHILDREN (node),
    8042              :                                               false) >= 0)
    8043              :             {
    8044         6023 :               if (dump_enabled_p ()
    8045         6943 :                   && !std::equal (tmp_perm.begin (), tmp_perm.end (),
    8046              :                                   perm.begin ()))
    8047           58 :                 dump_printf_loc (MSG_NOTE, vect_location,
    8048              :                                  "absorbing input layouts into %p\n",
    8049              :                                  (void *) node);
    8050        34136 :               std::copy (tmp_perm.begin (), tmp_perm.end (), perm.begin ());
    8051         6023 :               bitmap_set_bit (fully_folded, node_i);
    8052              :             }
    8053              :           else
    8054              :             {
    8055              :               /* Not MSG_MISSED because it would make no sense to users.  */
    8056          641 :               if (dump_enabled_p ())
    8057           46 :                 dump_printf_loc (MSG_NOTE, vect_location,
    8058              :                                  "failed to absorb input layouts into %p\n",
    8059              :                                  (void *) node);
    8060          641 :               change_vec_perm_layout (nullptr, perm, layout_i, layout_i);
    8061              :             }
    8062         6664 :         }
    8063              :       else
    8064              :         {
    8065       148650 :           gcc_assert (!SLP_TREE_LANE_PERMUTATION (node).exists ());
    8066       148650 :           auto &load_perm = SLP_TREE_LOAD_PERMUTATION (node);
    8067       148650 :           if (layout_i > 0)
    8068              :             /* ???  When we handle non-bijective permutes the idea
    8069              :                is that we can force the load-permutation to be
    8070              :                { min, min + 1, min + 2, ... max }.  But then the
    8071              :                scalar defs might no longer match the lane content
    8072              :                which means wrong-code with live lane vectorization.
    8073              :                So we possibly have to have NULL entries for those.  */
    8074        21067 :             vect_slp_permute (m_perms[layout_i], load_perm, true);
    8075              :         }
    8076              :     }
    8077              : 
    8078              :   /* Do this before any nodes disappear, since it involves a walk
    8079              :      over the leaves.  */
    8080        12525 :   remove_redundant_permutations ();
    8081              : 
    8082              :   /* Replace each child with a correctly laid-out version.  */
    8083       192889 :   for (unsigned int node_i : m_partitioned_nodes)
    8084              :     {
    8085              :       /* Skip nodes that have already been handled above.  */
    8086       155314 :       if (bitmap_bit_p (fully_folded, node_i))
    8087         6023 :         continue;
    8088              : 
    8089       149291 :       auto &vertex = m_vertices[node_i];
    8090       149291 :       int in_layout_i = m_partitions[vertex.partition].layout;
    8091       149291 :       gcc_assert (in_layout_i >= 0);
    8092              : 
    8093              :       unsigned j;
    8094              :       slp_tree child;
    8095       447216 :       FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (vertex.node), j, child)
    8096              :         {
    8097       183921 :           if (!child)
    8098         6017 :             continue;
    8099              : 
    8100       177904 :           slp_tree new_child = get_result_with_layout (child, in_layout_i);
    8101       177904 :           if (new_child != child)
    8102              :             {
    8103         4342 :               vect_free_slp_tree (child);
    8104         4342 :               SLP_TREE_CHILDREN (vertex.node)[j] = new_child;
    8105         4342 :               new_child->refcnt += 1;
    8106              :             }
    8107              :         }
    8108              :     }
    8109        12525 : }
    8110              : 
    8111              : /* Elide load permutations that are not necessary.  Such permutations might
    8112              :    be pre-existing, rather than created by the layout optimizations.  */
    8113              : 
    8114              : void
    8115       709983 : vect_optimize_slp_pass::remove_redundant_permutations ()
    8116              : {
    8117      4717581 :   for (unsigned int node_i : m_leafs)
    8118              :     {
    8119      2587632 :       slp_tree node = m_vertices[node_i].node;
    8120      2587632 :       if (!SLP_TREE_LOAD_PERMUTATION (node).exists ())
    8121      1959358 :         continue;
    8122              : 
    8123              :       /* In basic block vectorization we allow any subchain of an interleaving
    8124              :          chain.
    8125              :          FORNOW: not in loop SLP because of realignment complications.  */
    8126       628274 :       if (is_a <bb_vec_info> (m_vinfo))
    8127              :         {
    8128       188888 :           bool subchain_p = true;
    8129              :           stmt_vec_info next_load_info = NULL;
    8130              :           stmt_vec_info load_info;
    8131              :           unsigned j;
    8132       188888 :           FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), j, load_info)
    8133              :             {
    8134       156477 :               if (j != 0
    8135       156477 :                   && (next_load_info != load_info
    8136        69650 :                       || ! load_info
    8137        69650 :                       || DR_GROUP_GAP (load_info) != 1))
    8138              :                 {
    8139              :                   subchain_p = false;
    8140              :                   break;
    8141              :                 }
    8142       125306 :               next_load_info = DR_GROUP_NEXT_ELEMENT (load_info);
    8143              :             }
    8144        63582 :           if (subchain_p)
    8145              :             {
    8146        32411 :               SLP_TREE_LOAD_PERMUTATION (node).release ();
    8147        32411 :               continue;
    8148              :             }
    8149              :         }
    8150              :       else
    8151              :         {
    8152       564692 :           loop_vec_info loop_vinfo = as_a<loop_vec_info> (m_vinfo);
    8153       564692 :           bool this_load_permuted = !vect_load_perm_consecutive_p (node, 0);
    8154              :           /* When this isn't a grouped access we know it's single element
    8155              :              and contiguous.  */
    8156       564692 :           if (!STMT_VINFO_GROUPED_ACCESS (SLP_TREE_SCALAR_STMTS (node)[0]))
    8157              :             {
    8158       443344 :               if (!this_load_permuted
    8159       443344 :                   && (known_eq (LOOP_VINFO_VECT_FACTOR (loop_vinfo), 1U)
    8160       442583 :                       || SLP_TREE_LANES (node) == 1))
    8161       442585 :                 SLP_TREE_LOAD_PERMUTATION (node).release ();
    8162       443344 :               continue;
    8163              :             }
    8164       121348 :           stmt_vec_info first_stmt_info
    8165       121348 :             = DR_GROUP_FIRST_ELEMENT (SLP_TREE_SCALAR_STMTS (node)[0]);
    8166       121852 :           if (!this_load_permuted
    8167              :               /* The load requires permutation when unrolling exposes
    8168              :                  a gap either because the group is larger than the SLP
    8169              :                  group-size or because there is a gap between the groups.  */
    8170       121348 :               && (known_eq (LOOP_VINFO_VECT_FACTOR (loop_vinfo), 1U)
    8171        98850 :                   || ((SLP_TREE_LANES (node) == DR_GROUP_SIZE (first_stmt_info))
    8172          136 :                       && DR_GROUP_GAP (first_stmt_info) == 0)))
    8173              :             {
    8174          504 :               SLP_TREE_LOAD_PERMUTATION (node).release ();
    8175          504 :               continue;
    8176              :             }
    8177              :         }
    8178              :     }
    8179       709983 : }
    8180              : 
    8181              : /* Print the partition graph and layout information to the dump file.  */
    8182              : 
    8183              : void
    8184          679 : vect_optimize_slp_pass::dump ()
    8185              : {
    8186          679 :   dump_printf_loc (MSG_NOTE, vect_location,
    8187              :                    "SLP optimize permutations:\n");
    8188         1371 :   for (unsigned int layout_i = 1; layout_i < m_perms.length (); ++layout_i)
    8189              :     {
    8190          692 :       dump_printf_loc (MSG_NOTE, vect_location, "  %d: { ", layout_i);
    8191          692 :       const char *sep = "";
    8192         5909 :       for (unsigned int idx : m_perms[layout_i])
    8193              :         {
    8194         3833 :           dump_printf (MSG_NOTE, "%s%d", sep, idx);
    8195         3833 :           sep = ", ";
    8196              :         }
    8197          692 :       dump_printf (MSG_NOTE, " }\n");
    8198              :     }
    8199          679 :   dump_printf_loc (MSG_NOTE, vect_location,
    8200              :                    "SLP optimize partitions:\n");
    8201         5666 :   for (unsigned int partition_i = 0; partition_i < m_partitions.length ();
    8202              :        ++partition_i)
    8203              :     {
    8204         4987 :       auto &partition = m_partitions[partition_i];
    8205         4987 :       dump_printf_loc (MSG_NOTE, vect_location,  "  -------------\n");
    8206         4987 :       dump_printf_loc (MSG_NOTE, vect_location,
    8207              :                        "  partition %d (layout %d):\n",
    8208              :                        partition_i, partition.layout);
    8209         4987 :       dump_printf_loc (MSG_NOTE, vect_location, "    nodes:\n");
    8210        10208 :       for (unsigned int order_i = partition.node_begin;
    8211        10208 :            order_i < partition.node_end; ++order_i)
    8212              :         {
    8213         5221 :           auto &vertex = m_vertices[m_partitioned_nodes[order_i]];
    8214        10442 :           dump_printf_loc (MSG_NOTE, vect_location, "      - %p:\n",
    8215         5221 :                            (void *) vertex.node);
    8216         5221 :           dump_printf_loc (MSG_NOTE, vect_location,
    8217              :                            "          weight: %f\n",
    8218              :                            vertex.weight.to_double ());
    8219         5221 :           if (vertex.out_degree)
    8220         4080 :             dump_printf_loc (MSG_NOTE, vect_location,
    8221              :                              "          out weight: %f (degree %d)\n",
    8222              :                              vertex.out_weight.to_double (),
    8223              :                              vertex.out_degree);
    8224         5221 :           if (SLP_TREE_PERMUTE_P (vertex.node))
    8225          506 :             dump_printf_loc (MSG_NOTE, vect_location,
    8226              :                              "          op: VEC_PERM_EXPR\n");
    8227         4715 :           else if (auto rep = SLP_TREE_REPRESENTATIVE (vertex.node))
    8228         4697 :             dump_printf_loc (MSG_NOTE, vect_location,
    8229              :                              "          op template: %G", rep->stmt);
    8230              :         }
    8231         4987 :       dump_printf_loc (MSG_NOTE, vect_location, "    edges:\n");
    8232        10208 :       for (unsigned int order_i = partition.node_begin;
    8233        10208 :            order_i < partition.node_end; ++order_i)
    8234              :         {
    8235         5221 :           unsigned int node_i = m_partitioned_nodes[order_i];
    8236         5221 :           auto &vertex = m_vertices[node_i];
    8237        15727 :           auto print_edge = [&](graph_edge *, unsigned int other_node_i)
    8238              :             {
    8239        10506 :               auto &other_vertex = m_vertices[other_node_i];
    8240        10506 :               if (other_vertex.partition < vertex.partition)
    8241         5253 :                 dump_printf_loc (MSG_NOTE, vect_location,
    8242              :                                  "      - %p [%d] --> %p\n",
    8243         5253 :                                  (void *) other_vertex.node,
    8244              :                                  other_vertex.partition,
    8245         5253 :                                  (void *) vertex.node);
    8246              :               else
    8247         5253 :                 dump_printf_loc (MSG_NOTE, vect_location,
    8248              :                                  "      - %p --> [%d] %p\n",
    8249         5253 :                                  (void *) vertex.node,
    8250              :                                  other_vertex.partition,
    8251         5253 :                                  (void *) other_vertex.node);
    8252        15727 :             };
    8253         5221 :           for_each_partition_edge (node_i, print_edge);
    8254              :         }
    8255              : 
    8256        15160 :       for (unsigned int layout_i = 0; layout_i < m_perms.length (); ++layout_i)
    8257              :         {
    8258        10173 :           auto &layout_costs = partition_layout_costs (partition_i, layout_i);
    8259        10173 :           if (layout_costs.is_possible ())
    8260              :             {
    8261         8384 :               dump_printf_loc (MSG_NOTE, vect_location,
    8262              :                                "    layout %d:%s\n", layout_i,
    8263         8384 :                                partition.layout == int (layout_i)
    8264              :                                ? " (*)" : "");
    8265         8384 :               slpg_layout_cost combined_cost = layout_costs.in_cost;
    8266         8384 :               combined_cost.add_serial_cost (layout_costs.internal_cost);
    8267         8384 :               combined_cost.add_serial_cost (layout_costs.out_cost);
    8268              : #define TEMPLATE "{depth: %f, total: %f}"
    8269         8384 :               dump_printf_loc (MSG_NOTE, vect_location,
    8270              :                                "        " TEMPLATE "\n",
    8271              :                                layout_costs.in_cost.depth.to_double (),
    8272              :                                layout_costs.in_cost.total.to_double ());
    8273         8384 :               dump_printf_loc (MSG_NOTE, vect_location,
    8274              :                                "      + " TEMPLATE "\n",
    8275              :                                layout_costs.internal_cost.depth.to_double (),
    8276              :                                layout_costs.internal_cost.total.to_double ());
    8277         8384 :               dump_printf_loc (MSG_NOTE, vect_location,
    8278              :                                "      + " TEMPLATE "\n",
    8279              :                                layout_costs.out_cost.depth.to_double (),
    8280              :                                layout_costs.out_cost.total.to_double ());
    8281         8384 :               dump_printf_loc (MSG_NOTE, vect_location,
    8282              :                                "      = " TEMPLATE "\n",
    8283              :                                combined_cost.depth.to_double (),
    8284              :                                combined_cost.total.to_double ());
    8285              : #undef TEMPLATE
    8286              :             }
    8287              :           else
    8288         1789 :             dump_printf_loc (MSG_NOTE, vect_location,
    8289              :                              "    layout %d: rejected\n", layout_i);
    8290              :         }
    8291              :     }
    8292          679 : }
    8293              : 
    8294              : /* Masked load lanes discovery.  */
    8295              : 
    8296              : void
    8297       709983 : vect_optimize_slp_pass::decide_masked_load_lanes ()
    8298              : {
    8299      7355399 :   for (auto v : m_vertices)
    8300              :     {
    8301      5225450 :       slp_tree node = v.node;
    8302      5225450 :       if (SLP_TREE_DEF_TYPE (node) != vect_internal_def
    8303      3659682 :           || SLP_TREE_PERMUTE_P (node))
    8304      1706719 :         continue;
    8305      3518731 :       stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node);
    8306      1692229 :       if (! STMT_VINFO_GROUPED_ACCESS (stmt_info)
    8307              :           /* The mask has to be uniform.  */
    8308       997933 :           || STMT_VINFO_SLP_VECT_ONLY (stmt_info)
    8309       997855 :           || ! is_a <gcall *> (STMT_VINFO_STMT (stmt_info))
    8310      3518816 :           || ! gimple_call_internal_p (STMT_VINFO_STMT (stmt_info),
    8311              :                                        IFN_MASK_LOAD))
    8312      3518698 :         continue;
    8313           33 :       stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
    8314           66 :       if (STMT_VINFO_STRIDED_P (stmt_info)
    8315           33 :           || compare_step_with_zero (m_vinfo, stmt_info) <= 0
    8316           63 :           || vect_load_lanes_supported (SLP_TREE_VECTYPE (node),
    8317           30 :                                         DR_GROUP_SIZE (stmt_info),
    8318              :                                         true) == IFN_LAST)
    8319           33 :         continue;
    8320              : 
    8321              :       /* Uniform masks need to be suitably represented.  */
    8322            0 :       slp_tree mask = SLP_TREE_CHILDREN (node)[0];
    8323            0 :       if (!SLP_TREE_PERMUTE_P (mask)
    8324            0 :           || SLP_TREE_CHILDREN (mask).length () != 1)
    8325            0 :         continue;
    8326            0 :       bool match = true;
    8327            0 :       for (auto perm : SLP_TREE_LANE_PERMUTATION (mask))
    8328            0 :         if (perm.first != 0 || perm.second != 0)
    8329              :           {
    8330              :             match = false;
    8331              :             break;
    8332              :           }
    8333            0 :       if (!match)
    8334            0 :         continue;
    8335              : 
    8336              :       /* Now see if the consumer side matches.  */
    8337            0 :       for (graph_edge *pred = m_slpg->vertices[node->vertex].pred;
    8338            0 :            pred; pred = pred->pred_next)
    8339              :         {
    8340            0 :           slp_tree pred_node = m_vertices[pred->src].node;
    8341              :           /* All consumers should be a permute with a single outgoing lane.  */
    8342            0 :           if (!SLP_TREE_PERMUTE_P (pred_node)
    8343            0 :               || SLP_TREE_LANES (pred_node) != 1)
    8344              :             {
    8345              :               match = false;
    8346              :               break;
    8347              :             }
    8348            0 :           gcc_assert (SLP_TREE_CHILDREN (pred_node).length () == 1);
    8349              :         }
    8350            0 :       if (!match)
    8351            0 :         continue;
    8352              :       /* Now we can mark the nodes as to use load lanes.  */
    8353            0 :       node->ldst_lanes = true;
    8354            0 :       for (graph_edge *pred = m_slpg->vertices[node->vertex].pred;
    8355            0 :            pred; pred = pred->pred_next)
    8356            0 :         m_vertices[pred->src].node->ldst_lanes = true;
    8357              :       /* The catch is we have to massage the mask.  We have arranged
    8358              :          analyzed uniform masks to be represented by a splat VEC_PERM
    8359              :          which we can now simply elide as we cannot easily re-do SLP
    8360              :          discovery here.  */
    8361            0 :       slp_tree new_mask = SLP_TREE_CHILDREN (mask)[0];
    8362            0 :       SLP_TREE_REF_COUNT (new_mask)++;
    8363            0 :       SLP_TREE_CHILDREN (node)[0] = new_mask;
    8364            0 :       vect_free_slp_tree (mask);
    8365              :     }
    8366       709983 : }
    8367              : 
    8368              : /* Perform legitimizing attempts.  This is intended to improve the
    8369              :    situation when layout 0 is not valid which is a situation the cost
    8370              :    based propagation does not handle well.
    8371              :    Return true if further layout optimization is possible, false if
    8372              :    the layout configuration should be considered final.  */
    8373              : 
    8374              : bool
    8375        12525 : vect_optimize_slp_pass::legitimize ()
    8376              : {
    8377              :   /* Perform a very simple legitimizing attempt by attempting to choose
    8378              :      a single layout for all partitions that will make all permutations
    8379              :      a noop.  That should also be the optimal layout choice in case
    8380              :      layout zero is legitimate.
    8381              :      ???  Disconnected components of the SLP graph could have distinct
    8382              :      single layouts.  */
    8383        12525 :   int single_layout_i = -1;
    8384        12525 :   unsigned deferred_up_to = -1U;
    8385        39961 :   for (unsigned partition_i = 0; partition_i < m_partitions.length ();
    8386              :        ++partition_i)
    8387              :     {
    8388        34016 :       auto &partition = m_partitions[partition_i];
    8389        34016 :       if (single_layout_i == -1)
    8390              :         {
    8391        16374 :           single_layout_i = partition.layout;
    8392        16374 :           deferred_up_to = partition_i;
    8393              :         }
    8394        17642 :       else if (partition.layout == single_layout_i || partition.layout == -1)
    8395              :         ;
    8396              :       else
    8397              :         single_layout_i = 0;
    8398        30734 :       if (single_layout_i == 0)
    8399              :         return true;
    8400              : 
    8401        27525 :       if (single_layout_i != -1
    8402        27525 :           && !is_compatible_layout (partition, single_layout_i))
    8403              :         return true;
    8404              :     }
    8405              : 
    8406         5945 :   if (single_layout_i <= 0)
    8407              :     return true;
    8408              : 
    8409         6090 :   for (unsigned partition_i = 0; partition_i < deferred_up_to; ++partition_i)
    8410          160 :     if (!is_compatible_layout (m_partitions[partition_i],
    8411              :                                single_layout_i))
    8412              :       return true;
    8413              : 
    8414        16806 :   for (unsigned partition_i = 0; partition_i < m_partitions.length ();
    8415              :        ++partition_i)
    8416              :     {
    8417        10876 :       auto &partition = m_partitions[partition_i];
    8418        10876 :       partition.layout = single_layout_i;
    8419              :     }
    8420              : 
    8421              :   return false;
    8422              : }
    8423              : 
    8424              : /* Main entry point for the SLP graph optimization pass.  */
    8425              : 
    8426              : void
    8427       709983 : vect_optimize_slp_pass::run ()
    8428              : {
    8429       709983 :   build_graph ();
    8430       709983 :   create_partitions ();
    8431       709983 :   start_choosing_layouts ();
    8432       709983 :   if (m_perms.length () > 1)
    8433              :     {
    8434        12525 :       if (legitimize ())
    8435              :         {
    8436         6595 :           forward_pass ();
    8437         6595 :           backward_pass ();
    8438              :         }
    8439        12525 :       if (dump_enabled_p ())
    8440          679 :         dump ();
    8441        12525 :       materialize ();
    8442        50678 :       while (!m_perms.is_empty ())
    8443        25628 :         m_perms.pop ().release ();
    8444              :     }
    8445              :   else
    8446       697458 :     remove_redundant_permutations ();
    8447       709983 :   free_graph (m_slpg);
    8448       709983 :   build_graph ();
    8449       709983 :   decide_masked_load_lanes ();
    8450       709983 :   free_graph (m_slpg);
    8451       709983 : }
    8452              : 
    8453              : /* Apply CSE to NODE and its children using BST_MAP.  */
    8454              : 
    8455              : static void
    8456      5641577 : vect_cse_slp_nodes (scalar_stmts_to_slp_tree_map_t *bst_map, slp_tree& node)
    8457              : {
    8458      5641577 :   bool put_p = false;
    8459      5641577 :   if (SLP_TREE_DEF_TYPE (node) == vect_internal_def
    8460              :       /* Besides some VEC_PERM_EXPR, two-operator nodes also
    8461              :          lack scalar stmts and thus CSE doesn't work via bst_map.  Ideally
    8462              :          we'd have sth that works for all internal and external nodes.  */
    8463      5641577 :       && !SLP_TREE_SCALAR_STMTS (node).is_empty ())
    8464              :     {
    8465      4047880 :       slp_tree *leader = bst_map->get (SLP_TREE_SCALAR_STMTS (node));
    8466      4047880 :       if (leader)
    8467              :         {
    8468              :           /* We've visited this node already.  */
    8469       419381 :           if (!*leader || *leader == node)
    8470              :             return;
    8471              : 
    8472         4262 :           if (dump_enabled_p ())
    8473          912 :             dump_printf_loc (MSG_NOTE, vect_location,
    8474              :                              "re-using SLP tree %p for %p\n",
    8475              :                              (void *)*leader, (void *)node);
    8476         4262 :           vect_free_slp_tree (node);
    8477         4262 :           (*leader)->refcnt += 1;
    8478         4262 :           node = *leader;
    8479         4262 :           return;
    8480              :         }
    8481              : 
    8482              :       /* Avoid creating a cycle by populating the map only after recursion.  */
    8483      3628499 :       bst_map->put (SLP_TREE_SCALAR_STMTS (node).copy (), nullptr);
    8484      3628499 :       node->refcnt += 1;
    8485      3628499 :       put_p = true;
    8486              :       /* And recurse.  */
    8487              :     }
    8488              : 
    8489     15608406 :   for (slp_tree &child : SLP_TREE_CHILDREN (node))
    8490      4571352 :     if (child)
    8491      4116216 :       vect_cse_slp_nodes (bst_map, child);
    8492              : 
    8493              :   /* Now record the node for CSE in other siblings.  */
    8494      5222196 :   if (put_p)
    8495      3628499 :     *bst_map->get (SLP_TREE_SCALAR_STMTS (node)) = node;
    8496              : }
    8497              : 
    8498              : /* Optimize the SLP graph of VINFO.  */
    8499              : 
    8500              : void
    8501      1094418 : vect_optimize_slp (vec_info *vinfo)
    8502              : {
    8503      1094418 :   if (vinfo->slp_instances.is_empty ())
    8504              :     return;
    8505       709983 :   vect_optimize_slp_pass (vinfo).run ();
    8506              : 
    8507              :   /* Apply CSE again to nodes after permute optimization.  */
    8508       709983 :   scalar_stmts_to_slp_tree_map_t *bst_map
    8509       709983 :     = new scalar_stmts_to_slp_tree_map_t ();
    8510              : 
    8511      3655310 :   for (auto inst : vinfo->slp_instances)
    8512      1525361 :     vect_cse_slp_nodes (bst_map, SLP_INSTANCE_TREE (inst));
    8513              : 
    8514       709983 :   release_scalar_stmts_to_slp_tree_map (bst_map);
    8515              : }
    8516              : 
    8517              : /* Gather loads reachable from the individual SLP graph entries.  */
    8518              : 
    8519              : void
    8520      1094418 : vect_gather_slp_loads (vec_info *vinfo)
    8521              : {
    8522      1094418 :   unsigned i;
    8523      1094418 :   slp_instance instance;
    8524      2619779 :   FOR_EACH_VEC_ELT (vinfo->slp_instances, i, instance)
    8525              :     {
    8526      1525361 :       hash_set<slp_tree> visited;
    8527      1525361 :       vect_gather_slp_loads (SLP_INSTANCE_LOADS (instance),
    8528              :                              SLP_INSTANCE_TREE (instance), visited);
    8529      1525361 :     }
    8530      1094418 : }
    8531              : 
    8532              : /* For NODE update VF based on the number of lanes and the vector types
    8533              :    used.  */
    8534              : 
    8535              : static void
    8536      4469595 : vect_update_slp_vf_for_node (slp_tree node, poly_uint64 &vf,
    8537              :                              hash_set<slp_tree> &visited)
    8538              : {
    8539      4469595 :   if (!node || SLP_TREE_DEF_TYPE (node) != vect_internal_def)
    8540      1616674 :     return;
    8541      3227550 :   if (visited.add (node))
    8542              :     return;
    8543              : 
    8544     10861640 :   for (slp_tree child : SLP_TREE_CHILDREN (node))
    8545      3677509 :     vect_update_slp_vf_for_node (child, vf, visited);
    8546              : 
    8547              :   /* We do not visit SLP nodes for constants or externals - those neither
    8548              :      have a vector type set yet (vectorizable_* does this) nor do they
    8549              :      have max_nunits set.  Instead we rely on internal nodes max_nunit
    8550              :      to cover constant/external operands.
    8551              :      Note that when we stop using fixed size vectors externs and constants
    8552              :      shouldn't influence the (minimum) vectorization factor, instead
    8553              :      vectorizable_* should honor the vectorization factor when trying to
    8554              :      assign vector types to constants and externals and cause iteration
    8555              :      to a higher vectorization factor when required.  */
    8556      2852921 :   poly_uint64 node_vf
    8557      2852921 :     = calculate_unrolling_factor (node->max_nunits, SLP_TREE_LANES (node));
    8558      2852921 :   vf = force_common_multiple (vf, node_vf);
    8559              : 
    8560              :   /* For permute nodes that are fed from externs or constants we have to
    8561              :      consider their number of lanes as well.  Likewise for store-lanes.  */
    8562      2852921 :   if (SLP_TREE_PERMUTE_P (node) || node->ldst_lanes)
    8563       717012 :     for (slp_tree child : SLP_TREE_CHILDREN (node))
    8564       193116 :       if (SLP_TREE_DEF_TYPE (child) != vect_internal_def)
    8565              :         {
    8566         3599 :           poly_uint64 child_vf
    8567         3599 :             = calculate_unrolling_factor (node->max_nunits,
    8568              :                                           SLP_TREE_LANES (child));
    8569         3599 :           vf = force_common_multiple (vf, child_vf);
    8570              :         }
    8571              : }
    8572              : 
    8573              : /* For each possible SLP instance decide whether to SLP it and calculate overall
    8574              :    unrolling factor needed to SLP the loop.  Return TRUE if decided to SLP at
    8575              :    least one instance.  */
    8576              : 
    8577              : bool
    8578       497099 : vect_make_slp_decision (loop_vec_info loop_vinfo)
    8579              : {
    8580       497099 :   unsigned int i;
    8581       497099 :   poly_uint64 unrolling_factor = 1;
    8582       497099 :   const vec<slp_instance> &slp_instances
    8583              :     = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
    8584       497099 :   slp_instance instance;
    8585       497099 :   int decided_to_slp = 0;
    8586              : 
    8587       497099 :   DUMP_VECT_SCOPE ("vect_make_slp_decision");
    8588              : 
    8589       497099 :   hash_set<slp_tree> visited;
    8590      1289185 :   FOR_EACH_VEC_ELT (slp_instances, i, instance)
    8591              :     {
    8592       792086 :       slp_tree root = SLP_INSTANCE_TREE (instance);
    8593              : 
    8594              :       /* All unroll factors have the form:
    8595              : 
    8596              :            GET_MODE_SIZE (vinfo->vector_mode) * X
    8597              : 
    8598              :          for some rational X, so they must have a common multiple.  */
    8599       792086 :       vect_update_slp_vf_for_node (root, unrolling_factor, visited);
    8600              : 
    8601              :       /* If all instances ended up with vector(1) T roots make sure to
    8602              :          not vectorize.  RVV for example relies on loop vectorization
    8603              :          when some instances are essentially kept scalar.  See PR121048.  */
    8604       792086 :       if (SLP_TREE_VECTYPE (root)
    8605       792086 :           && known_gt (TYPE_VECTOR_SUBPARTS (SLP_TREE_VECTYPE (root)), 1U))
    8606       643463 :         decided_to_slp++;
    8607              :     }
    8608              : 
    8609       497099 :   LOOP_VINFO_VECT_FACTOR (loop_vinfo) = unrolling_factor;
    8610              : 
    8611       497099 :   if (decided_to_slp && dump_enabled_p ())
    8612              :     {
    8613        19489 :       dump_printf_loc (MSG_NOTE, vect_location,
    8614              :                        "Decided to SLP %d instances. Unrolling factor ",
    8615              :                        decided_to_slp);
    8616        19489 :       dump_dec (MSG_NOTE, unrolling_factor);
    8617        19489 :       dump_printf (MSG_NOTE, "\n");
    8618              :     }
    8619              : 
    8620       497099 :   return (decided_to_slp > 0);
    8621       497099 : }
    8622              : 
    8623              : /* Initialize a bb_vec_info struct for the statements in BBS basic blocks.  */
    8624              : 
    8625      2251752 : _bb_vec_info::_bb_vec_info (vec<basic_block> _bbs, vec_info_shared *shared)
    8626              :   : vec_info (vec_info::bb, shared),
    8627      2251752 :     roots (vNULL)
    8628              : {
    8629              :   /* The region we are operating on.  bbs[0] is the entry, excluding
    8630              :      its PHI nodes.  In the future we might want to track an explicit
    8631              :      entry edge to cover bbs[0] PHI nodes and have a region entry
    8632              :      insert location.  */
    8633      2251752 :   bbs = _bbs.address ();
    8634      2251752 :   nbbs = _bbs.length ();
    8635              : 
    8636     18030778 :   for (unsigned i = 0; i < nbbs; ++i)
    8637              :     {
    8638     15779026 :       if (i != 0)
    8639     20522277 :         for (gphi_iterator si = gsi_start_phis (bbs[i]); !gsi_end_p (si);
    8640      6995003 :              gsi_next (&si))
    8641              :           {
    8642      6995003 :             gphi *phi = si.phi ();
    8643      6995003 :             gimple_set_uid (phi, 0);
    8644      6995003 :             add_stmt (phi);
    8645              :           }
    8646     31558052 :       for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]);
    8647    142319577 :            !gsi_end_p (gsi); gsi_next (&gsi))
    8648              :         {
    8649    126540551 :           gimple *stmt = gsi_stmt (gsi);
    8650    126540551 :           gimple_set_uid (stmt, 0);
    8651    126540551 :           if (is_gimple_debug (stmt) || is_a <glabel *> (stmt))
    8652     80688711 :             continue;
    8653     45851840 :           add_stmt (stmt);
    8654              :         }
    8655              :     }
    8656      2251752 : }
    8657              : 
    8658              : 
    8659              : /* Free BB_VINFO struct, as well as all the stmt_vec_info structs of all the
    8660              :    stmts in the basic block.  */
    8661              : 
    8662      2251752 : _bb_vec_info::~_bb_vec_info ()
    8663              : {
    8664              :   /* Reset region marker.  */
    8665     18030778 :   for (unsigned i = 0; i < nbbs; ++i)
    8666              :     {
    8667     15779026 :       if (i != 0)
    8668     20538481 :         for (gphi_iterator si = gsi_start_phis (bbs[i]); !gsi_end_p (si);
    8669      7011207 :              gsi_next (&si))
    8670              :           {
    8671      7011207 :             gphi *phi = si.phi ();
    8672      7011207 :             gimple_set_uid (phi, -1);
    8673              :           }
    8674     31558052 :       for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]);
    8675    142280674 :            !gsi_end_p (gsi); gsi_next (&gsi))
    8676              :         {
    8677    126501648 :           gimple *stmt = gsi_stmt (gsi);
    8678    126501648 :           gimple_set_uid (stmt, -1);
    8679              :         }
    8680              :     }
    8681              : 
    8682      3631690 :   for (unsigned i = 0; i < roots.length (); ++i)
    8683              :     {
    8684      1379938 :       roots[i].stmts.release ();
    8685      1379938 :       roots[i].roots.release ();
    8686      1379938 :       roots[i].remain.release ();
    8687              :     }
    8688      2251752 :   roots.release ();
    8689      2251752 : }
    8690              : 
    8691              : /* Subroutine of vect_slp_analyze_node_operations.  Handle the root of NODE,
    8692              :    given then that child nodes have already been processed, and that
    8693              :    their def types currently match their SLP node's def type.  */
    8694              : 
    8695              : static bool
    8696      2716329 : vect_slp_analyze_node_operations_1 (vec_info *vinfo, slp_tree node,
    8697              :                                     slp_instance node_instance,
    8698              :                                     stmt_vector_for_cost *cost_vec)
    8699              : {
    8700              :   /* Handle purely internal nodes.  */
    8701      2716329 :   if (SLP_TREE_PERMUTE_P (node))
    8702              :     {
    8703        82375 :       if (!vectorizable_slp_permutation (vinfo, NULL, node, cost_vec))
    8704              :         return false;
    8705              : 
    8706              :       stmt_vec_info slp_stmt_info;
    8707              :       unsigned int i;
    8708       202780 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, slp_stmt_info)
    8709              :         {
    8710       122028 :           if (slp_stmt_info
    8711       116357 :               && STMT_VINFO_LIVE_P (slp_stmt_info)
    8712       122028 :               && !vectorizable_live_operation (vinfo, slp_stmt_info, node,
    8713              :                                                node_instance, i,
    8714              :                                                false, cost_vec))
    8715              :             return false;
    8716              :         }
    8717        80752 :       SLP_TREE_TYPE (node) = permute_info_type;
    8718        80752 :       return true;
    8719              :     }
    8720              : 
    8721      2633954 :   return vect_analyze_stmt (vinfo, node, node_instance, cost_vec);
    8722              : }
    8723              : 
    8724              : static int
    8725      1929307 : sort_ints (const void *a_, const void *b_)
    8726              : {
    8727      1929307 :   int a = *(const int *)a_;
    8728      1929307 :   int b = *(const int *)b_;
    8729      1929307 :   return a - b;
    8730              : }
    8731              : 
    8732              : /* Verify if we can externalize a set of internal defs.  */
    8733              : 
    8734              : static bool
    8735       411492 : vect_slp_can_convert_to_external (const vec<stmt_vec_info> &stmts)
    8736              : {
    8737              :   /* Constant generation uses get_later_stmt which can only handle
    8738              :      defs from the same BB or a set of defs that can be ordered
    8739              :      with a dominance query.  */
    8740       411492 :   basic_block bb = NULL;
    8741       411492 :   bool all_same = true;
    8742       411492 :   auto_vec<int> bbs;
    8743       822984 :   bbs.reserve_exact (stmts.length ());
    8744      2215618 :   for (stmt_vec_info stmt : stmts)
    8745              :     {
    8746       981142 :       if (!stmt)
    8747              :         return false;
    8748       981142 :       else if (!bb)
    8749       411492 :         bb = gimple_bb (stmt->stmt);
    8750       569650 :       else if (gimple_bb (stmt->stmt) != bb)
    8751       187007 :         all_same = false;
    8752       981142 :       bbs.quick_push (gimple_bb (stmt->stmt)->index);
    8753              :     }
    8754       411492 :   if (all_same)
    8755              :     return true;
    8756              : 
    8757              :   /* Produce a vector of unique BB indexes for the defs.  */
    8758       140100 :   bbs.qsort (sort_ints);
    8759              :   unsigned i, j;
    8760       338842 :   for (i = 1, j = 1; i < bbs.length (); ++i)
    8761       198742 :     if (bbs[i] != bbs[j-1])
    8762       149669 :       bbs[j++] = bbs[i];
    8763       140100 :   gcc_assert (j >= 2);
    8764       140100 :   bbs.truncate (j);
    8765              : 
    8766       280200 :   if (bbs.length () == 2)
    8767       136573 :     return (dominated_by_p (CDI_DOMINATORS,
    8768       136573 :                             BASIC_BLOCK_FOR_FN (cfun, bbs[0]),
    8769       136573 :                             BASIC_BLOCK_FOR_FN (cfun, bbs[1]))
    8770       266891 :             || dominated_by_p (CDI_DOMINATORS,
    8771       130318 :                                BASIC_BLOCK_FOR_FN (cfun, bbs[1]),
    8772       130318 :                                BASIC_BLOCK_FOR_FN (cfun, bbs[0])));
    8773              : 
    8774              :   /* ???  For more than two BBs we can sort the vector and verify the
    8775              :      result is a total order.  But we can't use vec::qsort with a
    8776              :      compare function using a dominance query since there's no way to
    8777              :      signal failure and any fallback for an unordered pair would
    8778              :      fail qsort_chk later.
    8779              :      For now simply hope that ordering after BB index provides the
    8780              :      best candidate total order.  If required we can implement our
    8781              :      own mergesort or export an entry without checking.  */
    8782       428060 :   for (unsigned i = 1; i < bbs.length (); ++i)
    8783        13072 :     if (!dominated_by_p (CDI_DOMINATORS,
    8784        13072 :                          BASIC_BLOCK_FOR_FN (cfun, bbs[i]),
    8785        13072 :                          BASIC_BLOCK_FOR_FN (cfun, bbs[i-1])))
    8786              :       return false;
    8787              : 
    8788              :   return true;
    8789       411492 : }
    8790              : 
    8791              : /* Try to build NODE from scalars, returning true on success.
    8792              :    NODE_INSTANCE is the SLP instance that contains NODE.  */
    8793              : 
    8794              : static bool
    8795       636956 : vect_slp_convert_to_external (vec_info *vinfo, slp_tree node,
    8796              :                               slp_instance node_instance)
    8797              : {
    8798       636956 :   stmt_vec_info stmt_info;
    8799       636956 :   unsigned int i;
    8800              : 
    8801       636956 :   if (!is_a <bb_vec_info> (vinfo)
    8802        90910 :       || node == SLP_INSTANCE_TREE (node_instance)
    8803        31087 :       || !SLP_TREE_SCALAR_STMTS (node).exists ()
    8804        31046 :       || vect_contains_pattern_stmt_p (SLP_TREE_SCALAR_STMTS (node))
    8805              :       /* Force the mask use to be built from scalars instead.  */
    8806        23053 :       || VECTOR_BOOLEAN_TYPE_P (SLP_TREE_VECTYPE (node))
    8807       659772 :       || !vect_slp_can_convert_to_external (SLP_TREE_SCALAR_STMTS (node)))
    8808       614140 :     return false;
    8809              : 
    8810        22816 :   if (dump_enabled_p ())
    8811           74 :     dump_printf_loc (MSG_NOTE, vect_location,
    8812              :                      "Building vector operands of %p from scalars instead\n",
    8813              :                      (void *) node);
    8814              : 
    8815              :   /* Don't remove and free the child nodes here, since they could be
    8816              :      referenced by other structures.  The analysis and scheduling phases
    8817              :      (need to) ignore child nodes of anything that isn't vect_internal_def.  */
    8818        22816 :   unsigned int group_size = SLP_TREE_LANES (node);
    8819        22816 :   SLP_TREE_DEF_TYPE (node) = vect_external_def;
    8820              :   /* Invariants get their vector type from the uses.  */
    8821        22816 :   SLP_TREE_VECTYPE (node) = NULL_TREE;
    8822        22816 :   SLP_TREE_SCALAR_OPS (node).safe_grow (group_size, true);
    8823        22816 :   SLP_TREE_LOAD_PERMUTATION (node).release ();
    8824        80500 :   FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
    8825              :     {
    8826        57684 :       tree lhs = gimple_get_lhs (vect_orig_stmt (stmt_info)->stmt);
    8827        57684 :       SLP_TREE_SCALAR_OPS (node)[i] = lhs;
    8828              :     }
    8829              :   return true;
    8830              : }
    8831              : 
    8832              : /* Return true if all elements of the slice are the same.  */
    8833              : bool
    8834       449684 : vect_scalar_ops_slice::all_same_p () const
    8835              : {
    8836       500863 :   for (unsigned int i = 1; i < length; ++i)
    8837       414528 :     if (!operand_equal_p (op (0), op (i)))
    8838              :       return false;
    8839              :   return true;
    8840              : }
    8841              : 
    8842              : hashval_t
    8843       417965 : vect_scalar_ops_slice_hash::hash (const value_type &s)
    8844              : {
    8845       417965 :   hashval_t hash = 0;
    8846      1600839 :   for (unsigned i = 0; i < s.length; ++i)
    8847      1182874 :     hash = iterative_hash_expr (s.op (i), hash);
    8848       417965 :   return hash;
    8849              : }
    8850              : 
    8851              : bool
    8852       228135 : vect_scalar_ops_slice_hash::equal (const value_type &s1,
    8853              :                                    const compare_type &s2)
    8854              : {
    8855       228135 :   if (s1.length != s2.length)
    8856              :     return false;
    8857       393860 :   for (unsigned i = 0; i < s1.length; ++i)
    8858       343584 :     if (!operand_equal_p (s1.op (i), s2.op (i)))
    8859              :       return false;
    8860              :   return true;
    8861              : }
    8862              : 
    8863              : /* Compute the prologue cost for invariant or constant operands represented
    8864              :    by NODE.  */
    8865              : 
    8866              : static void
    8867      1092578 : vect_prologue_cost_for_slp (vec_info *vinfo, slp_tree node,
    8868              :                             stmt_vector_for_cost *cost_vec)
    8869              : {
    8870              :   /* There's a special case of an existing vector, that costs nothing.  */
    8871      1092578 :   if (SLP_TREE_SCALAR_OPS (node).length () == 0
    8872      1092578 :       && !SLP_TREE_VEC_DEFS (node).is_empty ())
    8873         2271 :     return;
    8874              :   /* Without looking at the actual initializer a vector of
    8875              :      constants can be implemented as load from the constant pool.
    8876              :      When all elements are the same we can use a splat.  */
    8877      1090307 :   tree vectype = SLP_TREE_VECTYPE (node);
    8878      1090307 :   unsigned group_size = SLP_TREE_LANES (node);
    8879      1090307 :   unsigned HOST_WIDE_INT const_nunits;
    8880      1090307 :   unsigned nelt_limit;
    8881      1090307 :   unsigned nvectors = vect_get_num_copies (vinfo, node);
    8882      1090307 :   auto ops = &SLP_TREE_SCALAR_OPS (node);
    8883      1090307 :   auto_vec<unsigned int> starts (nvectors);
    8884      1090307 :   if (TYPE_VECTOR_SUBPARTS (vectype).is_constant (&const_nunits)
    8885      1090307 :       && ! multiple_p (const_nunits, group_size))
    8886              :     {
    8887        65919 :       nelt_limit = const_nunits;
    8888        65919 :       hash_set<vect_scalar_ops_slice_hash> vector_ops;
    8889       273535 :       for (unsigned int i = 0; i < nvectors; ++i)
    8890       207616 :         if (!vector_ops.add ({ ops, i * nelt_limit, nelt_limit }))
    8891       157340 :           starts.quick_push (i * nelt_limit);
    8892        65919 :     }
    8893              :   else
    8894              :     {
    8895              :       /* If either the vector has variable length or the vectors
    8896              :          are composed of repeated whole groups we only need to
    8897              :          cost construction once.  All vectors will be the same.  */
    8898      1024388 :       nelt_limit = group_size;
    8899      1024388 :       starts.quick_push (0);
    8900              :     }
    8901              :   /* ???  We're just tracking whether vectors in a single node are the same.
    8902              :      Ideally we'd do something more global.  */
    8903      1090307 :   bool passed = false;
    8904      4452649 :   for (unsigned int start : starts)
    8905              :     {
    8906      1181728 :       vect_cost_for_stmt kind;
    8907      1181728 :       if (SLP_TREE_DEF_TYPE (node) == vect_constant_def)
    8908              :         kind = vector_load;
    8909       449684 :       else if (vect_scalar_ops_slice { ops, start, nelt_limit }.all_same_p ())
    8910              :         kind = scalar_to_vec;
    8911              :       else
    8912       363349 :         kind = vec_construct;
    8913              :       /* The target cost hook has no idea which part of the SLP node
    8914              :          we are costing so avoid passing it down more than once.  Pass
    8915              :          it to the first vec_construct or scalar_to_vec part since for those
    8916              :          the x86 backend tries to account for GPR to XMM register moves.  */
    8917      1181728 :       record_stmt_cost (cost_vec, 1, kind, nullptr,
    8918      1181728 :                         (kind != vector_load && !passed) ? node : nullptr,
    8919              :                         vectype, 0, vect_prologue);
    8920      1181728 :       if (kind != vector_load)
    8921       449684 :         passed = true;
    8922              :     }
    8923      1090307 : }
    8924              : 
    8925              : /* Analyze statements contained in SLP tree NODE after recursively analyzing
    8926              :    the subtree.  NODE_INSTANCE contains NODE and VINFO contains INSTANCE.
    8927              : 
    8928              :    Return true if the operations are supported.  */
    8929              : 
    8930              : static bool
    8931      5043518 : vect_slp_analyze_node_operations (vec_info *vinfo, slp_tree node,
    8932              :                                   slp_instance node_instance,
    8933              :                                   hash_set<slp_tree> &visited_set,
    8934              :                                   vec<slp_tree> &visited_vec,
    8935              :                                   stmt_vector_for_cost *cost_vec)
    8936              : {
    8937      5043518 :   int i, j;
    8938      5043518 :   slp_tree child;
    8939              : 
    8940              :   /* Assume we can code-generate all invariants.  */
    8941      5043518 :   if (!node
    8942      4652240 :       || SLP_TREE_DEF_TYPE (node) == vect_constant_def
    8943      3859765 :       || SLP_TREE_DEF_TYPE (node) == vect_external_def)
    8944              :     return true;
    8945              : 
    8946      3374619 :   if (SLP_TREE_DEF_TYPE (node) == vect_uninitialized_def)
    8947              :     {
    8948            5 :       if (dump_enabled_p ())
    8949            0 :         dump_printf_loc (MSG_NOTE, vect_location,
    8950              :                          "Failed cyclic SLP reference in %p\n", (void *) node);
    8951            5 :       return false;
    8952              :     }
    8953      3374614 :   gcc_assert (SLP_TREE_DEF_TYPE (node) == vect_internal_def);
    8954              : 
    8955              :   /* If we already analyzed the exact same set of scalar stmts we're done.
    8956              :      We share the generated vector stmts for those.  */
    8957      3374614 :   if (visited_set.add (node))
    8958              :     return true;
    8959      3076384 :   visited_vec.safe_push (node);
    8960              : 
    8961      3076384 :   bool res = true;
    8962      3076384 :   unsigned visited_rec_start = visited_vec.length ();
    8963      3076384 :   unsigned cost_vec_rec_start = cost_vec->length ();
    8964      3076384 :   bool seen_non_constant_child = false;
    8965      6400742 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    8966              :     {
    8967      3684199 :       res = vect_slp_analyze_node_operations (vinfo, child, node_instance,
    8968              :                                               visited_set, visited_vec,
    8969              :                                               cost_vec);
    8970      3684199 :       if (!res)
    8971              :         break;
    8972      3324358 :       if (child && SLP_TREE_DEF_TYPE (child) != vect_constant_def)
    8973      3324358 :         seen_non_constant_child = true;
    8974              :     }
    8975              :   /* We're having difficulties scheduling nodes with just constant
    8976              :      operands and no scalar stmts since we then cannot compute a stmt
    8977              :      insertion place.  */
    8978      3076384 :   if (res
    8979      3076384 :       && !seen_non_constant_child
    8980      3076384 :       && SLP_TREE_SCALAR_STMTS (node).is_empty ())
    8981              :     {
    8982          214 :       if (dump_enabled_p ())
    8983            6 :         dump_printf_loc (MSG_NOTE, vect_location,
    8984              :                          "Cannot vectorize all-constant op node %p\n",
    8985              :                          (void *) node);
    8986              :       res = false;
    8987              :     }
    8988              : 
    8989      3076170 :   if (res)
    8990      2716329 :     res = vect_slp_analyze_node_operations_1 (vinfo, node, node_instance,
    8991              :                                               cost_vec);
    8992              :   /* If analysis failed we have to pop all recursive visited nodes
    8993              :      plus ourselves.  */
    8994      3076384 :   if (!res)
    8995              :     {
    8996      3148822 :       while (visited_vec.length () >= visited_rec_start)
    8997       937455 :         visited_set.remove (visited_vec.pop ());
    8998       636956 :       cost_vec->truncate (cost_vec_rec_start);
    8999              :     }
    9000              : 
    9001              :   /* When the node can be vectorized cost invariant nodes it references.
    9002              :      This is not done in DFS order to allow the referring node
    9003              :      vectorizable_* calls to nail down the invariant nodes vector type
    9004              :      and possibly unshare it if it needs a different vector type than
    9005              :      other referrers.  */
    9006      3076384 :   if (res)
    9007      5408530 :     FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
    9008      2969102 :       if (child
    9009      2649437 :           && (SLP_TREE_DEF_TYPE (child) == vect_constant_def
    9010      2649437 :               || SLP_TREE_DEF_TYPE (child) == vect_external_def)
    9011              :           /* Perform usual caching, note code-generation still
    9012              :              code-gens these nodes multiple times but we expect
    9013              :              to CSE them later.  */
    9014      4104459 :           && !visited_set.add (child))
    9015              :         {
    9016      1132458 :           visited_vec.safe_push (child);
    9017              :           /* ???  After auditing more code paths make a "default"
    9018              :              and push the vector type from NODE to all children
    9019              :              if it is not already set.  */
    9020              :           /* Compute the number of vectors to be generated.  */
    9021      1132458 :           tree vector_type = SLP_TREE_VECTYPE (child);
    9022      1132458 :           if (!vector_type)
    9023              :             {
    9024              :               /* Masked loads can have an undefined (default SSA definition)
    9025              :                  else operand.  We do not need to cost it.  */
    9026        39880 :               vec<tree> ops = SLP_TREE_SCALAR_OPS (child);
    9027        41311 :               if (SLP_TREE_TYPE (node) == load_vec_info_type
    9028        41311 :                   && ((ops.length ()
    9029         1431 :                        && TREE_CODE (ops[0]) == SSA_NAME
    9030            0 :                        && SSA_NAME_IS_DEFAULT_DEF (ops[0])
    9031            0 :                        && VAR_P (SSA_NAME_VAR (ops[0])))
    9032         1431 :                       || SLP_TREE_DEF_TYPE (child) == vect_constant_def))
    9033         1431 :                 continue;
    9034              : 
    9035              :               /* For shifts with a scalar argument we don't need
    9036              :                  to cost or code-generate anything.
    9037              :                  ???  Represent this more explicitly.  */
    9038        38449 :               gcc_assert (SLP_TREE_TYPE (node) == shift_vec_info_type
    9039              :                           && j == 1);
    9040        38449 :               continue;
    9041        38449 :             }
    9042              : 
    9043              :           /* And cost them.  */
    9044      1092578 :           vect_prologue_cost_for_slp (vinfo, child, cost_vec);
    9045              :         }
    9046              : 
    9047              :   /* If this node or any of its children can't be vectorized, try pruning
    9048              :      the tree here rather than felling the whole thing.  */
    9049       636956 :   if (!res && vect_slp_convert_to_external (vinfo, node, node_instance))
    9050              :     {
    9051              :       /* We'll need to revisit this for invariant costing and number
    9052              :          of vectorized stmt setting.   */
    9053              :       res = true;
    9054              :     }
    9055              : 
    9056              :   return res;
    9057              : }
    9058              : 
    9059              : /* Mark lanes of NODE that are live outside of the basic-block vectorized
    9060              :    region and that can be vectorized using vectorizable_live_operation
    9061              :    with STMT_VINFO_LIVE_P.  Not handled live operations will cause the
    9062              :    scalar code computing it to be retained.  */
    9063              : 
    9064              : static void
    9065       989913 : vect_bb_slp_mark_live_stmts (bb_vec_info bb_vinfo, slp_tree node,
    9066              :                              slp_instance instance,
    9067              :                              stmt_vector_for_cost *cost_vec,
    9068              :                              hash_set<stmt_vec_info> &svisited,
    9069              :                              hash_set<slp_tree> &visited)
    9070              : {
    9071       989913 :   if (visited.add (node))
    9072        56568 :     return;
    9073              : 
    9074       933345 :   unsigned i;
    9075       933345 :   stmt_vec_info stmt_info;
    9076       933345 :   stmt_vec_info last_stmt = vect_find_last_scalar_stmt_in_slp (node);
    9077      3353233 :   FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
    9078              :     {
    9079      2419888 :       if (!stmt_info || svisited.contains (stmt_info))
    9080        90136 :         continue;
    9081      2384344 :       stmt_vec_info orig_stmt_info = vect_orig_stmt (stmt_info);
    9082      2384344 :       if (STMT_VINFO_IN_PATTERN_P (orig_stmt_info)
    9083        35547 :           && STMT_VINFO_RELATED_STMT (orig_stmt_info) != stmt_info)
    9084              :         /* Only the pattern root stmt computes the original scalar value.  */
    9085        29615 :         continue;
    9086      2354729 :       if (!PURE_SLP_STMT (orig_stmt_info))
    9087              :         /* Iff the stmt is not part of the vector coverage because it or
    9088              :            uses of it are used by SLP graph leafs as extern input there is
    9089              :            no point in trying to live code-generate from a vector stmt as
    9090              :            the scalar stmt will survive anyway.  */
    9091        24977 :         continue;
    9092      2329752 :       bool mark_visited = true;
    9093      2329752 :       gimple *orig_stmt = orig_stmt_info->stmt;
    9094      2329752 :       ssa_op_iter op_iter;
    9095      2329752 :       def_operand_p def_p;
    9096      5225818 :       FOR_EACH_PHI_OR_STMT_DEF (def_p, orig_stmt, op_iter, SSA_OP_DEF)
    9097              :         {
    9098              :           /* We have to verify whether we can insert the lane extract
    9099              :              before all uses.  The following is a conservative approximation.
    9100              :              We cannot put this into vectorizable_live_operation because
    9101              :              iterating over all use stmts from inside a FOR_EACH_IMM_USE_STMT
    9102              :              doesn't work.
    9103              :              Note that while the fact that we emit code for loads at the
    9104              :              first load should make this a non-problem leafs we construct
    9105              :              from scalars are vectorized after the last scalar def.
    9106              :              ???  If we'd actually compute the insert location during
    9107              :              analysis we could use sth less conservative than the last
    9108              :              scalar stmt in the node for the dominance check.  */
    9109              :           /* ???  What remains is "live" uses in vector CTORs in the same
    9110              :              SLP graph which is where those uses can end up code-generated
    9111              :              right after their definition instead of close to their original
    9112              :              use.  But that would restrict us to code-generate lane-extracts
    9113              :              from the latest stmt in a node.  So we compensate for this
    9114              :              during code-generation, simply not replacing uses for those
    9115              :              hopefully rare cases.  */
    9116       566314 :           imm_use_iterator use_iter;
    9117       566314 :           gimple *use_stmt;
    9118       566314 :           stmt_vec_info use_stmt_info;
    9119              : 
    9120       566314 :           bool live_p = false;
    9121       566314 :           bool can_insert = true;
    9122      2188668 :           FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, DEF_FROM_PTR (def_p))
    9123      1076496 :             if (!is_gimple_debug (use_stmt)
    9124      1076496 :                 && (!(use_stmt_info = bb_vinfo->lookup_stmt (use_stmt))
    9125       825936 :                     || !PURE_SLP_STMT (use_stmt_info)))
    9126              :               {
    9127       196026 :                 live_p = true;
    9128       196026 :                 if (!vect_stmt_dominates_stmt_p (last_stmt->stmt, use_stmt))
    9129              :                   {
    9130        20456 :                     if (dump_enabled_p ())
    9131           43 :                       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    9132              :                                        "Cannot determine insertion place for "
    9133              :                                        "lane extract of %T at node %p\n",
    9134              :                                        DEF_FROM_PTR (def_p), (void *)node);
    9135              :                     can_insert = false;
    9136              :                     break;
    9137              :                   }
    9138       566314 :               }
    9139       566314 :           if (live_p && can_insert)
    9140              :             {
    9141              :               /* Only record a live stmt when we can replace all uses.  We
    9142              :                  record from which SLP tree we vectorize the uses, so we'll
    9143              :                  cost once and can deal with the case that not all SLP nodes
    9144              :                  may be suitable for code-generation of all live uses.
    9145              :                  ???  But we never split up the work between multiple SLP
    9146              :                  nodes.  */
    9147        87353 :               STMT_VINFO_LIVE_P (stmt_info) = true;
    9148        87353 :               if (!vectorizable_live_operation (bb_vinfo, stmt_info, node,
    9149              :                                                 instance, i, false, cost_vec))
    9150              :                 {
    9151            0 :                   STMT_VINFO_LIVE_P (stmt_info) = false;
    9152            0 :                   mark_visited = false;
    9153              :                 }
    9154              :             }
    9155              :         }
    9156      2329752 :       if (mark_visited)
    9157      2329752 :         svisited.add (stmt_info);
    9158              :     }
    9159              : 
    9160              :   slp_tree child;
    9161      2729806 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    9162       975720 :     if (child && SLP_TREE_DEF_TYPE (child) == vect_internal_def)
    9163       276778 :       vect_bb_slp_mark_live_stmts (bb_vinfo, child, instance, cost_vec,
    9164              :                                    svisited, visited);
    9165              : }
    9166              : 
    9167              : /* Traverse all slp instances of BB_VINFO, and mark lanes of every node that
    9168              :    are live outside of the basic-block vectorized region and that can be
    9169              :    vectorized using vectorizable_live_operation with STMT_VINFO_LIVE_P.  */
    9170              : 
    9171              : static void
    9172       245217 : vect_bb_slp_mark_live_stmts (bb_vec_info bb_vinfo)
    9173              : {
    9174       245217 :   if (bb_vinfo->slp_instances.is_empty ())
    9175            0 :     return;
    9176              : 
    9177       245217 :   hash_set<slp_tree> visited;
    9178       245217 :   hash_set<stmt_vec_info> svisited;
    9179      1448786 :   for (slp_instance instance : bb_vinfo->slp_instances)
    9180              :     {
    9181       713135 :       if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ())
    9182        50995 :         STMT_VINFO_LIVE_P (SLP_INSTANCE_ROOT_STMTS (instance)[0]) = true;
    9183       713135 :       vect_location = instance->location ();
    9184       713135 :       vect_bb_slp_mark_live_stmts (bb_vinfo, SLP_INSTANCE_TREE (instance),
    9185              :                                    instance, &instance->cost_vec,
    9186              :                                    svisited, visited);
    9187              :     }
    9188       245217 : }
    9189              : 
    9190              : /* Determine whether we can vectorize the reduction epilogue for INSTANCE.  */
    9191              : 
    9192              : static bool
    9193        89318 : vectorizable_bb_reduc_epilogue (slp_instance instance,
    9194              :                                 stmt_vector_for_cost *cost_vec)
    9195              : {
    9196        89318 :   gassign *stmt = as_a <gassign *> (instance->root_stmts[0]->stmt);
    9197        89318 :   enum tree_code reduc_code = gimple_assign_rhs_code (stmt);
    9198        89318 :   if (reduc_code == MINUS_EXPR)
    9199            0 :     reduc_code = PLUS_EXPR;
    9200        89318 :   internal_fn reduc_fn;
    9201        89318 :   tree vectype = SLP_TREE_VECTYPE (SLP_INSTANCE_TREE (instance));
    9202        89318 :   if (!vectype
    9203        89306 :       || !useless_type_conversion_p (TREE_TYPE (gimple_assign_lhs (stmt)),
    9204        89306 :                                      TREE_TYPE (vectype))
    9205        52412 :       || (maybe_ne (TYPE_VECTOR_SUBPARTS (vectype), 2u)
    9206         1041 :           && (!reduction_fn_for_scalar_code (reduc_code, &reduc_fn)
    9207         1041 :               || reduc_fn == IFN_LAST
    9208         1041 :               || !direct_internal_fn_supported_p (reduc_fn, vectype,
    9209              :                                                   OPTIMIZE_FOR_BOTH)))
    9210              :       /* Two-element reductions do not need special-handling for fold-left,
    9211              :          other cases are not yet implemented.  remain_defs also have to
    9212              :          be included here.  */
    9213       141728 :       || (needs_fold_left_reduction_p (TREE_TYPE (vectype), reduc_code)
    9214         3797 :           && (!instance->remain_defs.is_empty ()
    9215         1860 :               || SLP_TREE_LANES (SLP_INSTANCE_TREE (instance)) != 2)))
    9216              :     {
    9217        38895 :       if (dump_enabled_p ())
    9218           48 :         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    9219              :                          "not vectorized: basic block reduction epilogue "
    9220              :                          "operation unsupported.\n");
    9221        38895 :       return false;
    9222              :     }
    9223              : 
    9224              :   /* There's no way to cost a horizontal vector reduction via REDUC_FN so
    9225              :      cost log2 vector operations plus shuffles and one extraction.  */
    9226        50423 :   unsigned steps = floor_log2 (vect_nunits_for_cost (vectype));
    9227        50423 :   record_stmt_cost (cost_vec, steps, vector_stmt, instance->root_stmts[0],
    9228              :                     vectype, 0, vect_body);
    9229        50423 :   record_stmt_cost (cost_vec, steps, vec_perm, instance->root_stmts[0],
    9230              :                     vectype, 0, vect_body);
    9231        50423 :   record_stmt_cost (cost_vec, 1, vec_to_scalar, instance->root_stmts[0],
    9232              :                     vectype, 0, vect_body);
    9233              : 
    9234              :   /* Since we replace all stmts of a possibly longer scalar reduction
    9235              :      chain account for the extra scalar stmts for that.  */
    9236        50423 :   if (!instance->remain_defs.is_empty ())
    9237        33746 :     record_stmt_cost (cost_vec, instance->remain_defs.length (), scalar_stmt,
    9238        16873 :                       instance->root_stmts[0], 0, vect_body);
    9239              :   return true;
    9240              : }
    9241              : 
    9242              : /* Prune from ROOTS all stmts that are computed as part of lanes of NODE
    9243              :    and recurse to children.  */
    9244              : 
    9245              : static void
    9246       364522 : vect_slp_prune_covered_roots (slp_tree node, hash_set<stmt_vec_info> &roots,
    9247              :                               hash_set<slp_tree> &visited)
    9248              : {
    9249       364522 :   if (SLP_TREE_DEF_TYPE (node) != vect_internal_def
    9250       364522 :       || visited.add (node))
    9251       172154 :     return;
    9252              : 
    9253      1012615 :   for (auto stmt : SLP_TREE_SCALAR_STMTS (node))
    9254       448089 :     if (stmt)
    9255       479440 :       roots.remove (vect_orig_stmt (stmt));
    9256              : 
    9257       772953 :   for (auto child : SLP_TREE_CHILDREN (node))
    9258       259591 :     if (child)
    9259       258173 :       vect_slp_prune_covered_roots (child, roots, visited);
    9260              : }
    9261              : 
    9262              : /* Hand over COST_VEC to the target COSTS grouped by SLP node.  */
    9263              : 
    9264              : static void
    9265       979993 : add_slp_costs (vector_costs *costs, stmt_vector_for_cost& cost_vec)
    9266              : {
    9267      3751600 :   for (unsigned start = 0; start < cost_vec.length ();)
    9268              :     {
    9269      2771607 :       unsigned end = start + 1;
    9270      3422556 :       while (end < cost_vec.length ()
    9271      5873783 :              && cost_vec[start].node == cost_vec[end].node)
    9272       650949 :         end++;
    9273      2771607 :       costs->add_slp_cost (cost_vec[start].node,
    9274      2771607 :                            array_slice<stmt_info_for_cost>
    9275      2771607 :                              (cost_vec.begin () + start, end - start));
    9276      2771607 :       start = end;
    9277              :     }
    9278       979993 : }
    9279              : 
    9280              : /* Analyze statements in SLP instances of VINFO.  Return true if the
    9281              :    operations are supported. */
    9282              : 
    9283              : bool
    9284       690566 : vect_slp_analyze_operations (vec_info *vinfo)
    9285              : {
    9286       690566 :   slp_instance instance;
    9287       690566 :   int i;
    9288              : 
    9289       690566 :   DUMP_VECT_SCOPE ("vect_slp_analyze_operations");
    9290              : 
    9291       690566 :   hash_set<slp_tree> visited;
    9292      1792653 :   for (i = 0; vinfo->slp_instances.iterate (i, &instance); )
    9293              :     {
    9294      1359319 :       auto_vec<slp_tree> visited_vec;
    9295      1359319 :       stmt_vector_for_cost cost_vec;
    9296      1359319 :       cost_vec.create (2);
    9297      1359319 :       if (is_a <bb_vec_info> (vinfo))
    9298       817410 :         vect_location = instance->location ();
    9299      1359319 :       if (!vect_slp_analyze_node_operations (vinfo,
    9300              :                                              SLP_INSTANCE_TREE (instance),
    9301              :                                              instance, visited, visited_vec,
    9302              :                                              &cost_vec)
    9303              :           /* CTOR instances require vectorized defs for the SLP tree root.  */
    9304      1105015 :           || (SLP_INSTANCE_KIND (instance) == slp_inst_kind_ctor
    9305         6129 :               && (SLP_TREE_DEF_TYPE (SLP_INSTANCE_TREE (instance))
    9306              :                   != vect_internal_def
    9307              :                   /* Make sure we vectorized with the expected type.  */
    9308         6129 :                   || !useless_type_conversion_p
    9309         6129 :                         (TREE_TYPE (TREE_TYPE (gimple_assign_rhs1
    9310              :                                               (instance->root_stmts[0]->stmt))),
    9311         6129 :                          TREE_TYPE (SLP_TREE_VECTYPE
    9312              :                                             (SLP_INSTANCE_TREE (instance))))))
    9313              :           /* Check we can vectorize the reduction.  */
    9314      1105000 :           || (SLP_INSTANCE_KIND (instance) == slp_inst_kind_bb_reduc
    9315        89318 :               && !vectorizable_bb_reduc_epilogue (instance, &cost_vec))
    9316              :           /* Check we can vectorize the gcond.  */
    9317      2425424 :           || (SLP_INSTANCE_KIND (instance) == slp_inst_kind_gcond
    9318        65385 :               && !vectorizable_early_exit (as_a <loop_vec_info> (vinfo),
    9319        65385 :                                            SLP_INSTANCE_ROOT_STMTS (instance)[0],
    9320              :                                            NULL,
    9321              :                                            SLP_INSTANCE_TREE (instance),
    9322              :                                            &cost_vec)))
    9323              :         {
    9324       355965 :           cost_vec.release ();
    9325       355965 :           slp_tree node = SLP_INSTANCE_TREE (instance);
    9326       355965 :           stmt_vec_info stmt_info;
    9327       355965 :           if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ())
    9328       266281 :             stmt_info = SLP_INSTANCE_ROOT_STMTS (instance)[0];
    9329        89684 :           else if (!SLP_TREE_SCALAR_STMTS (node).is_empty ()
    9330        89684 :                    && SLP_TREE_SCALAR_STMTS (node)[0])
    9331              :             stmt_info = SLP_TREE_SCALAR_STMTS (node)[0];
    9332              :           else
    9333            0 :             stmt_info = SLP_TREE_REPRESENTATIVE (node);
    9334       355965 :           if (is_a <loop_vec_info> (vinfo))
    9335              :             {
    9336       257232 :               if (dump_enabled_p ())
    9337         6833 :                 dump_printf_loc (MSG_NOTE, vect_location,
    9338              :                                  "unsupported SLP instance starting from: %G",
    9339              :                                  stmt_info->stmt);
    9340       257232 :               return false;
    9341              :             }
    9342        98733 :           if (dump_enabled_p ())
    9343          104 :             dump_printf_loc (MSG_NOTE, vect_location,
    9344              :                              "removing SLP instance operations starting from: %G",
    9345              :                              stmt_info->stmt);
    9346       235076 :           while (!visited_vec.is_empty ())
    9347              :             {
    9348       136343 :               slp_tree node = visited_vec.pop ();
    9349       136343 :               SLP_TREE_TYPE (node) = undef_vec_info_type;
    9350       136343 :               if (node->data)
    9351              :                 {
    9352         8474 :                   delete node->data;
    9353         8474 :                   node->data = nullptr;
    9354              :                 }
    9355       136343 :               visited.remove (node);
    9356              :             }
    9357        98733 :           vect_free_slp_instance (instance);
    9358        98733 :           vinfo->slp_instances.ordered_remove (i);
    9359              :         }
    9360              :       else
    9361              :         {
    9362      1003354 :           i++;
    9363      1003354 :           if (loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (vinfo))
    9364              :             {
    9365       284677 :               add_slp_costs (loop_vinfo->vector_costs, cost_vec);
    9366       284677 :               cost_vec.release ();
    9367              :             }
    9368              :           else
    9369              :             /* For BB vectorization remember the SLP graph entry
    9370              :                cost for later.  */
    9371       718677 :             instance->cost_vec = cost_vec;
    9372              :         }
    9373      1359319 :     }
    9374              : 
    9375              :   /* Now look for SLP instances with a root that are covered by other
    9376              :      instances and remove them.  */
    9377       433334 :   hash_set<stmt_vec_info> roots;
    9378      1799568 :   for (i = 0; vinfo->slp_instances.iterate (i, &instance); ++i)
    9379       992059 :     if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ())
    9380        59159 :       roots.add (SLP_INSTANCE_ROOT_STMTS (instance)[0]);
    9381       433334 :   if (!roots.is_empty ())
    9382              :     {
    9383        23524 :       visited.empty ();
    9384       129873 :       for (i = 0; vinfo->slp_instances.iterate (i, &instance); ++i)
    9385       106349 :         vect_slp_prune_covered_roots (SLP_INSTANCE_TREE (instance), roots,
    9386              :                                       visited);
    9387       129873 :       for (i = 0; vinfo->slp_instances.iterate (i, &instance); )
    9388       106349 :         if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ()
    9389        59159 :             && !roots.contains (SLP_INSTANCE_ROOT_STMTS (instance)[0]))
    9390              :           {
    9391         5542 :             stmt_vec_info root = SLP_INSTANCE_ROOT_STMTS (instance)[0];
    9392         5542 :             if (dump_enabled_p ())
    9393          283 :               dump_printf_loc (MSG_NOTE, vect_location,
    9394              :                                "removing SLP instance operations starting "
    9395              :                                "from: %G", root->stmt);
    9396         5542 :             vect_free_slp_instance (instance);
    9397         5542 :             vinfo->slp_instances.ordered_remove (i);
    9398              :           }
    9399              :         else
    9400       100807 :           ++i;
    9401              :     }
    9402              : 
    9403       866668 :   return !vinfo->slp_instances.is_empty ();
    9404      1123900 : }
    9405              : 
    9406              : /* Get the SLP instance leader from INSTANCE_LEADER thereby transitively
    9407              :    closing the eventual chain.  */
    9408              : 
    9409              : static slp_instance
    9410       797725 : get_ultimate_leader (slp_instance instance,
    9411              :                      hash_map<slp_instance, slp_instance> &instance_leader)
    9412              : {
    9413       797725 :   auto_vec<slp_instance *, 8> chain;
    9414       797725 :   slp_instance *tem;
    9415       901110 :   while (*(tem = instance_leader.get (instance)) != instance)
    9416              :     {
    9417       103385 :       chain.safe_push (tem);
    9418       103385 :       instance = *tem;
    9419              :     }
    9420       901110 :   while (!chain.is_empty ())
    9421       103385 :     *chain.pop () = instance;
    9422       797725 :   return instance;
    9423       797725 : }
    9424              : 
    9425              : namespace {
    9426              : /* Subroutine of vect_bb_partition_graph_r.  Map KEY to INSTANCE in
    9427              :    KEY_TO_INSTANCE, making INSTANCE the leader of any previous mapping
    9428              :    for KEY.  Return true if KEY was already in KEY_TO_INSTANCE.
    9429              : 
    9430              :    INSTANCE_LEADER is as for get_ultimate_leader.  */
    9431              : 
    9432              : template<typename T>
    9433              : bool
    9434      3543339 : vect_map_to_instance (slp_instance instance, T key,
    9435              :                       hash_map<T, slp_instance> &key_to_instance,
    9436              :                       hash_map<slp_instance, slp_instance> &instance_leader)
    9437              : {
    9438              :   bool existed_p;
    9439      3543339 :   slp_instance &key_instance = key_to_instance.get_or_insert (key, &existed_p);
    9440      3543339 :   if (!existed_p)
    9441              :     ;
    9442       236553 :   else if (key_instance != instance)
    9443              :     {
    9444              :       /* If we're running into a previously marked key make us the
    9445              :          leader of the current ultimate leader.  This keeps the
    9446              :          leader chain acyclic and works even when the current instance
    9447              :          connects two previously independent graph parts.  */
    9448        84590 :       slp_instance key_leader
    9449        84590 :         = get_ultimate_leader (key_instance, instance_leader);
    9450        84590 :       if (key_leader != instance)
    9451        26183 :         instance_leader.put (key_leader, instance);
    9452              :     }
    9453      3543339 :   key_instance = instance;
    9454      3543339 :   return existed_p;
    9455              : }
    9456              : }
    9457              : 
    9458              : /* Worker of vect_bb_partition_graph, recurse on NODE.  */
    9459              : 
    9460              : static void
    9461       989913 : vect_bb_partition_graph_r (bb_vec_info bb_vinfo,
    9462              :                            slp_instance instance, slp_tree node,
    9463              :                            hash_map<stmt_vec_info, slp_instance> &stmt_to_instance,
    9464              :                            hash_map<slp_tree, slp_instance> &node_to_instance,
    9465              :                            hash_map<slp_instance, slp_instance> &instance_leader)
    9466              : {
    9467      5512419 :   for (auto stmt_info : SLP_TREE_SCALAR_STMTS (node))
    9468      2553426 :     if (stmt_info)
    9469      2553426 :       vect_map_to_instance (instance, stmt_info, stmt_to_instance,
    9470              :                             instance_leader);
    9471              : 
    9472       989913 :   if (vect_map_to_instance (instance, node, node_to_instance,
    9473              :                             instance_leader))
    9474              :     return;
    9475              : 
    9476      3550547 :   for (auto child : SLP_TREE_CHILDREN (node))
    9477       975720 :     if (child && SLP_TREE_DEF_TYPE (child) == vect_internal_def)
    9478       276778 :       vect_bb_partition_graph_r (bb_vinfo, instance, child, stmt_to_instance,
    9479              :                                  node_to_instance, instance_leader);
    9480              : }
    9481              : 
    9482              : /* Partition the SLP graph into pieces that can be costed independently.  */
    9483              : 
    9484              : static void
    9485       245217 : vect_bb_partition_graph (bb_vec_info bb_vinfo)
    9486              : {
    9487       245217 :   DUMP_VECT_SCOPE ("vect_bb_partition_graph");
    9488              : 
    9489              :   /* First walk the SLP graph assigning each involved scalar stmt a
    9490              :      corresponding SLP graph entry and upon visiting a previously
    9491              :      marked stmt, make the stmts leader the current SLP graph entry.  */
    9492       245217 :   hash_map<stmt_vec_info, slp_instance> stmt_to_instance;
    9493       245217 :   hash_map<slp_tree, slp_instance> node_to_instance;
    9494       245217 :   hash_map<slp_instance, slp_instance> instance_leader;
    9495       245217 :   slp_instance instance;
    9496       958352 :   for (unsigned i = 0; bb_vinfo->slp_instances.iterate (i, &instance); ++i)
    9497              :     {
    9498       713135 :       instance_leader.put (instance, instance);
    9499       713135 :       vect_bb_partition_graph_r (bb_vinfo,
    9500              :                                  instance, SLP_INSTANCE_TREE (instance),
    9501              :                                  stmt_to_instance, node_to_instance,
    9502              :                                  instance_leader);
    9503              :     }
    9504              : 
    9505              :   /* Then collect entries to each independent subgraph.  */
    9506      1203569 :   for (unsigned i = 0; bb_vinfo->slp_instances.iterate (i, &instance); ++i)
    9507              :     {
    9508       713135 :       slp_instance leader = get_ultimate_leader (instance, instance_leader);
    9509       713135 :       leader->subgraph_entries.safe_push (instance);
    9510       713135 :       if (dump_enabled_p ()
    9511       713135 :           && leader != instance)
    9512           71 :         dump_printf_loc (MSG_NOTE, vect_location,
    9513              :                          "instance %p is leader of %p\n",
    9514              :                          (void *) leader, (void *) instance);
    9515              :     }
    9516       245217 : }
    9517              : 
    9518              : /* Compute the scalar cost of the SLP node NODE and its children
    9519              :    and return it.  Do not account defs that are marked in LIFE and
    9520              :    update LIFE according to uses of NODE.  */
    9521              : 
    9522              : static void
    9523       709179 : vect_bb_slp_scalar_cost (bb_vec_info vinfo,
    9524              :                          vec<stmt_vec_info> &worklist,
    9525              :                          stmt_vector_for_cost *cost_vec,
    9526              :                          hash_set<stmt_vec_info> &visited)
    9527              : {
    9528      3300985 :   while (!worklist.is_empty ())
    9529              :     {
    9530      2591806 :       stmt_vec_info stmt = worklist.pop ();
    9531      2911039 :       if (!PURE_SLP_STMT (stmt))
    9532       339506 :         continue;
    9533              : 
    9534              :       /* When the stmt is live but not actually vectorized we have
    9535              :          to keep the feeding scalar defs.  */
    9536      2278180 :       if (!STMT_VINFO_LIVE_P (vect_stmt_to_vectorize (stmt)))
    9537              :         {
    9538      2187216 :           bool live_p = false;
    9539      2187216 :           ssa_op_iter op_iter;
    9540      2187216 :           def_operand_p def_p;
    9541      4821032 :           FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt->stmt, op_iter, SSA_OP_DEF)
    9542              :             {
    9543       446600 :               imm_use_iterator use_iter;
    9544       446600 :               gimple *use_stmt;
    9545      1606656 :               FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, DEF_FROM_PTR (def_p))
    9546       713456 :                 if (!is_gimple_debug (use_stmt))
    9547              :                   {
    9548       540356 :                     stmt_vec_info use_stmt_info = vinfo->lookup_stmt (use_stmt);
    9549       540356 :                     if (!use_stmt_info || !PURE_SLP_STMT (use_stmt_info))
    9550              :                       {
    9551        31600 :                         if (dump_enabled_p ())
    9552              :                           {
    9553           82 :                             dump_printf_loc (MSG_NOTE, vect_location,
    9554              :                                              "stmt considered live: %G",
    9555              :                                              stmt->stmt);
    9556           82 :                             dump_printf_loc (MSG_NOTE, vect_location,
    9557              :                                              "because of use in: %G",
    9558              :                                              use_stmt);
    9559              :                           }
    9560              :                         live_p = true;
    9561              :                       }
    9562       446600 :                   }
    9563              :             }
    9564      2187216 :           if (live_p)
    9565        20273 :             continue;
    9566              :         }
    9567              : 
    9568              :       /* The following assert verifies that vect_bb_partition_graph
    9569              :          partitions the SLP graph in a way that each scalar stmt of
    9570              :          the coverage of the SLP graph belongs to exactly one subgraph.
    9571              :          ???  This is currently not guaranteed since the function
    9572              :          works purely on SLP_TREE_SCALAR_STMTS, resulting in the assert
    9573              :          tripping or scalar stmts costed multiple times, making vectorization
    9574              :          more profitable than it really is.  */
    9575              :       /* gcc_checking_assert (!gimple_visited_p (stmt->stmt)); */
    9576              : 
    9577      2252300 :       if (vect_nop_conversion_p (stmt))
    9578              :         ;
    9579              :       /* For single-argument PHIs assume coalescing which means zero
    9580              :          cost for the scalar and the vector PHIs.  This avoids
    9581              :          artificially favoring the vector path (but may pessimize it
    9582              :          in some cases).  */
    9583      2222634 :       else if (is_a <gphi *> (stmt->stmt)
    9584      2222634 :                && gimple_phi_num_args (as_a <gphi *> (stmt->stmt)) == 1)
    9585              :         ;
    9586              :       else
    9587              :         {
    9588      2212089 :           vect_cost_for_stmt kind;
    9589      2212089 :           if (STMT_VINFO_DATA_REF (stmt))
    9590              :             {
    9591      1994329 :               data_reference_p dr = STMT_VINFO_DATA_REF (stmt);
    9592      1994329 :               tree base = get_base_address (DR_REF (dr));
    9593              :               /* When the scalar access is to a non-global not
    9594              :                  address-taken decl that is not BLKmode assume we can
    9595              :                  access it with a single non-load/store instruction.  */
    9596      1994329 :               if (DECL_P (base)
    9597      1535245 :                   && !is_global_var (base)
    9598      1458908 :                   && !TREE_ADDRESSABLE (base)
    9599      2546410 :                   && DECL_MODE (base) != BLKmode)
    9600              :                 kind = scalar_stmt;
    9601      1850186 :               else if (DR_IS_READ (STMT_VINFO_DATA_REF (stmt)))
    9602              :                 kind = scalar_load;
    9603              :               else
    9604      1613102 :                 kind = scalar_store;
    9605              :             }
    9606              :           else
    9607              :             kind = scalar_stmt;
    9608              :           /* Cost each scalar stmt only once.  */
    9609      2212089 :           gimple_set_visited (stmt->stmt, true);
    9610      2212089 :           record_stmt_cost (cost_vec, 1, kind, stmt, NULL_TREE, 0, vect_body);
    9611              :         }
    9612              : 
    9613              :       /* Now walk relevant parts of the SSA use-def graph.  */
    9614      2252300 :       slp_oprnds child_ops (stmt);
    9615      4756641 :       for (unsigned i = 0; i < child_ops.num_slp_children; ++i)
    9616              :         {
    9617      2504341 :           tree op = child_ops.get_op_for_slp_child (stmt, i);
    9618      2504341 :           stmt_vec_info def = vinfo->lookup_def (op);
    9619      2504341 :           if (def && !visited.add (def))
    9620       752304 :             worklist.safe_push (def);
    9621              :         }
    9622              :     }
    9623       709179 : }
    9624              : 
    9625              : 
    9626              : /* Comparator for the loop-index sorted cost vectors.  */
    9627              : 
    9628              : static int
    9629     19304644 : li_cost_vec_cmp (const void *a_, const void *b_, void *)
    9630              : {
    9631     19304644 :   auto *a = (const std::pair<unsigned, stmt_info_for_cost *> *)a_;
    9632     19304644 :   auto *b = (const std::pair<unsigned, stmt_info_for_cost *> *)b_;
    9633     19304644 :   if (a->first < b->first)
    9634              :     return -1;
    9635     18205357 :   else if (a->first == b->first)
    9636     17282624 :     return 0;
    9637              :   return 1;
    9638              : }
    9639              : 
    9640              : /* Check if vectorization of the basic block is profitable for the
    9641              :    subgraph denoted by SLP_INSTANCES.  */
    9642              : 
    9643              : static bool
    9644       683174 : vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo,
    9645              :                                     vec<slp_instance> slp_instances,
    9646              :                                     loop_p orig_loop)
    9647              : {
    9648       683174 :   slp_instance instance;
    9649       683174 :   int i;
    9650       683174 :   unsigned int vec_inside_cost = 0, vec_outside_cost = 0, scalar_cost = 0;
    9651       683174 :   unsigned int vec_prologue_cost = 0, vec_epilogue_cost = 0;
    9652              : 
    9653       683174 :   if (dump_enabled_p ())
    9654              :     {
    9655          122 :       dump_printf_loc (MSG_NOTE, vect_location, "Costing subgraph:\n");
    9656          249 :       FOR_EACH_VEC_ELT (slp_instances, i, instance)
    9657          127 :         dump_printf_loc (MSG_NOTE, vect_location, "   entry instance %p -> "
    9658              :                          "node %p\n", (void *)instance,
    9659          127 :                          (void *)SLP_INSTANCE_TREE (instance));
    9660          122 :       hash_set<slp_tree> visited;
    9661          493 :       FOR_EACH_VEC_ELT (slp_instances, i, instance)
    9662          127 :         vect_print_slp_graph (MSG_NOTE, vect_location,
    9663              :                               SLP_INSTANCE_TREE (instance), visited);
    9664          122 :     }
    9665              : 
    9666              :   /* Then DFS walk scalar stmts, performing costing and handling
    9667              :      still live scalar stmts via the previously computed vector coverage.  */
    9668       683174 :   stmt_vector_for_cost scalar_costs = vNULL;
    9669       683174 :   stmt_vector_for_cost vector_costs = vNULL;
    9670       683174 :   hash_set<slp_tree> visited;
    9671       683174 :   hash_set<stmt_vec_info> svisited;
    9672      1392353 :   FOR_EACH_VEC_ELT (slp_instances, i, instance)
    9673              :     {
    9674       709179 :       auto_vec<stmt_vec_info> worklist;
    9675       709179 :       if (SLP_INSTANCE_ROOT_STMTS (instance).exists ())
    9676       100524 :         record_stmt_cost (&scalar_costs,
    9677        50262 :                           SLP_INSTANCE_ROOT_STMTS (instance).length (),
    9678              :                           scalar_stmt,
    9679        50262 :                           SLP_INSTANCE_ROOT_STMTS (instance)[0], 0, vect_body);
    9680      3980873 :       for (auto stmt : SLP_TREE_SCALAR_STMTS (SLP_INSTANCE_TREE (instance)))
    9681              :         {
    9682      1853336 :           stmt = vect_orig_stmt (stmt);
    9683      1853336 :           if (!svisited.add (stmt))
    9684      1839502 :             worklist.safe_push (stmt);
    9685              :         }
    9686       709179 :       vect_bb_slp_scalar_cost (bb_vinfo, worklist, &scalar_costs, svisited);
    9687       709179 :       vector_costs.safe_splice (instance->cost_vec);
    9688       709179 :       instance->cost_vec.release ();
    9689       709179 :     }
    9690              : 
    9691       683174 :   if (dump_enabled_p ())
    9692          122 :     dump_printf_loc (MSG_NOTE, vect_location, "Cost model analysis: \n");
    9693              : 
    9694              :   /* When costing non-loop vectorization we need to consider each covered
    9695              :      loop independently and make sure vectorization is profitable.  For
    9696              :      now we assume a loop may be not entered or executed an arbitrary
    9697              :      number of iterations (???  static information can provide more
    9698              :      precise info here) which means we can simply cost each containing
    9699              :      loops stmts separately.  */
    9700              : 
    9701              :   /* First produce cost vectors sorted by loop index.  */
    9702       683174 :   auto_vec<std::pair<unsigned, stmt_info_for_cost *> >
    9703       683174 :     li_scalar_costs (scalar_costs.length ());
    9704       683174 :   auto_vec<std::pair<unsigned, stmt_info_for_cost *> >
    9705       683174 :     li_vector_costs (vector_costs.length ());
    9706       683174 :   stmt_info_for_cost *cost;
    9707      2945525 :   FOR_EACH_VEC_ELT (scalar_costs, i, cost)
    9708              :     {
    9709      2262351 :       unsigned l = gimple_bb (cost->stmt_info->stmt)->loop_father->num;
    9710      2262351 :       li_scalar_costs.quick_push (std::make_pair (l, cost));
    9711              :     }
    9712              :   /* Use a random used loop as fallback in case the first vector_costs
    9713              :      entry does not have a stmt_info associated with it.  */
    9714       683174 :   unsigned l = li_scalar_costs[0].first;
    9715      2608705 :   FOR_EACH_VEC_ELT (vector_costs, i, cost)
    9716              :     {
    9717              :       /* We inherit from the previous COST, invariants, externals and
    9718              :          extracts immediately follow the cost for the related stmt.  */
    9719      1925531 :       if (cost->stmt_info)
    9720      1164150 :         l = gimple_bb (cost->stmt_info->stmt)->loop_father->num;
    9721      1925531 :       li_vector_costs.quick_push (std::make_pair (l, cost));
    9722              :     }
    9723       683174 :   li_scalar_costs.stablesort (li_cost_vec_cmp, NULL);
    9724       683174 :   li_vector_costs.stablesort (li_cost_vec_cmp, NULL);
    9725              : 
    9726              :   /* Now cost the portions individually.  */
    9727              :   unsigned vi = 0;
    9728              :   unsigned si = 0;
    9729              :   bool profitable = true;
    9730      1380338 :   while (si < li_scalar_costs.length ()
    9731      2077544 :          && vi < li_vector_costs.length ())
    9732              :     {
    9733       697164 :       unsigned sl = li_scalar_costs[si].first;
    9734       697164 :       unsigned vl = li_vector_costs[vi].first;
    9735       697164 :       if (sl != vl)
    9736              :         {
    9737         1848 :           if (dump_enabled_p ())
    9738            2 :             dump_printf_loc (MSG_NOTE, vect_location,
    9739              :                              "Scalar %d and vector %d loop part do not "
    9740              :                              "match up, skipping scalar part\n", sl, vl);
    9741              :           /* Skip the scalar part, assuming zero cost on the vector side.  */
    9742         2768 :           do
    9743              :             {
    9744         2768 :               si++;
    9745              :             }
    9746         2768 :           while (si < li_scalar_costs.length ()
    9747         6136 :                  && li_scalar_costs[si].first == sl);
    9748         1848 :           continue;
    9749              :         }
    9750              : 
    9751       695316 :       if (dump_enabled_p ())
    9752          135 :         dump_printf_loc (MSG_NOTE, vect_location,
    9753              :                          "Scalar cost for part in loop %d\n", sl);
    9754       695316 :       class vector_costs *scalar_target_cost_data = init_cost (bb_vinfo, true);
    9755      2259450 :       do
    9756              :         {
    9757      2259450 :           add_stmt_cost (scalar_target_cost_data, li_scalar_costs[si].second);
    9758      2259450 :           si++;
    9759              :         }
    9760      2259450 :       while (si < li_scalar_costs.length ()
    9761      4531425 :              && li_scalar_costs[si].first == sl);
    9762       695316 :       scalar_target_cost_data->finish_cost (nullptr);
    9763       695316 :       scalar_cost = scalar_target_cost_data->body_cost ();
    9764              : 
    9765              :       /* Complete the target-specific vector cost calculation.  */
    9766       695316 :       if (dump_enabled_p ())
    9767          135 :         dump_printf_loc (MSG_NOTE, vect_location,
    9768              :                          "Vector cost for part in loop %d\n", vl);
    9769       695316 :       class vector_costs *vect_target_cost_data = init_cost (bb_vinfo, false);
    9770       695316 :       auto_vec<stmt_info_for_cost> tem;
    9771      1918506 :       do
    9772              :         {
    9773      1918506 :           tem.safe_push (*li_vector_costs[vi].second);
    9774      1918506 :           vi++;
    9775              :         }
    9776      1918506 :       while (vi < li_vector_costs.length ()
    9777      3850668 :              && li_vector_costs[vi].first == vl);
    9778       695316 :       add_slp_costs (vect_target_cost_data, tem);
    9779       695316 :       vect_target_cost_data->finish_cost (scalar_target_cost_data);
    9780       695316 :       vec_prologue_cost = vect_target_cost_data->prologue_cost ();
    9781       695316 :       vec_inside_cost = vect_target_cost_data->body_cost ();
    9782       695316 :       vec_epilogue_cost = vect_target_cost_data->epilogue_cost ();
    9783       695316 :       delete scalar_target_cost_data;
    9784       695316 :       delete vect_target_cost_data;
    9785              : 
    9786       695316 :       vec_outside_cost = vec_prologue_cost + vec_epilogue_cost;
    9787              : 
    9788       695316 :       if (dump_enabled_p ())
    9789              :         {
    9790          135 :           dump_printf_loc (MSG_NOTE, vect_location,
    9791              :                            "Cost model analysis for part in loop %d:\n", sl);
    9792          135 :           dump_printf (MSG_NOTE, "  Vector cost: %d\n",
    9793              :                        vec_inside_cost + vec_outside_cost);
    9794          135 :           dump_printf (MSG_NOTE, "  Scalar cost: %d\n", scalar_cost);
    9795              :         }
    9796              : 
    9797              :       /* Vectorization is profitable if its cost is more than the cost of scalar
    9798              :          version.  Note that we err on the vector side for equal cost because
    9799              :          the cost estimate is otherwise quite pessimistic (constant uses are
    9800              :          free on the scalar side but cost a load on the vector side for
    9801              :          example).  */
    9802       695316 :       if (vec_outside_cost + vec_inside_cost > scalar_cost)
    9803       202921 :         profitable = false;
    9804       695316 :     }
    9805      1170087 :   if (profitable && vi < li_vector_costs.length ())
    9806              :     {
    9807         1150 :       if (dump_enabled_p ())
    9808            0 :         dump_printf_loc (MSG_NOTE, vect_location,
    9809              :                          "Excess vector cost for part in loop %d:\n",
    9810            0 :                          li_vector_costs[vi].first);
    9811              :       profitable = false;
    9812              :     }
    9813              : 
    9814              :   /* Unset visited flag.  This is delayed when the subgraph is profitable
    9815              :      and we process the loop for remaining unvectorized if-converted code.  */
    9816       683174 :   if (!orig_loop || !profitable)
    9817      2943356 :     FOR_EACH_VEC_ELT (scalar_costs, i, cost)
    9818      2260336 :       gimple_set_visited  (cost->stmt_info->stmt, false);
    9819              : 
    9820       683174 :   scalar_costs.release ();
    9821       683174 :   vector_costs.release ();
    9822              : 
    9823       683174 :   return profitable;
    9824       683174 : }
    9825              : 
    9826              : /* qsort comparator for lane defs.  */
    9827              : 
    9828              : static int
    9829          120 : vld_cmp (const void *a_, const void *b_)
    9830              : {
    9831          120 :   auto *a = (const std::pair<unsigned, tree> *)a_;
    9832          120 :   auto *b = (const std::pair<unsigned, tree> *)b_;
    9833          120 :   return a->first - b->first;
    9834              : }
    9835              : 
    9836              : /* Return true if USE_STMT is a vector lane insert into VEC and set
    9837              :    *THIS_LANE to the lane number that is set.  */
    9838              : 
    9839              : static bool
    9840          301 : vect_slp_is_lane_insert (gimple *use_stmt, tree vec, unsigned *this_lane)
    9841              : {
    9842          301 :   gassign *use_ass = dyn_cast <gassign *> (use_stmt);
    9843          108 :   if (!use_ass
    9844          108 :       || gimple_assign_rhs_code (use_ass) != BIT_INSERT_EXPR
    9845           35 :       || (vec
    9846           35 :           ? gimple_assign_rhs1 (use_ass) != vec
    9847           24 :           : ((vec = gimple_assign_rhs1 (use_ass)), false))
    9848           59 :       || !useless_type_conversion_p (TREE_TYPE (TREE_TYPE (vec)),
    9849           59 :                                      TREE_TYPE (gimple_assign_rhs2 (use_ass)))
    9850           59 :       || !constant_multiple_p
    9851           59 :             (tree_to_poly_uint64 (gimple_assign_rhs3 (use_ass)),
    9852          118 :              tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (TREE_TYPE (vec)))),
    9853              :              this_lane))
    9854          242 :     return false;
    9855              :   return true;
    9856              : }
    9857              : 
    9858              : /* Find any vectorizable constructors and add them to the grouped_store
    9859              :    array.  */
    9860              : 
    9861              : static void
    9862      2251752 : vect_slp_check_for_roots (bb_vec_info bb_vinfo)
    9863              : {
    9864     18030778 :   for (unsigned i = 0; i < bb_vinfo->nbbs; ++i)
    9865     31558052 :     for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[i]);
    9866    142319577 :          !gsi_end_p (gsi); gsi_next (&gsi))
    9867              :     {
    9868    126540551 :       gassign *assign = dyn_cast<gassign *> (gsi_stmt (gsi));
    9869              :       /* This can be used to start SLP discovery for early breaks for BB early breaks
    9870              :          when we get that far.  */
    9871    126540551 :       if (!assign)
    9872    190348345 :         continue;
    9873              : 
    9874     32395296 :       tree rhs = gimple_assign_rhs1 (assign);
    9875     32395296 :       enum tree_code code = gimple_assign_rhs_code (assign);
    9876     32395296 :       use_operand_p use_p;
    9877     32395296 :       gimple *use_stmt;
    9878     32395296 :       if (code == CONSTRUCTOR)
    9879              :         {
    9880      1672959 :           if (!VECTOR_TYPE_P (TREE_TYPE (rhs))
    9881        67690 :               || maybe_ne (TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)),
    9882        97663 :                            CONSTRUCTOR_NELTS (rhs))
    9883        44872 :               || VECTOR_TYPE_P (TREE_TYPE (CONSTRUCTOR_ELT (rhs, 0)->value))
    9884      1717811 :               || uniform_vector_p (rhs))
    9885      1658653 :             continue;
    9886              : 
    9887              :           unsigned j;
    9888              :           tree val;
    9889        70465 :           FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), j, val)
    9890        56159 :             if (TREE_CODE (val) != SSA_NAME
    9891        56159 :                 || !bb_vinfo->lookup_def (val))
    9892              :               break;
    9893        34962 :           if (j != CONSTRUCTOR_NELTS (rhs))
    9894         3175 :             continue;
    9895              : 
    9896        14306 :           vec<stmt_vec_info> roots = vNULL;
    9897        14306 :           roots.safe_push (bb_vinfo->lookup_stmt (assign));
    9898        14306 :           vec<stmt_vec_info> stmts;
    9899        14306 :           stmts.create (CONSTRUCTOR_NELTS (rhs));
    9900        79820 :           FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), j, val)
    9901        51208 :             stmts.quick_push
    9902        51208 :               (vect_stmt_to_vectorize (bb_vinfo->lookup_def (val)));
    9903        14306 :           bb_vinfo->roots.safe_push (slp_root (slp_inst_kind_ctor,
    9904        14306 :                                                stmts, roots));
    9905              :         }
    9906     30722337 :       else if (code == BIT_INSERT_EXPR
    9907         1041 :                && VECTOR_TYPE_P (TREE_TYPE (rhs))
    9908          715 :                && TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)).is_constant ()
    9909          715 :                && TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)).to_constant () > 1
    9910          712 :                && integer_zerop (gimple_assign_rhs3 (assign))
    9911          398 :                && useless_type_conversion_p
    9912          398 :                     (TREE_TYPE (TREE_TYPE (rhs)),
    9913          398 :                      TREE_TYPE (gimple_assign_rhs2 (assign)))
    9914     30723073 :                && bb_vinfo->lookup_def (gimple_assign_rhs2 (assign)))
    9915              :         {
    9916              :           /* We start to match on insert to lane zero but since the
    9917              :              inserts need not be ordered we'd have to search both
    9918              :              the def and the use chains.  */
    9919          263 :           tree vectype = TREE_TYPE (rhs);
    9920          263 :           unsigned nlanes = TYPE_VECTOR_SUBPARTS (vectype).to_constant ();
    9921          263 :           auto_vec<std::pair<unsigned, tree> > lane_defs (nlanes);
    9922          263 :           auto_sbitmap lanes (nlanes);
    9923          263 :           bitmap_clear (lanes);
    9924          263 :           bitmap_set_bit (lanes, 0);
    9925          263 :           tree def = gimple_assign_lhs (assign);
    9926          263 :           lane_defs.quick_push
    9927          263 :                       (std::make_pair (0, gimple_assign_rhs2 (assign)));
    9928          263 :           unsigned lanes_found = 1;
    9929              :           /* Start with the use chains, the last stmt will be the root.  */
    9930          263 :           stmt_vec_info last = bb_vinfo->lookup_stmt (assign);
    9931          263 :           vec<stmt_vec_info> roots = vNULL;
    9932          263 :           roots.safe_push (last);
    9933          274 :           do
    9934              :             {
    9935          274 :               use_operand_p use_p;
    9936          274 :               gimple *use_stmt;
    9937          274 :               if (!single_imm_use (def, &use_p, &use_stmt))
    9938              :                 break;
    9939          264 :               unsigned this_lane;
    9940          264 :               if (!bb_vinfo->lookup_stmt (use_stmt)
    9941          264 :                   || !vect_slp_is_lane_insert (use_stmt, def, &this_lane)
    9942          299 :                   || !bb_vinfo->lookup_def (gimple_assign_rhs2 (use_stmt)))
    9943              :                 break;
    9944           35 :               if (bitmap_bit_p (lanes, this_lane))
    9945              :                 break;
    9946           15 :               lanes_found++;
    9947           15 :               bitmap_set_bit (lanes, this_lane);
    9948           15 :               gassign *use_ass = as_a <gassign *> (use_stmt);
    9949           15 :               lane_defs.quick_push (std::make_pair
    9950           15 :                                      (this_lane, gimple_assign_rhs2 (use_ass)));
    9951           15 :               last = bb_vinfo->lookup_stmt (use_ass);
    9952           15 :               roots.safe_push (last);
    9953           15 :               def = gimple_assign_lhs (use_ass);
    9954              :             }
    9955           15 :           while (lanes_found < nlanes);
    9956          263 :           if (roots.length () > 1)
    9957            7 :             std::swap(roots[0], roots[roots.length () - 1]);
    9958          263 :           if (lanes_found < nlanes)
    9959              :             {
    9960              :               /* Now search the def chain.  */
    9961          259 :               def = gimple_assign_rhs1 (assign);
    9962          261 :               do
    9963              :                 {
    9964          261 :                   if (TREE_CODE (def) != SSA_NAME
    9965          261 :                       || !has_single_use (def))
    9966              :                     break;
    9967           57 :                   gimple *def_stmt = SSA_NAME_DEF_STMT (def);
    9968           57 :                   unsigned this_lane;
    9969           57 :                   if (!bb_vinfo->lookup_stmt (def_stmt)
    9970           37 :                       || !vect_slp_is_lane_insert (def_stmt,
    9971              :                                                    NULL_TREE, &this_lane)
    9972           81 :                       || !bb_vinfo->lookup_def (gimple_assign_rhs2 (def_stmt)))
    9973              :                     break;
    9974           24 :                   if (bitmap_bit_p (lanes, this_lane))
    9975              :                     break;
    9976            4 :                   lanes_found++;
    9977            4 :                   bitmap_set_bit (lanes, this_lane);
    9978            8 :                   lane_defs.quick_push (std::make_pair
    9979            4 :                                           (this_lane,
    9980            4 :                                            gimple_assign_rhs2 (def_stmt)));
    9981            4 :                   roots.safe_push (bb_vinfo->lookup_stmt (def_stmt));
    9982            4 :                   def = gimple_assign_rhs1 (def_stmt);
    9983              :                 }
    9984            4 :               while (lanes_found < nlanes);
    9985              :             }
    9986          263 :           if (lanes_found == nlanes)
    9987              :             {
    9988              :               /* Sort lane_defs after the lane index and register the root.  */
    9989            6 :               lane_defs.qsort (vld_cmp);
    9990            6 :               vec<stmt_vec_info> stmts;
    9991            6 :               stmts.create (nlanes);
    9992           30 :               for (unsigned i = 0; i < nlanes; ++i)
    9993           24 :                 stmts.quick_push (bb_vinfo->lookup_def (lane_defs[i].second));
    9994            6 :               bb_vinfo->roots.safe_push (slp_root (slp_inst_kind_ctor,
    9995            6 :                                                    stmts, roots));
    9996              :             }
    9997              :           else
    9998          257 :             roots.release ();
    9999          263 :         }
   10000     30722074 :       else if (!VECTOR_TYPE_P (TREE_TYPE (rhs))
   10001     29708573 :                && (associative_tree_code (code) || code == MINUS_EXPR)
   10002              :                /* Ops with constants at the tail can be stripped here.  */
   10003      6606201 :                && TREE_CODE (rhs) == SSA_NAME
   10004      6532684 :                && TREE_CODE (gimple_assign_rhs2 (assign)) == SSA_NAME
   10005              :                /* Should be the chain end.  */
   10006     33600442 :                && (!single_imm_use (gimple_assign_lhs (assign),
   10007              :                                     &use_p, &use_stmt)
   10008      2290327 :                    || !is_gimple_assign (use_stmt)
   10009      1666950 :                    || (gimple_assign_rhs_code (use_stmt) != code
   10010      1105801 :                        && ((code != PLUS_EXPR && code != MINUS_EXPR)
   10011       605226 :                            || (gimple_assign_rhs_code (use_stmt)
   10012       605226 :                                != (code == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR))))))
   10013              :         {
   10014              :           /* We start the match at the end of a possible association
   10015              :              chain.  */
   10016      2201562 :           auto_vec<chain_op_t> chain;
   10017      2201562 :           auto_vec<std::pair<tree_code, gimple *> > worklist;
   10018      2201562 :           auto_vec<gimple *> chain_stmts;
   10019      2201562 :           gimple *code_stmt = NULL, *alt_code_stmt = NULL;
   10020      2201562 :           if (code == MINUS_EXPR)
   10021       353337 :             code = PLUS_EXPR;
   10022      2201562 :           internal_fn reduc_fn;
   10023      2600744 :           if (!reduction_fn_for_scalar_code (code, &reduc_fn)
   10024      2201562 :               || reduc_fn == IFN_LAST)
   10025       399182 :             continue;
   10026      1802380 :           vect_slp_linearize_chain (bb_vinfo, worklist, chain, code, assign,
   10027              :                                     /* ??? */
   10028              :                                     code_stmt, alt_code_stmt, &chain_stmts,
   10029              :                                     false);
   10030      3604760 :           if (chain.length () > 1)
   10031              :             {
   10032              :               /* Sort the chain according to def_type and operation.  */
   10033      1802380 :               chain.sort (dt_sort_cmp, bb_vinfo);
   10034              :               /* ???  Now we'd want to strip externals and constants
   10035              :                  but record those to be handled in the epilogue.  */
   10036              :               /* ???  For now do not allow mixing ops or externs/constants.  */
   10037      1802380 :               bool invalid = false;
   10038      1802380 :               unsigned remain_cnt = 0;
   10039      5640637 :               for (unsigned i = 0; i < chain.length (); ++i)
   10040              :                 {
   10041      4191594 :                   if (chain[i].code != code)
   10042              :                     {
   10043              :                       invalid = true;
   10044              :                       break;
   10045              :                     }
   10046      3838257 :                   if (chain[i].dt != vect_internal_def
   10047              :                       /* Avoid stmts where the def is not the LHS, like
   10048              :                          ASMs.  */
   10049      7324753 :                       || (gimple_get_lhs (bb_vinfo->lookup_def
   10050      3486496 :                                                       (chain[i].op)->stmt)
   10051      3486496 :                           != chain[i].op))
   10052       354713 :                     remain_cnt++;
   10053              :                 }
   10054      1802380 :               if (!invalid && chain.length () - remain_cnt > 1)
   10055              :                 {
   10056      1365626 :                   vec<stmt_vec_info> stmts;
   10057      1365626 :                   vec<tree> remain = vNULL;
   10058      1365626 :                   stmts.create (chain.length ());
   10059      1365626 :                   if (remain_cnt > 0)
   10060        47179 :                     remain.create (remain_cnt);
   10061      4544215 :                   for (unsigned i = 0; i < chain.length (); ++i)
   10062              :                     {
   10063      3178589 :                       stmt_vec_info stmt_info;
   10064      3178589 :                       if (chain[i].dt == vect_internal_def
   10065      3178589 :                           && ((stmt_info = bb_vinfo->lookup_def (chain[i].op)),
   10066      3090458 :                               gimple_get_lhs (stmt_info->stmt) == chain[i].op))
   10067      3090374 :                         stmts.quick_push (stmt_info);
   10068              :                       else
   10069        88215 :                         remain.quick_push (chain[i].op);
   10070              :                     }
   10071      1365626 :                   vec<stmt_vec_info> roots;
   10072      1365626 :                   roots.create (chain_stmts.length ());
   10073      3178589 :                   for (unsigned i = 0; i < chain_stmts.length (); ++i)
   10074      1812963 :                     roots.quick_push (bb_vinfo->lookup_stmt (chain_stmts[i]));
   10075      1365626 :                   bb_vinfo->roots.safe_push (slp_root (slp_inst_kind_bb_reduc,
   10076      1365626 :                                                        stmts, roots, remain));
   10077              :                 }
   10078              :             }
   10079      2201562 :         }
   10080              :     }
   10081      2251752 : }
   10082              : 
   10083              : /* Walk the grouped store chains and replace entries with their
   10084              :    pattern variant if any.  */
   10085              : 
   10086              : static void
   10087       663442 : vect_fixup_store_groups_with_patterns (vec_info *vinfo)
   10088              : {
   10089       663442 :   stmt_vec_info first_element;
   10090       663442 :   unsigned i;
   10091              : 
   10092      1569083 :   FOR_EACH_VEC_ELT (vinfo->grouped_stores, i, first_element)
   10093              :     {
   10094              :       /* We also have CTORs in this array.  */
   10095       905641 :       if (!STMT_VINFO_GROUPED_ACCESS (first_element))
   10096            0 :         continue;
   10097       905641 :       if (STMT_VINFO_IN_PATTERN_P (first_element))
   10098              :         {
   10099          252 :           stmt_vec_info orig = first_element;
   10100          252 :           first_element = STMT_VINFO_RELATED_STMT (first_element);
   10101          252 :           DR_GROUP_FIRST_ELEMENT (first_element) = first_element;
   10102          252 :           DR_GROUP_SIZE (first_element) = DR_GROUP_SIZE (orig);
   10103          252 :           DR_GROUP_GAP (first_element) = DR_GROUP_GAP (orig);
   10104          252 :           DR_GROUP_NEXT_ELEMENT (first_element) = DR_GROUP_NEXT_ELEMENT (orig);
   10105          252 :           vinfo->grouped_stores[i] = first_element;
   10106              :         }
   10107       905641 :       stmt_vec_info prev = first_element;
   10108      2546414 :       while (DR_GROUP_NEXT_ELEMENT (prev))
   10109              :         {
   10110      1640773 :           stmt_vec_info elt = DR_GROUP_NEXT_ELEMENT (prev);
   10111      1640773 :           if (STMT_VINFO_IN_PATTERN_P (elt))
   10112              :             {
   10113          849 :               stmt_vec_info orig = elt;
   10114          849 :               elt = STMT_VINFO_RELATED_STMT (elt);
   10115          849 :               DR_GROUP_NEXT_ELEMENT (prev) = elt;
   10116          849 :               DR_GROUP_GAP (elt) = DR_GROUP_GAP (orig);
   10117          849 :               DR_GROUP_NEXT_ELEMENT (elt) = DR_GROUP_NEXT_ELEMENT (orig);
   10118              :             }
   10119      1640773 :           DR_GROUP_FIRST_ELEMENT (elt) = first_element;
   10120      1640773 :           prev = elt;
   10121              :         }
   10122              :     }
   10123       663442 : }
   10124              : 
   10125              : /* Check if the region described by BB_VINFO can be vectorized, returning
   10126              :    true if so.  When returning false, set FATAL to true if the same failure
   10127              :    would prevent vectorization at other vector sizes, false if it is still
   10128              :    worth trying other sizes.  N_STMTS is the number of statements in the
   10129              :    region.  */
   10130              : 
   10131              : static bool
   10132      2251752 : vect_slp_analyze_bb_1 (bb_vec_info bb_vinfo, int n_stmts, bool &fatal,
   10133              :                        vec<int> *dataref_groups)
   10134              : {
   10135      2251752 :   DUMP_VECT_SCOPE ("vect_slp_analyze_bb");
   10136              : 
   10137      2251752 :   slp_instance instance;
   10138      2251752 :   int i;
   10139              : 
   10140              :   /* The first group of checks is independent of the vector size.  */
   10141      2251752 :   fatal = true;
   10142              : 
   10143              :   /* Analyze the data references.  */
   10144              : 
   10145      2251752 :   if (!vect_analyze_data_refs (bb_vinfo, NULL))
   10146              :     {
   10147            0 :       if (dump_enabled_p ())
   10148            0 :         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10149              :                          "not vectorized: unhandled data-ref in basic "
   10150              :                          "block.\n");
   10151            0 :       return false;
   10152              :     }
   10153              : 
   10154      2251752 :   if (!vect_analyze_data_ref_accesses (bb_vinfo, dataref_groups))
   10155              :     {
   10156            0 :      if (dump_enabled_p ())
   10157            0 :        dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10158              :                         "not vectorized: unhandled data access in "
   10159              :                         "basic block.\n");
   10160            0 :       return false;
   10161              :     }
   10162              : 
   10163      2251752 :   vect_slp_check_for_roots (bb_vinfo);
   10164              : 
   10165              :   /* If there are no grouped stores and no constructors in the region
   10166              :      there is no need to continue with pattern recog as vect_analyze_slp
   10167              :      will fail anyway.  */
   10168      2251752 :   if (bb_vinfo->grouped_stores.is_empty ()
   10169      1903664 :       && bb_vinfo->roots.is_empty ())
   10170              :     {
   10171      1588310 :       if (dump_enabled_p ())
   10172         1012 :         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10173              :                          "not vectorized: no grouped stores in "
   10174              :                          "basic block.\n");
   10175      1588310 :       return false;
   10176              :     }
   10177              : 
   10178              :   /* While the rest of the analysis below depends on it in some way.  */
   10179       663442 :   fatal = false;
   10180              : 
   10181       663442 :   vect_pattern_recog (bb_vinfo);
   10182              : 
   10183              :   /* Update store groups from pattern processing.  */
   10184       663442 :   vect_fixup_store_groups_with_patterns (bb_vinfo);
   10185              : 
   10186              :   /* Check the SLP opportunities in the basic block, analyze and build SLP
   10187              :      trees.  */
   10188       663442 :   if (!vect_analyze_slp (bb_vinfo, n_stmts, false))
   10189              :     {
   10190            0 :       if (dump_enabled_p ())
   10191              :         {
   10192            0 :           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10193              :                            "Failed to SLP the basic block.\n");
   10194            0 :           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10195              :                            "not vectorized: failed to find SLP opportunities "
   10196              :                            "in basic block.\n");
   10197              :         }
   10198            0 :       return false;
   10199              :     }
   10200              : 
   10201              :   /* Optimize permutations.  */
   10202       663442 :   vect_optimize_slp (bb_vinfo);
   10203              : 
   10204              :   /* Gather the loads reachable from the SLP graph entries.  */
   10205       663442 :   vect_gather_slp_loads (bb_vinfo);
   10206              : 
   10207       663442 :   vect_record_base_alignments (bb_vinfo);
   10208              : 
   10209              :   /* Analyze and verify the alignment of data references and the
   10210              :      dependence in the SLP instances.  */
   10211      1489385 :   for (i = 0; BB_VINFO_SLP_INSTANCES (bb_vinfo).iterate (i, &instance); )
   10212              :     {
   10213       825943 :       vect_location = instance->location ();
   10214       825943 :       if (! vect_slp_analyze_instance_alignment (bb_vinfo, instance)
   10215       825943 :           || ! vect_slp_analyze_instance_dependence (bb_vinfo, instance))
   10216              :         {
   10217         8533 :           slp_tree node = SLP_INSTANCE_TREE (instance);
   10218         8533 :           stmt_vec_info stmt_info = SLP_TREE_SCALAR_STMTS (node)[0];
   10219         8533 :           if (dump_enabled_p ())
   10220            4 :             dump_printf_loc (MSG_NOTE, vect_location,
   10221              :                              "removing SLP instance operations starting from: %G",
   10222              :                              stmt_info->stmt);
   10223         8533 :           vect_free_slp_instance (instance);
   10224         8533 :           BB_VINFO_SLP_INSTANCES (bb_vinfo).ordered_remove (i);
   10225         8533 :           continue;
   10226         8533 :         }
   10227              : 
   10228              :       /* Mark all the statements that we want to vectorize as relevant.  */
   10229       817410 :       vect_mark_slp_stmts_relevant (SLP_INSTANCE_TREE (instance));
   10230              : 
   10231       817410 :       i++;
   10232              :     }
   10233      2283668 :   if (! BB_VINFO_SLP_INSTANCES (bb_vinfo).length ())
   10234              :     return false;
   10235              : 
   10236       277133 :   if (!vect_slp_analyze_operations (bb_vinfo))
   10237              :     {
   10238        31916 :       if (dump_enabled_p ())
   10239           69 :         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10240              :                          "not vectorized: bad operation in basic block.\n");
   10241        31916 :       return false;
   10242              :     }
   10243              : 
   10244              :   /* Mark all the statements that we vectorize.  */
   10245       245217 :   vect_bb_slp_mark_stmts_vectorized (bb_vinfo);
   10246              : 
   10247              :   /* Compute vectorizable live stmts.  */
   10248       245217 :   vect_bb_slp_mark_live_stmts (bb_vinfo);
   10249              : 
   10250       245217 :   vect_bb_partition_graph (bb_vinfo);
   10251              : 
   10252       245217 :   return true;
   10253              : }
   10254              : 
   10255              : /* Subroutine of vect_slp_bb.  Try to vectorize the statements for all
   10256              :    basic blocks in BBS, returning true on success.
   10257              :    The region has N_STMTS statements and has the datarefs given by DATAREFS.  */
   10258              : 
   10259              : static bool
   10260      1898616 : vect_slp_region (vec<basic_block> bbs, vec<data_reference_p> datarefs,
   10261              :                  vec<int> *dataref_groups, unsigned int n_stmts,
   10262              :                  loop_p orig_loop)
   10263              : {
   10264      1898616 :   bb_vec_info bb_vinfo;
   10265      1898616 :   auto_vector_modes vector_modes;
   10266              : 
   10267              :   /* Autodetect first vector size we try.  */
   10268      1898616 :   machine_mode next_vector_mode = VOIDmode;
   10269      1898616 :   targetm.vectorize.autovectorize_vector_modes (&vector_modes, false);
   10270      1898616 :   unsigned int mode_i = 0;
   10271              : 
   10272      1898616 :   vec_info_shared shared;
   10273              : 
   10274      1898616 :   machine_mode autodetected_vector_mode = VOIDmode;
   10275      2604888 :   while (1)
   10276              :     {
   10277      2251752 :       bool vectorized = false;
   10278      2251752 :       bool fatal = false;
   10279      2251752 :       bb_vinfo = new _bb_vec_info (bbs, &shared);
   10280              : 
   10281      2251752 :       bool first_time_p = shared.datarefs.is_empty ();
   10282      2251752 :       BB_VINFO_DATAREFS (bb_vinfo) = datarefs;
   10283      2251752 :       if (first_time_p)
   10284      1923054 :         bb_vinfo->shared->save_datarefs ();
   10285              :       else
   10286       328698 :         bb_vinfo->shared->check_datarefs ();
   10287      2251752 :       bb_vinfo->vector_mode = next_vector_mode;
   10288              : 
   10289      2251752 :       if (vect_slp_analyze_bb_1 (bb_vinfo, n_stmts, fatal, dataref_groups))
   10290              :         {
   10291       245217 :           if (dump_enabled_p ())
   10292              :             {
   10293         1576 :               dump_printf_loc (MSG_NOTE, vect_location,
   10294              :                                "***** Analysis succeeded with vector mode"
   10295          788 :                                " %s\n", GET_MODE_NAME (bb_vinfo->vector_mode));
   10296          788 :               dump_printf_loc (MSG_NOTE, vect_location, "SLPing BB part\n");
   10297              :             }
   10298              : 
   10299       245217 :           bb_vinfo->shared->check_datarefs ();
   10300              : 
   10301       245217 :           bool force_clear = false;
   10302       245217 :           auto_vec<slp_instance> profitable_subgraphs;
   10303      1448786 :           for (slp_instance instance : BB_VINFO_SLP_INSTANCES (bb_vinfo))
   10304              :             {
   10305       713135 :               if (instance->subgraph_entries.is_empty ())
   10306       249764 :                 continue;
   10307              : 
   10308       686952 :               dump_user_location_t saved_vect_location = vect_location;
   10309       686952 :               vect_location = instance->location ();
   10310       686952 :               if (!unlimited_cost_model (NULL)
   10311       683183 :                   && !param_vect_allow_possibly_not_worthwhile_vectorizations
   10312      1370126 :                   && !vect_bb_vectorization_profitable_p
   10313       683174 :                         (bb_vinfo, instance->subgraph_entries, orig_loop))
   10314              :                 {
   10315       197398 :                   if (dump_enabled_p ())
   10316           49 :                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10317              :                                      "not vectorized: vectorization is not "
   10318              :                                      "profitable.\n");
   10319       197398 :                   vect_location = saved_vect_location;
   10320       197398 :                   continue;
   10321              :                 }
   10322              : 
   10323       489554 :               vect_location = saved_vect_location;
   10324       489554 :               if (!dbg_cnt (vect_slp))
   10325              :                 {
   10326            0 :                   force_clear = true;
   10327            0 :                   continue;
   10328              :                 }
   10329              : 
   10330       489554 :               profitable_subgraphs.safe_push (instance);
   10331              :             }
   10332              : 
   10333              :           /* When we're vectorizing an if-converted loop body make sure
   10334              :              we vectorized all if-converted code.  */
   10335       407125 :           if ((!profitable_subgraphs.is_empty () || force_clear) && orig_loop)
   10336              :             {
   10337          153 :               gcc_assert (bb_vinfo->nbbs == 1);
   10338          306 :               for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[0]);
   10339         6049 :                    !gsi_end_p (gsi); gsi_next (&gsi))
   10340              :                 {
   10341              :                   /* The costing above left us with DCEable vectorized scalar
   10342              :                      stmts having the visited flag set on profitable
   10343              :                      subgraphs.  Do the delayed clearing of the flag here.  */
   10344         5896 :                   if (gimple_visited_p (gsi_stmt (gsi)))
   10345              :                     {
   10346         1876 :                       gimple_set_visited (gsi_stmt (gsi), false);
   10347         1876 :                       continue;
   10348              :                     }
   10349         4020 :                   if (flag_vect_cost_model == VECT_COST_MODEL_UNLIMITED)
   10350          813 :                     continue;
   10351              : 
   10352         8821 :                   if (gassign *ass = dyn_cast <gassign *> (gsi_stmt (gsi)))
   10353         3647 :                     if (gimple_assign_rhs_code (ass) == COND_EXPR)
   10354              :                       {
   10355          157 :                         if (!profitable_subgraphs.is_empty ()
   10356           68 :                             && dump_enabled_p ())
   10357            0 :                           dump_printf_loc (MSG_NOTE, vect_location,
   10358              :                                            "not profitable because of "
   10359              :                                            "unprofitable if-converted scalar "
   10360              :                                            "code\n");
   10361           89 :                         profitable_subgraphs.truncate (0);
   10362              :                       }
   10363              :                 }
   10364              :             }
   10365              : 
   10366              :           /* Finally schedule the profitable subgraphs.  */
   10367      1058500 :           for (slp_instance instance : profitable_subgraphs)
   10368              :             {
   10369       489467 :               if (!vectorized && dump_enabled_p ())
   10370          749 :                 dump_printf_loc (MSG_NOTE, vect_location,
   10371              :                                  "Basic block will be vectorized "
   10372              :                                  "using SLP\n");
   10373       489467 :               vectorized = true;
   10374              : 
   10375              :               /* Dump before scheduling as store vectorization will remove
   10376              :                  the original stores and mess with the instance tree
   10377              :                  so querying its location will eventually ICE.  */
   10378       489467 :               if (flag_checking)
   10379      1969756 :                 for (slp_instance sub : instance->subgraph_entries)
   10380       501355 :                   gcc_assert (SLP_TREE_VECTYPE (SLP_INSTANCE_TREE (sub)));
   10381       489467 :               unsigned HOST_WIDE_INT bytes;
   10382       489467 :               if (dump_enabled_p ())
   10383         3561 :                 for (slp_instance sub : instance->subgraph_entries)
   10384              :                   {
   10385          942 :                     tree vtype = SLP_TREE_VECTYPE (SLP_INSTANCE_TREE (sub));
   10386         1884 :                     if (GET_MODE_SIZE (TYPE_MODE (vtype)).is_constant (&bytes))
   10387          942 :                       dump_printf_loc (MSG_OPTIMIZED_LOCATIONS,
   10388          942 :                                        sub->location (),
   10389              :                                        "basic block part vectorized using %wu "
   10390              :                                        "byte vectors\n", bytes);
   10391              :                     else
   10392              :                       dump_printf_loc (MSG_OPTIMIZED_LOCATIONS,
   10393              :                                        sub->location (),
   10394              :                                        "basic block part vectorized using "
   10395              :                                        "variable length vectors\n");
   10396              :                   }
   10397              : 
   10398       489467 :               dump_user_location_t saved_vect_location = vect_location;
   10399       489467 :               vect_location = instance->location ();
   10400              : 
   10401       489467 :               vect_schedule_slp (bb_vinfo, instance->subgraph_entries);
   10402              : 
   10403       489467 :               vect_location = saved_vect_location;
   10404              :             }
   10405              : 
   10406              : 
   10407              :           /* Generate the invariant statements.  */
   10408       245217 :           if (!gimple_seq_empty_p (bb_vinfo->inv_pattern_def_seq))
   10409              :             {
   10410           27 :               if (dump_enabled_p ())
   10411            0 :                 dump_printf_loc (MSG_NOTE, vect_location,
   10412              :                          "------>generating invariant statements\n");
   10413              : 
   10414           27 :               bb_vinfo->insert_seq_on_entry (NULL,
   10415              :                                              bb_vinfo->inv_pattern_def_seq);
   10416              :             }
   10417       245217 :         }
   10418              :       else
   10419              :         {
   10420      2006535 :           if (dump_enabled_p ())
   10421         1303 :             dump_printf_loc (MSG_NOTE, vect_location,
   10422              :                              "***** Analysis failed with vector mode %s\n",
   10423         1303 :                              GET_MODE_NAME (bb_vinfo->vector_mode));
   10424              :         }
   10425              : 
   10426      2251752 :       if (mode_i == 0)
   10427      1898616 :         autodetected_vector_mode = bb_vinfo->vector_mode;
   10428              : 
   10429      2251752 :       if (!fatal)
   10430      3269912 :         while (mode_i < vector_modes.length ()
   10431      1887806 :                && vect_chooses_same_modes_p (bb_vinfo, vector_modes[mode_i]))
   10432              :           {
   10433       354718 :             if (dump_enabled_p ())
   10434         1708 :               dump_printf_loc (MSG_NOTE, vect_location,
   10435              :                                "***** The result for vector mode %s would"
   10436              :                                " be the same\n",
   10437          854 :                                GET_MODE_NAME (vector_modes[mode_i]));
   10438       354718 :             mode_i += 1;
   10439              :           }
   10440              : 
   10441      2251752 :       delete bb_vinfo;
   10442              : 
   10443      2251752 :       if (mode_i < vector_modes.length ()
   10444      2057690 :           && VECTOR_MODE_P (autodetected_vector_mode)
   10445      2055872 :           && (related_vector_mode (vector_modes[mode_i],
   10446              :                                    GET_MODE_INNER (autodetected_vector_mode))
   10447      1027936 :               == autodetected_vector_mode)
   10448      4309442 :           && (related_vector_mode (autodetected_vector_mode,
   10449       512599 :                                    GET_MODE_INNER (vector_modes[mode_i]))
   10450      1025198 :               == vector_modes[mode_i]))
   10451              :         {
   10452       512599 :           if (dump_enabled_p ())
   10453          193 :             dump_printf_loc (MSG_NOTE, vect_location,
   10454              :                              "***** Skipping vector mode %s, which would"
   10455              :                              " repeat the analysis for %s\n",
   10456          193 :                              GET_MODE_NAME (vector_modes[mode_i]),
   10457          193 :                              GET_MODE_NAME (autodetected_vector_mode));
   10458       512599 :           mode_i += 1;
   10459              :         }
   10460              : 
   10461      2251752 :       if (vectorized
   10462      2089912 :           || mode_i == vector_modes.length ()
   10463      1895898 :           || autodetected_vector_mode == VOIDmode
   10464              :           /* If vect_slp_analyze_bb_1 signaled that analysis for all
   10465              :              vector sizes will fail do not bother iterating.  */
   10466      3117896 :           || fatal)
   10467      3797232 :         return vectorized;
   10468              : 
   10469              :       /* Try the next biggest vector size.  */
   10470       353136 :       next_vector_mode = vector_modes[mode_i++];
   10471       353136 :       if (dump_enabled_p ())
   10472          227 :         dump_printf_loc (MSG_NOTE, vect_location,
   10473              :                          "***** Re-trying analysis with vector mode %s\n",
   10474          227 :                          GET_MODE_NAME (next_vector_mode));
   10475       353136 :     }
   10476      1898616 : }
   10477              : 
   10478              : 
   10479              : /* Main entry for the BB vectorizer.  Analyze and transform BBS, returns
   10480              :    true if anything in the basic-block was vectorized.  */
   10481              : 
   10482              : static bool
   10483      1898616 : vect_slp_bbs (const vec<basic_block> &bbs, loop_p orig_loop)
   10484              : {
   10485      1898616 :   vec<data_reference_p> datarefs = vNULL;
   10486      1898616 :   auto_vec<int> dataref_groups;
   10487      1898616 :   int insns = 0;
   10488      1898616 :   int current_group = 0;
   10489              : 
   10490     12610412 :   for (unsigned i = 0; i < bbs.length (); i++)
   10491              :     {
   10492     10711796 :       basic_block bb = bbs[i];
   10493     92068999 :       for (gimple_stmt_iterator gsi = gsi_after_labels (bb); !gsi_end_p (gsi);
   10494     81357203 :            gsi_next (&gsi))
   10495              :         {
   10496     81357203 :           gimple *stmt = gsi_stmt (gsi);
   10497     81357203 :           if (is_gimple_debug (stmt))
   10498     51028113 :             continue;
   10499              : 
   10500     30329090 :           insns++;
   10501              : 
   10502     30329090 :           if (gimple_location (stmt) != UNKNOWN_LOCATION)
   10503     27219941 :             vect_location = stmt;
   10504              : 
   10505     30329090 :           if (!vect_find_stmt_data_reference (NULL, stmt, &datarefs,
   10506              :                                               &dataref_groups, current_group))
   10507      5175397 :             ++current_group;
   10508              :         }
   10509              :       /* New BBs always start a new DR group.  */
   10510     10711796 :       ++current_group;
   10511              :     }
   10512              : 
   10513      1898616 :   return vect_slp_region (bbs, datarefs, &dataref_groups, insns, orig_loop);
   10514      1898616 : }
   10515              : 
   10516              : /* Special entry for the BB vectorizer.  Analyze and transform a single
   10517              :    if-converted BB with ORIG_LOOPs body being the not if-converted
   10518              :    representation.  Returns true if anything in the basic-block was
   10519              :    vectorized.  */
   10520              : 
   10521              : bool
   10522        19445 : vect_slp_if_converted_bb (basic_block bb, loop_p orig_loop)
   10523              : {
   10524        19445 :   auto_vec<basic_block> bbs;
   10525        19445 :   bbs.safe_push (bb);
   10526        19445 :   return vect_slp_bbs (bbs, orig_loop);
   10527        19445 : }
   10528              : 
   10529              : /* Main entry for the BB vectorizer.  Analyze and transform BB, returns
   10530              :    true if anything in the basic-block was vectorized.  */
   10531              : 
   10532              : bool
   10533       914389 : vect_slp_function (function *fun)
   10534              : {
   10535       914389 :   bool r = false;
   10536       914389 :   int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
   10537       914389 :   auto_bitmap exit_bbs;
   10538       914389 :   bitmap_set_bit (exit_bbs, EXIT_BLOCK);
   10539       914389 :   edge entry = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (fun));
   10540       914389 :   unsigned n = rev_post_order_and_mark_dfs_back_seme (fun, entry, exit_bbs,
   10541       914389 :                                                       true, rpo, NULL);
   10542              : 
   10543              :   /* For the moment split the function into pieces to avoid making
   10544              :      the iteration on the vector mode moot.  Split at points we know
   10545              :      to not handle well which is CFG merges (SLP discovery doesn't
   10546              :      handle non-loop-header PHIs) and loop exits.  Since pattern
   10547              :      recog requires reverse iteration to visit uses before defs
   10548              :      simply chop RPO into pieces.  */
   10549       914389 :   auto_vec<basic_block> bbs;
   10550     11637665 :   for (unsigned i = 0; i < n; i++)
   10551              :     {
   10552     10723276 :       basic_block bb = BASIC_BLOCK_FOR_FN (fun, rpo[i]);
   10553     10723276 :       bool split = false;
   10554              : 
   10555              :       /* Split when a BB is not dominated by the first block.  */
   10556     20224021 :       if (!bbs.is_empty ()
   10557      9500745 :           && !dominated_by_p (CDI_DOMINATORS, bb, bbs[0]))
   10558              :         {
   10559       676425 :           if (dump_enabled_p ())
   10560          146 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10561              :                              "splitting region at dominance boundary bb%d\n",
   10562              :                              bb->index);
   10563              :           split = true;
   10564              :         }
   10565              :       /* Split when the loop determined by the first block
   10566              :          is exited.  This is because we eventually insert
   10567              :          invariants at region begin.  */
   10568     18871171 :       else if (!bbs.is_empty ()
   10569      8824320 :                && bbs[0]->loop_father != bb->loop_father
   10570      2299697 :                && !flow_loop_nested_p (bbs[0]->loop_father, bb->loop_father))
   10571              :         {
   10572         3844 :           if (dump_enabled_p ())
   10573            6 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10574              :                              "splitting region at loop %d exit at bb%d\n",
   10575            3 :                              bbs[0]->loop_father->num, bb->index);
   10576              :           split = true;
   10577              :         }
   10578     10043007 :       else if (!bbs.is_empty ()
   10579      8820476 :                && bb->loop_father->header == bb
   10580       472683 :                && bb->loop_father->dont_vectorize)
   10581              :         {
   10582         7296 :           if (dump_enabled_p ())
   10583           72 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10584              :                              "splitting region at dont-vectorize loop %d "
   10585              :                              "entry at bb%d\n",
   10586              :                              bb->loop_father->num, bb->index);
   10587              :           split = true;
   10588              :         }
   10589              : 
   10590     11410841 :       if (split && !bbs.is_empty ())
   10591              :         {
   10592       687565 :           r |= vect_slp_bbs (bbs, NULL);
   10593       687565 :           bbs.truncate (0);
   10594              :         }
   10595              : 
   10596     10723276 :       if (bbs.is_empty ())
   10597              :         {
   10598              :           /* We need to be able to insert at the head of the region which
   10599              :              we cannot for region starting with a returns-twice call.  */
   10600      1910096 :           if (gcall *first = safe_dyn_cast <gcall *> (first_stmt (bb)))
   10601       403108 :             if (gimple_call_flags (first) & ECF_RETURNS_TWICE)
   10602              :               {
   10603          306 :                 if (dump_enabled_p ())
   10604            2 :                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10605              :                                    "skipping bb%d as start of region as it "
   10606              :                                    "starts with returns-twice call\n",
   10607              :                                    bb->index);
   10608        30925 :                 continue;
   10609              :               }
   10610              :           /* If the loop this BB belongs to is marked as not to be vectorized
   10611              :              honor that also for BB vectorization.  */
   10612      1909790 :           if (bb->loop_father->dont_vectorize)
   10613        30619 :             continue;
   10614              :         }
   10615              : 
   10616     10692351 :       bbs.safe_push (bb);
   10617              : 
   10618              :       /* When we have a stmt ending this block and defining a
   10619              :          value we have to insert on edges when inserting after it for
   10620              :          a vector containing its definition.  Avoid this for now.  */
   10621     21384702 :       if (gimple *last = *gsi_last_bb (bb))
   10622      8684558 :         if (gimple_get_lhs (last)
   10623      8684558 :             && is_ctrl_altering_stmt (last))
   10624              :           {
   10625       277224 :             if (dump_enabled_p ())
   10626            2 :               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10627              :                                "splitting region at control altering "
   10628              :                                "definition %G", last);
   10629       277224 :             r |= vect_slp_bbs (bbs, NULL);
   10630       277224 :             bbs.truncate (0);
   10631              :           }
   10632              :     }
   10633              : 
   10634       914389 :   if (!bbs.is_empty ())
   10635       914382 :     r |= vect_slp_bbs (bbs, NULL);
   10636              : 
   10637       914389 :   free (rpo);
   10638              : 
   10639       914389 :   return r;
   10640       914389 : }
   10641              : 
   10642              : /* Build a variable-length vector in which the elements in ELTS are repeated
   10643              :    to a fill NRESULTS vectors of type VECTOR_TYPE.  Store the vectors in
   10644              :    RESULTS and add any new instructions to SEQ.
   10645              : 
   10646              :    The approach we use is:
   10647              : 
   10648              :    (1) Find a vector mode VM with integer elements of mode IM.
   10649              : 
   10650              :    (2) Replace ELTS[0:NELTS] with ELTS'[0:NELTS'], where each element of
   10651              :        ELTS' has mode IM.  This involves creating NELTS' VIEW_CONVERT_EXPRs
   10652              :        from small vectors to IM.
   10653              : 
   10654              :    (3) Duplicate each ELTS'[I] into a vector of mode VM.
   10655              : 
   10656              :    (4) Use a tree of interleaving VEC_PERM_EXPRs to create VMs with the
   10657              :        correct byte contents.
   10658              : 
   10659              :    (5) Use VIEW_CONVERT_EXPR to cast the final VMs to the required type.
   10660              : 
   10661              :    We try to find the largest IM for which this sequence works, in order
   10662              :    to cut down on the number of interleaves.  */
   10663              : 
   10664              : void
   10665            0 : duplicate_and_interleave (vec_info *vinfo, gimple_seq *seq, tree vector_type,
   10666              :                           const vec<tree> &elts, unsigned int nresults,
   10667              :                           vec<tree> &results)
   10668              : {
   10669            0 :   unsigned int nelts = elts.length ();
   10670            0 :   tree element_type = TREE_TYPE (vector_type);
   10671              : 
   10672              :   /* (1) Find a vector mode VM with integer elements of mode IM.  */
   10673            0 :   unsigned int nvectors = 1;
   10674            0 :   tree new_vector_type;
   10675            0 :   tree permutes[2];
   10676            0 :   if (!can_duplicate_and_interleave_p (vinfo, nelts, element_type,
   10677              :                                        &nvectors, &new_vector_type,
   10678              :                                        permutes))
   10679            0 :     gcc_unreachable ();
   10680              : 
   10681              :   /* Get a vector type that holds ELTS[0:NELTS/NELTS'].  */
   10682            0 :   unsigned int partial_nelts = nelts / nvectors;
   10683            0 :   tree partial_vector_type = build_vector_type (element_type, partial_nelts);
   10684              : 
   10685            0 :   tree_vector_builder partial_elts;
   10686            0 :   auto_vec<tree, 32> pieces (nvectors * 2);
   10687            0 :   pieces.quick_grow_cleared (nvectors * 2);
   10688            0 :   for (unsigned int i = 0; i < nvectors; ++i)
   10689              :     {
   10690              :       /* (2) Replace ELTS[0:NELTS] with ELTS'[0:NELTS'], where each element of
   10691              :              ELTS' has mode IM.  */
   10692            0 :       partial_elts.new_vector (partial_vector_type, partial_nelts, 1);
   10693            0 :       for (unsigned int j = 0; j < partial_nelts; ++j)
   10694            0 :         partial_elts.quick_push (elts[i * partial_nelts + j]);
   10695            0 :       tree t = gimple_build_vector (seq, &partial_elts);
   10696            0 :       t = gimple_build (seq, VIEW_CONVERT_EXPR,
   10697            0 :                         TREE_TYPE (new_vector_type), t);
   10698              : 
   10699              :       /* (3) Duplicate each ELTS'[I] into a vector of mode VM.  */
   10700            0 :       pieces[i] = gimple_build_vector_from_val (seq, new_vector_type, t);
   10701              :     }
   10702              : 
   10703              :   /* (4) Use a tree of VEC_PERM_EXPRs to create a single VM with the
   10704              :          correct byte contents.
   10705              : 
   10706              :      Conceptually, we need to repeat the following operation log2(nvectors)
   10707              :      times, where hi_start = nvectors / 2:
   10708              : 
   10709              :         out[i * 2] = VEC_PERM_EXPR (in[i], in[i + hi_start], lo_permute);
   10710              :         out[i * 2 + 1] = VEC_PERM_EXPR (in[i], in[i + hi_start], hi_permute);
   10711              : 
   10712              :      However, if each input repeats every N elements and the VF is
   10713              :      a multiple of N * 2, the HI result is the same as the LO result.
   10714              :      This will be true for the first N1 iterations of the outer loop,
   10715              :      followed by N2 iterations for which both the LO and HI results
   10716              :      are needed.  I.e.:
   10717              : 
   10718              :         N1 + N2 = log2(nvectors)
   10719              : 
   10720              :      Each "N1 iteration" doubles the number of redundant vectors and the
   10721              :      effect of the process as a whole is to have a sequence of nvectors/2**N1
   10722              :      vectors that repeats 2**N1 times.  Rather than generate these redundant
   10723              :      vectors, we halve the number of vectors for each N1 iteration.  */
   10724              :   unsigned int in_start = 0;
   10725              :   unsigned int out_start = nvectors;
   10726              :   unsigned int new_nvectors = nvectors;
   10727            0 :   for (unsigned int in_repeat = 1; in_repeat < nvectors; in_repeat *= 2)
   10728              :     {
   10729            0 :       unsigned int hi_start = new_nvectors / 2;
   10730            0 :       unsigned int out_i = 0;
   10731            0 :       for (unsigned int in_i = 0; in_i < new_nvectors; ++in_i)
   10732              :         {
   10733            0 :           if ((in_i & 1) != 0
   10734            0 :               && multiple_p (TYPE_VECTOR_SUBPARTS (new_vector_type),
   10735              :                              2 * in_repeat))
   10736            0 :             continue;
   10737              : 
   10738            0 :           tree output = make_ssa_name (new_vector_type);
   10739            0 :           tree input1 = pieces[in_start + (in_i / 2)];
   10740            0 :           tree input2 = pieces[in_start + (in_i / 2) + hi_start];
   10741            0 :           gassign *stmt = gimple_build_assign (output, VEC_PERM_EXPR,
   10742              :                                                input1, input2,
   10743              :                                                permutes[in_i & 1]);
   10744            0 :           gimple_seq_add_stmt (seq, stmt);
   10745            0 :           pieces[out_start + out_i] = output;
   10746            0 :           out_i += 1;
   10747              :         }
   10748            0 :       std::swap (in_start, out_start);
   10749            0 :       new_nvectors = out_i;
   10750              :     }
   10751              : 
   10752              :   /* (5) Use VIEW_CONVERT_EXPR to cast the final VM to the required type.  */
   10753            0 :   results.reserve (nresults);
   10754            0 :   for (unsigned int i = 0; i < nresults; ++i)
   10755            0 :     if (i < new_nvectors)
   10756            0 :       results.quick_push (gimple_build (seq, VIEW_CONVERT_EXPR, vector_type,
   10757            0 :                                         pieces[in_start + i]));
   10758              :     else
   10759            0 :       results.quick_push (results[i - new_nvectors]);
   10760            0 : }
   10761              : 
   10762              : 
   10763              : /* For constant and loop invariant defs in OP_NODE this function creates
   10764              :    vector defs that will be used in the vectorized stmts and stores them
   10765              :    to SLP_TREE_VEC_DEFS of OP_NODE.  */
   10766              : 
   10767              : static void
   10768       498514 : vect_create_constant_vectors (vec_info *vinfo, slp_tree op_node)
   10769              : {
   10770       498514 :   unsigned HOST_WIDE_INT nunits;
   10771       498514 :   tree vec_cst;
   10772       498514 :   unsigned j, number_of_places_left_in_vector;
   10773       498514 :   tree vector_type;
   10774       498514 :   tree vop;
   10775       498514 :   int group_size = op_node->ops.length ();
   10776       498514 :   unsigned int vec_num, i;
   10777       498514 :   unsigned number_of_copies = 1;
   10778       498514 :   bool constant_p;
   10779       498514 :   gimple_seq ctor_seq = NULL;
   10780       498514 :   auto_vec<tree, 16> permute_results;
   10781              : 
   10782              :   /* We always want SLP_TREE_VECTYPE (op_node) here correctly set.  */
   10783       498514 :   vector_type = SLP_TREE_VECTYPE (op_node);
   10784              : 
   10785       498514 :   unsigned int number_of_vectors = vect_get_num_copies (vinfo, op_node);
   10786       498514 :   SLP_TREE_VEC_DEFS (op_node).create (number_of_vectors);
   10787       498514 :   auto_vec<tree> voprnds (number_of_vectors);
   10788              : 
   10789              :   /* NUMBER_OF_COPIES is the number of times we need to use the same values in
   10790              :      created vectors. It is greater than 1 if unrolling is performed.
   10791              : 
   10792              :      For example, we have two scalar operands, s1 and s2 (e.g., group of
   10793              :      strided accesses of size two), while NUNITS is four (i.e., four scalars
   10794              :      of this type can be packed in a vector).  The output vector will contain
   10795              :      two copies of each scalar operand: {s1, s2, s1, s2}.  (NUMBER_OF_COPIES
   10796              :      will be 2).
   10797              : 
   10798              :      If GROUP_SIZE > NUNITS, the scalars will be split into several vectors
   10799              :      containing the operands.
   10800              : 
   10801              :      For example, NUNITS is four as before, and the group size is 8
   10802              :      (s1, s2, ..., s8).  We will create two vectors {s1, s2, s3, s4} and
   10803              :      {s5, s6, s7, s8}.  */
   10804              : 
   10805              :   /* When using duplicate_and_interleave, we just need one element for
   10806              :      each scalar statement.  */
   10807       498514 :   if (!TYPE_VECTOR_SUBPARTS (vector_type).is_constant (&nunits))
   10808              :     nunits = group_size;
   10809              : 
   10810       498514 :   number_of_copies = nunits * number_of_vectors / group_size;
   10811              : 
   10812       498514 :   number_of_places_left_in_vector = nunits;
   10813       498514 :   constant_p = true;
   10814       498514 :   tree uniform_elt = NULL_TREE;
   10815       498514 :   tree_vector_builder elts (vector_type, nunits, 1);
   10816       498514 :   elts.quick_grow (nunits);
   10817       498514 :   stmt_vec_info insert_after = NULL;
   10818      1481362 :   for (j = 0; j < number_of_copies; j++)
   10819              :     {
   10820       982848 :       tree op;
   10821      3772406 :       for (i = group_size - 1; op_node->ops.iterate (i, &op); i--)
   10822              :         {
   10823              :           /* Create 'vect_ = {op0,op1,...,opn}'.  */
   10824      1806710 :           tree orig_op = op;
   10825      1806710 :           if (number_of_places_left_in_vector == nunits)
   10826              :             uniform_elt = op;
   10827      1177370 :           else if (uniform_elt && operand_equal_p (uniform_elt, op))
   10828       746279 :             op = elts[number_of_places_left_in_vector];
   10829              :           else
   10830              :             uniform_elt = NULL_TREE;
   10831      1806710 :           number_of_places_left_in_vector--;
   10832      1806710 :           if (!types_compatible_p (TREE_TYPE (vector_type), TREE_TYPE (op)))
   10833              :             {
   10834       280771 :               if (CONSTANT_CLASS_P (op))
   10835              :                 {
   10836       102599 :                   if (VECTOR_BOOLEAN_TYPE_P (vector_type))
   10837              :                     {
   10838              :                       /* Can't use VIEW_CONVERT_EXPR for booleans because
   10839              :                          of possibly different sizes of scalar value and
   10840              :                          vector element.  */
   10841           66 :                       if (integer_zerop (op))
   10842           66 :                         op = build_int_cst (TREE_TYPE (vector_type), 0);
   10843            0 :                       else if (integer_onep (op))
   10844            0 :                         op = build_all_ones_cst (TREE_TYPE (vector_type));
   10845              :                       else
   10846            0 :                         gcc_unreachable ();
   10847              :                     }
   10848              :                   else
   10849       102533 :                     op = fold_unary (VIEW_CONVERT_EXPR,
   10850              :                                      TREE_TYPE (vector_type), op);
   10851       102599 :                   gcc_assert (op && CONSTANT_CLASS_P (op));
   10852              :                 }
   10853              :               else
   10854              :                 {
   10855       178172 :                   tree new_temp = make_ssa_name (TREE_TYPE (vector_type));
   10856       178172 :                   gimple *init_stmt;
   10857       178172 :                   if (VECTOR_BOOLEAN_TYPE_P (vector_type))
   10858              :                     {
   10859          427 :                       tree true_val
   10860          427 :                         = build_all_ones_cst (TREE_TYPE (vector_type));
   10861          427 :                       tree false_val
   10862          427 :                         = build_zero_cst (TREE_TYPE (vector_type));
   10863          427 :                       gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (op)));
   10864          427 :                       init_stmt = gimple_build_assign (new_temp, COND_EXPR,
   10865              :                                                        op, true_val,
   10866              :                                                        false_val);
   10867              :                     }
   10868              :                   else
   10869              :                     {
   10870       177745 :                       op = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (vector_type),
   10871              :                                    op);
   10872       177745 :                       init_stmt
   10873       177745 :                         = gimple_build_assign (new_temp, VIEW_CONVERT_EXPR,
   10874              :                                                op);
   10875              :                     }
   10876       178172 :                   gimple_seq_add_stmt (&ctor_seq, init_stmt);
   10877       178172 :                   op = new_temp;
   10878              :                 }
   10879              :             }
   10880      1806710 :           elts[number_of_places_left_in_vector] = op;
   10881      1806710 :           if (!CONSTANT_CLASS_P (op))
   10882       322146 :             constant_p = false;
   10883              :           /* For BB vectorization we have to compute an insert location
   10884              :              when a def is inside the analyzed region since we cannot
   10885              :              simply insert at the BB start in this case.  */
   10886      1806710 :           stmt_vec_info opdef;
   10887      1806710 :           if (TREE_CODE (orig_op) == SSA_NAME
   10888       184927 :               && !SSA_NAME_IS_DEFAULT_DEF (orig_op)
   10889       164718 :               && is_a <bb_vec_info> (vinfo)
   10890      1913647 :               && (opdef = vinfo->lookup_def (orig_op)))
   10891              :             {
   10892        87177 :               if (!insert_after)
   10893              :                 insert_after = opdef;
   10894              :               else
   10895        47933 :                 insert_after = get_later_stmt (insert_after, opdef);
   10896              :             }
   10897              : 
   10898      1806710 :           if (number_of_places_left_in_vector == 0)
   10899              :             {
   10900       629340 :               auto type_nunits = TYPE_VECTOR_SUBPARTS (vector_type);
   10901       629340 :               if (uniform_elt)
   10902       653744 :                 vec_cst = gimple_build_vector_from_val (&ctor_seq, vector_type,
   10903       326872 :                                                         elts[0]);
   10904       604936 :               else if (constant_p
   10905       604936 :                        ? multiple_p (type_nunits, nunits)
   10906       111775 :                        : known_eq (type_nunits, nunits))
   10907       302468 :                 vec_cst = gimple_build_vector (&ctor_seq, &elts);
   10908              :               else
   10909              :                 {
   10910            0 :                   if (permute_results.is_empty ())
   10911            0 :                     duplicate_and_interleave (vinfo, &ctor_seq, vector_type,
   10912              :                                               elts, number_of_vectors,
   10913              :                                               permute_results);
   10914            0 :                   vec_cst = permute_results[number_of_vectors - j - 1];
   10915              :                 }
   10916       629340 :               if (!gimple_seq_empty_p (ctor_seq))
   10917              :                 {
   10918       139523 :                   if (insert_after)
   10919              :                     {
   10920        39244 :                       gimple_stmt_iterator gsi;
   10921        39244 :                       if (gimple_code (insert_after->stmt) == GIMPLE_PHI)
   10922              :                         {
   10923          698 :                           gsi = gsi_after_labels (gimple_bb (insert_after->stmt));
   10924          698 :                           gsi_insert_seq_before (&gsi, ctor_seq,
   10925              :                                                  GSI_CONTINUE_LINKING);
   10926              :                         }
   10927        38546 :                       else if (!stmt_ends_bb_p (insert_after->stmt))
   10928              :                         {
   10929        38546 :                           gsi = gsi_for_stmt (insert_after->stmt);
   10930        38546 :                           gsi_insert_seq_after (&gsi, ctor_seq,
   10931              :                                                 GSI_CONTINUE_LINKING);
   10932              :                         }
   10933              :                       else
   10934              :                         {
   10935              :                           /* When we want to insert after a def where the
   10936              :                              defining stmt throws then insert on the fallthru
   10937              :                              edge.  */
   10938            0 :                           edge e = find_fallthru_edge
   10939            0 :                                      (gimple_bb (insert_after->stmt)->succs);
   10940            0 :                           basic_block new_bb
   10941            0 :                             = gsi_insert_seq_on_edge_immediate (e, ctor_seq);
   10942            0 :                           gcc_assert (!new_bb);
   10943              :                         }
   10944              :                     }
   10945              :                   else
   10946       100279 :                     vinfo->insert_seq_on_entry (NULL, ctor_seq);
   10947       139523 :                   ctor_seq = NULL;
   10948              :                 }
   10949       629340 :               voprnds.quick_push (vec_cst);
   10950       629340 :               insert_after = NULL;
   10951       629340 :               number_of_places_left_in_vector = nunits;
   10952       629340 :               constant_p = true;
   10953       629340 :               elts.new_vector (vector_type, nunits, 1);
   10954       629340 :               elts.quick_grow (nunits);
   10955              :             }
   10956              :         }
   10957              :     }
   10958              : 
   10959              :   /* Since the vectors are created in the reverse order, we should invert
   10960              :      them.  */
   10961       498514 :   vec_num = voprnds.length ();
   10962      1127854 :   for (j = vec_num; j != 0; j--)
   10963              :     {
   10964       629340 :       vop = voprnds[j - 1];
   10965       629340 :       SLP_TREE_VEC_DEFS (op_node).quick_push (vop);
   10966              :     }
   10967              : 
   10968              :   /* In case that VF is greater than the unrolling factor needed for the SLP
   10969              :      group of stmts, NUMBER_OF_VECTORS to be created is greater than
   10970              :      NUMBER_OF_SCALARS/NUNITS or NUNITS/NUMBER_OF_SCALARS, and hence we have
   10971              :      to replicate the vectors.  */
   10972       498514 :   while (number_of_vectors > SLP_TREE_VEC_DEFS (op_node).length ())
   10973       498514 :     for (i = 0; SLP_TREE_VEC_DEFS (op_node).iterate (i, &vop) && i < vec_num;
   10974              :          i++)
   10975            0 :       SLP_TREE_VEC_DEFS (op_node).quick_push (vop);
   10976       498514 : }
   10977              : 
   10978              : /* Get the scalar definition of the Nth lane from SLP_NODE or NULL_TREE
   10979              :    if there is no definition for it in the scalar IL or it is not known.  */
   10980              : 
   10981              : tree
   10982         2617 : vect_get_slp_scalar_def (slp_tree slp_node, unsigned n)
   10983              : {
   10984         2617 :   if (SLP_TREE_DEF_TYPE (slp_node) == vect_internal_def)
   10985              :     {
   10986         2605 :       if (!SLP_TREE_SCALAR_STMTS (slp_node).exists ())
   10987              :         return NULL_TREE;
   10988         2605 :       stmt_vec_info def = SLP_TREE_SCALAR_STMTS (slp_node)[n];
   10989         2605 :       if (!def)
   10990              :         return NULL_TREE;
   10991         2605 :       return gimple_get_lhs (STMT_VINFO_STMT (def));
   10992              :     }
   10993              :   else
   10994           12 :     return SLP_TREE_SCALAR_OPS (slp_node)[n];
   10995              : }
   10996              : 
   10997              : /* Get the Ith vectorized definition from SLP_NODE.  */
   10998              : 
   10999              : tree
   11000       147771 : vect_get_slp_vect_def (slp_tree slp_node, unsigned i)
   11001              : {
   11002       147771 :   return SLP_TREE_VEC_DEFS (slp_node)[i];
   11003              : }
   11004              : 
   11005              : /* Get the vectorized definitions of SLP_NODE in *VEC_DEFS.  */
   11006              : 
   11007              : void
   11008       947664 : vect_get_slp_defs (slp_tree slp_node, vec<tree> *vec_defs)
   11009              : {
   11010      1895328 :   vec_defs->create (SLP_TREE_VEC_DEFS (slp_node).length ());
   11011       947664 :   vec_defs->splice (SLP_TREE_VEC_DEFS (slp_node));
   11012       947664 : }
   11013              : 
   11014              : /* Get N vectorized definitions for SLP_NODE.  */
   11015              : 
   11016              : void
   11017         2953 : vect_get_slp_defs (vec_info *,
   11018              :                    slp_tree slp_node, vec<vec<tree> > *vec_oprnds, unsigned n)
   11019              : {
   11020         2953 :   if (n == -1U)
   11021         2953 :     n = SLP_TREE_CHILDREN (slp_node).length ();
   11022              : 
   11023        10648 :   for (unsigned i = 0; i < n; ++i)
   11024              :     {
   11025         7695 :       slp_tree child = SLP_TREE_CHILDREN (slp_node)[i];
   11026         7695 :       vec<tree> vec_defs = vNULL;
   11027         7695 :       vect_get_slp_defs (child, &vec_defs);
   11028         7695 :       vec_oprnds->quick_push (vec_defs);
   11029              :     }
   11030         2953 : }
   11031              : 
   11032              : /* A subroutine of vect_transform_slp_perm_load with two extra arguments:
   11033              :    - PERM gives the permutation that the caller wants to use for NODE,
   11034              :      which might be different from SLP_LOAD_PERMUTATION.
   11035              :    - DUMP_P controls whether the function dumps information.  */
   11036              : 
   11037              : static bool
   11038       137914 : vect_transform_slp_perm_load_1 (vec_info *vinfo, slp_tree node,
   11039              :                                 load_permutation_t &perm,
   11040              :                                 const vec<tree> &dr_chain,
   11041              :                                 gimple_stmt_iterator *gsi, poly_uint64 vf,
   11042              :                                 bool analyze_only, bool dump_p,
   11043              :                                 unsigned *n_perms, unsigned int *n_loads,
   11044              :                                 bool dce_chain)
   11045              : {
   11046       137914 :   stmt_vec_info stmt_info = SLP_TREE_SCALAR_STMTS (node)[0];
   11047       137914 :   int vec_index = 0;
   11048       137914 :   tree vectype = SLP_TREE_VECTYPE (node);
   11049       137914 :   unsigned int group_size = SLP_TREE_LANES (node);
   11050       137914 :   unsigned int mask_element;
   11051       137914 :   unsigned dr_group_size;
   11052       137914 :   machine_mode mode;
   11053              : 
   11054       137914 :   if (!STMT_VINFO_GROUPED_ACCESS (stmt_info))
   11055              :     {
   11056              :       /* We have both splats of the same non-grouped load and groups
   11057              :          of distinct invariant loads entering here.  */
   11058         1491 :       unsigned max_idx = 0;
   11059         8261 :       for (auto idx : perm)
   11060         3788 :         max_idx = idx > max_idx ? idx : max_idx;
   11061         1491 :       dr_group_size = max_idx + 1;
   11062              :     }
   11063              :   else
   11064              :     {
   11065       136423 :       stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
   11066       136423 :       dr_group_size = DR_GROUP_SIZE (stmt_info);
   11067              :     }
   11068              : 
   11069       137914 :   mode = TYPE_MODE (vectype);
   11070       137914 :   poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
   11071       137914 :   unsigned int nstmts = vect_get_num_copies (vinfo, node);
   11072              : 
   11073              :   /* Initialize the vect stmts of NODE to properly insert the generated
   11074              :      stmts later.  */
   11075       137914 :   if (! analyze_only)
   11076        58773 :     for (unsigned i = SLP_TREE_VEC_DEFS (node).length (); i < nstmts; i++)
   11077        22623 :       SLP_TREE_VEC_DEFS (node).quick_push (NULL_TREE);
   11078              : 
   11079              :   /* Generate permutation masks for every NODE. Number of masks for each NODE
   11080              :      is equal to GROUP_SIZE.
   11081              :      E.g., we have a group of three nodes with three loads from the same
   11082              :      location in each node, and the vector size is 4. I.e., we have a
   11083              :      a0b0c0a1b1c1... sequence and we need to create the following vectors:
   11084              :      for a's: a0a0a0a1 a1a1a2a2 a2a3a3a3
   11085              :      for b's: b0b0b0b1 b1b1b2b2 b2b3b3b3
   11086              :      ...
   11087              : 
   11088              :      The masks for a's should be: {0,0,0,3} {3,3,6,6} {6,9,9,9}.
   11089              :      The last mask is illegal since we assume two operands for permute
   11090              :      operation, and the mask element values can't be outside that range.
   11091              :      Hence, the last mask must be converted into {2,5,5,5}.
   11092              :      For the first two permutations we need the first and the second input
   11093              :      vectors: {a0,b0,c0,a1} and {b1,c1,a2,b2}, and for the last permutation
   11094              :      we need the second and the third vectors: {b1,c1,a2,b2} and
   11095              :      {c2,a3,b3,c3}.  */
   11096              : 
   11097       137914 :   int vect_stmts_counter = 0;
   11098       137914 :   unsigned int index = 0;
   11099       137914 :   int first_vec_index = -1;
   11100       137914 :   int second_vec_index = -1;
   11101       137914 :   bool noop_p = true;
   11102       137914 :   *n_perms = 0;
   11103              : 
   11104       137914 :   vec_perm_builder mask;
   11105       137914 :   unsigned int nelts_to_build;
   11106       137914 :   unsigned int nvectors_per_build;
   11107       137914 :   unsigned int in_nlanes;
   11108       137914 :   bool repeating_p = (group_size == dr_group_size
   11109       173509 :                       && multiple_p (nunits, group_size));
   11110       137914 :   if (repeating_p)
   11111              :     {
   11112              :       /* A single vector contains a whole number of copies of the node, so:
   11113              :          (a) all permutes can use the same mask; and
   11114              :          (b) the permutes only need a single vector input.  */
   11115        33187 :       mask.new_vector (nunits, group_size, 3);
   11116        33187 :       nelts_to_build = mask.encoded_nelts ();
   11117              :       /* It's possible to obtain zero nstmts during analyze_only, so make
   11118              :          it at least one to ensure the later computation for n_perms
   11119              :          proceed.  */
   11120        33187 :       nvectors_per_build = nstmts > 0 ? nstmts : 1;
   11121        33187 :       in_nlanes = dr_group_size * 3;
   11122              :     }
   11123              :   else
   11124              :     {
   11125              :       /* We need to construct a separate mask for each vector statement.  */
   11126       104727 :       unsigned HOST_WIDE_INT const_nunits, const_vf;
   11127       104727 :       if (!nunits.is_constant (&const_nunits)
   11128       104727 :           || !vf.is_constant (&const_vf))
   11129              :         return false;
   11130       104727 :       mask.new_vector (const_nunits, const_nunits, 1);
   11131       104727 :       nelts_to_build = const_vf * group_size;
   11132       104727 :       nvectors_per_build = 1;
   11133       104727 :       in_nlanes = const_vf * dr_group_size;
   11134              :     }
   11135       137914 :   auto_sbitmap used_in_lanes (in_nlanes);
   11136       137914 :   bitmap_clear (used_in_lanes);
   11137       137914 :   auto_bitmap used_defs;
   11138              : 
   11139       137914 :   unsigned int count = mask.encoded_nelts ();
   11140       137914 :   mask.quick_grow (count);
   11141       137914 :   vec_perm_indices indices;
   11142              : 
   11143       723912 :   for (unsigned int j = 0; j < nelts_to_build; j++)
   11144              :     {
   11145       597373 :       unsigned int iter_num = j / group_size;
   11146       597373 :       unsigned int stmt_num = j % group_size;
   11147       597373 :       unsigned int i = (iter_num * dr_group_size + perm[stmt_num]);
   11148       597373 :       bitmap_set_bit (used_in_lanes, i);
   11149       597373 :       if (repeating_p)
   11150              :         {
   11151              :           first_vec_index = 0;
   11152              :           mask_element = i;
   11153              :         }
   11154              :       else
   11155              :         {
   11156              :           /* Enforced before the loop when !repeating_p.  */
   11157       381163 :           unsigned int const_nunits = nunits.to_constant ();
   11158       381163 :           vec_index = i / const_nunits;
   11159       381163 :           mask_element = i % const_nunits;
   11160       381163 :           if (vec_index == first_vec_index
   11161       381163 :               || first_vec_index == -1)
   11162              :             {
   11163              :               first_vec_index = vec_index;
   11164              :             }
   11165       152744 :           else if (vec_index == second_vec_index
   11166       152744 :                    || second_vec_index == -1)
   11167              :             {
   11168       146475 :               second_vec_index = vec_index;
   11169       146475 :               mask_element += const_nunits;
   11170              :             }
   11171              :           else
   11172              :             {
   11173         6269 :               if (dump_p)
   11174          280 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   11175              :                                  "permutation requires at "
   11176              :                                  "least three vectors %G",
   11177              :                                  stmt_info->stmt);
   11178         6269 :               gcc_assert (analyze_only);
   11179              :               return false;
   11180              :             }
   11181              : 
   11182       374894 :           gcc_assert (mask_element < 2 * const_nunits);
   11183              :         }
   11184              : 
   11185       591104 :       if (mask_element != index)
   11186       380343 :         noop_p = false;
   11187       591104 :       mask[index++] = mask_element;
   11188              : 
   11189       591104 :       if (index == count)
   11190              :         {
   11191       162369 :           if (!noop_p)
   11192              :             {
   11193       132287 :               indices.new_vector (mask, second_vec_index == -1 ? 1 : 2, nunits);
   11194       132287 :               if (!can_vec_perm_const_p (mode, mode, indices))
   11195              :                 {
   11196         5106 :                   if (dump_p)
   11197              :                     {
   11198           79 :                       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   11199              :                                        "unsupported vect permute { ");
   11200          673 :                       for (i = 0; i < count; ++i)
   11201              :                         {
   11202          594 :                           dump_dec (MSG_MISSED_OPTIMIZATION, mask[i]);
   11203          594 :                           dump_printf (MSG_MISSED_OPTIMIZATION, " ");
   11204              :                         }
   11205           79 :                       dump_printf (MSG_MISSED_OPTIMIZATION, "}\n");
   11206              :                     }
   11207         5106 :                   gcc_assert (analyze_only);
   11208              :                   return false;
   11209              :                 }
   11210              : 
   11211       127181 :               tree mask_vec = NULL_TREE;
   11212       127181 :               if (!analyze_only)
   11213        20904 :                 mask_vec = vect_gen_perm_mask_checked (vectype, indices);
   11214              : 
   11215       127181 :               if (second_vec_index == -1)
   11216        36553 :                 second_vec_index = first_vec_index;
   11217              : 
   11218       257236 :               for (unsigned int ri = 0; ri < nvectors_per_build; ++ri)
   11219              :                 {
   11220       130055 :                   ++*n_perms;
   11221       130055 :                   if (analyze_only)
   11222       108868 :                     continue;
   11223              :                   /* Generate the permute statement if necessary.  */
   11224        21187 :                   tree first_vec = dr_chain[first_vec_index + ri];
   11225        21187 :                   tree second_vec = dr_chain[second_vec_index + ri];
   11226        21187 :                   gassign *stmt = as_a<gassign *> (stmt_info->stmt);
   11227        21187 :                   tree perm_dest
   11228        21187 :                     = vect_create_destination_var (gimple_assign_lhs (stmt),
   11229              :                                                    vectype);
   11230        21187 :                   perm_dest = make_ssa_name (perm_dest);
   11231        21187 :                   gimple *perm_stmt
   11232        21187 :                     = gimple_build_assign (perm_dest, VEC_PERM_EXPR, first_vec,
   11233              :                                            second_vec, mask_vec);
   11234        21187 :                   vect_finish_stmt_generation (vinfo, stmt_info, perm_stmt,
   11235              :                                                gsi);
   11236        21187 :                   if (dce_chain)
   11237              :                     {
   11238        20264 :                       bitmap_set_bit (used_defs, first_vec_index + ri);
   11239        20264 :                       bitmap_set_bit (used_defs, second_vec_index + ri);
   11240              :                     }
   11241              : 
   11242              :                   /* Store the vector statement in NODE.  */
   11243        21187 :                   SLP_TREE_VEC_DEFS (node)[vect_stmts_counter++] = perm_dest;
   11244              :                 }
   11245              :             }
   11246        30082 :           else if (!analyze_only)
   11247              :             {
   11248         2872 :               for (unsigned int ri = 0; ri < nvectors_per_build; ++ri)
   11249              :                 {
   11250         1436 :                   tree first_vec = dr_chain[first_vec_index + ri];
   11251              :                   /* If mask was NULL_TREE generate the requested
   11252              :                      identity transform.  */
   11253         1436 :                   if (dce_chain)
   11254         1429 :                     bitmap_set_bit (used_defs, first_vec_index + ri);
   11255              : 
   11256              :                   /* Store the vector statement in NODE.  */
   11257         1436 :                   SLP_TREE_VEC_DEFS (node)[vect_stmts_counter++] = first_vec;
   11258              :                 }
   11259              :             }
   11260              : 
   11261              :           index = 0;
   11262              :           first_vec_index = -1;
   11263              :           second_vec_index = -1;
   11264              :           noop_p = true;
   11265              :         }
   11266              :     }
   11267              : 
   11268       126539 :   if (n_loads)
   11269              :     {
   11270        88779 :       if (repeating_p)
   11271        10731 :         *n_loads = nstmts;
   11272              :       else
   11273              :         {
   11274              :           /* Enforced above when !repeating_p.  */
   11275        78048 :           unsigned int const_nunits = nunits.to_constant ();
   11276        78048 :           *n_loads = 0;
   11277        78048 :           bool load_seen = false;
   11278      1051973 :           for (unsigned i = 0; i < in_nlanes; ++i)
   11279              :             {
   11280       973925 :               if (i % const_nunits == 0)
   11281              :                 {
   11282       416120 :                   if (load_seen)
   11283       123900 :                     *n_loads += 1;
   11284              :                   load_seen = false;
   11285              :                 }
   11286       973925 :               if (bitmap_bit_p (used_in_lanes, i))
   11287       270362 :                 load_seen = true;
   11288              :             }
   11289        78048 :           if (load_seen)
   11290        51748 :             *n_loads += 1;
   11291              :         }
   11292              :     }
   11293              : 
   11294       126539 :   if (dce_chain)
   11295       229345 :     for (unsigned i = 0; i < dr_chain.length (); ++i)
   11296        74149 :       if (!bitmap_bit_p (used_defs, i))
   11297              :         {
   11298        40891 :           tree def = dr_chain[i];
   11299        41301 :           do
   11300              :             {
   11301        41301 :               gimple *stmt = SSA_NAME_DEF_STMT (def);
   11302        41301 :               if (is_gimple_assign (stmt)
   11303        41301 :                   && (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR
   11304        41301 :                       || gimple_assign_rhs_code (stmt) == CONSTRUCTOR))
   11305         4979 :                 def = single_ssa_tree_operand (stmt, SSA_OP_USE);
   11306              :               else
   11307              :                 def = NULL;
   11308        41301 :               gimple_stmt_iterator rgsi = gsi_for_stmt (stmt);
   11309        41301 :               gsi_remove (&rgsi, true);
   11310        41301 :               release_defs (stmt);
   11311              :             }
   11312        41301 :           while (def);
   11313              :         }
   11314              : 
   11315              :   return true;
   11316       137914 : }
   11317              : 
   11318              : /* Generate vector permute statements from a list of loads in DR_CHAIN.
   11319              :    If ANALYZE_ONLY is TRUE, only check that it is possible to create valid
   11320              :    permute statements for the SLP node NODE.  Store the number of vector
   11321              :    permute instructions in *N_PERMS and the number of vector load
   11322              :    instructions in *N_LOADS.  If DCE_CHAIN is true, remove all definitions
   11323              :    that were not needed.  */
   11324              : 
   11325              : bool
   11326        98580 : vect_transform_slp_perm_load (vec_info *vinfo,
   11327              :                               slp_tree node, const vec<tree> &dr_chain,
   11328              :                               gimple_stmt_iterator *gsi, poly_uint64 vf,
   11329              :                               bool analyze_only, unsigned *n_perms,
   11330              :                               unsigned int *n_loads, bool dce_chain)
   11331              : {
   11332        98580 :   return vect_transform_slp_perm_load_1 (vinfo, node,
   11333        98580 :                                          SLP_TREE_LOAD_PERMUTATION (node),
   11334              :                                          dr_chain, gsi, vf, analyze_only,
   11335              :                                          dump_enabled_p (), n_perms, n_loads,
   11336        98580 :                                          dce_chain);
   11337              : }
   11338              : 
   11339              : /* Produce the next vector result for SLP permutation NODE by adding a vector
   11340              :    statement at GSI.  If MASK_VEC is nonnull, add:
   11341              : 
   11342              :       <new SSA name> = VEC_PERM_EXPR <FIRST_DEF, SECOND_DEF, MASK_VEC>
   11343              : 
   11344              :    otherwise add:
   11345              : 
   11346              :       <new SSA name> = VEC_PERM_EXPR <FIRST_DEF, SECOND_DEF,
   11347              :                                       { N, N+1, N+2, ... }>
   11348              : 
   11349              :    where N == IDENTITY_OFFSET which is either zero or equal to the
   11350              :    number of elements of the result.  */
   11351              : 
   11352              : static void
   11353        31527 : vect_add_slp_permutation (vec_info *vinfo, gimple_stmt_iterator *gsi,
   11354              :                           slp_tree node, tree first_def, tree second_def,
   11355              :                           tree mask_vec, poly_uint64 identity_offset)
   11356              : {
   11357        31527 :   tree vectype = SLP_TREE_VECTYPE (node);
   11358              : 
   11359              :   /* ???  We SLP match existing vector element extracts but
   11360              :      allow punning which we need to re-instantiate at uses
   11361              :      but have no good way of explicitly representing.  */
   11362        31527 :   if (operand_equal_p (TYPE_SIZE (TREE_TYPE (first_def)), TYPE_SIZE (vectype))
   11363        31527 :       && !types_compatible_p (TREE_TYPE (first_def), vectype))
   11364              :     {
   11365           20 :       gassign *conv_stmt
   11366           20 :         = gimple_build_assign (make_ssa_name (vectype),
   11367              :                                build1 (VIEW_CONVERT_EXPR, vectype, first_def));
   11368           20 :       vect_finish_stmt_generation (vinfo, NULL, conv_stmt, gsi);
   11369           20 :       first_def = gimple_assign_lhs (conv_stmt);
   11370              :     }
   11371        31527 :   gassign *perm_stmt;
   11372        31527 :   if (mask_vec)
   11373              :     {
   11374        28125 :       if (operand_equal_p (TYPE_SIZE (TREE_TYPE (first_def)),
   11375        28125 :                            TYPE_SIZE (vectype))
   11376        28125 :           && !types_compatible_p (TREE_TYPE (second_def), vectype))
   11377              :         {
   11378            8 :           gassign *conv_stmt
   11379            8 :             = gimple_build_assign (make_ssa_name (vectype),
   11380              :                                    build1 (VIEW_CONVERT_EXPR,
   11381              :                                            vectype, second_def));
   11382            8 :           vect_finish_stmt_generation (vinfo, NULL, conv_stmt, gsi);
   11383            8 :           second_def = gimple_assign_lhs (conv_stmt);
   11384              :         }
   11385        28125 :       tree perm_dest = make_ssa_name (vectype);
   11386        28125 :       perm_stmt = gimple_build_assign (perm_dest, VEC_PERM_EXPR,
   11387              :                                        first_def, second_def,
   11388              :                                        mask_vec);
   11389              :     }
   11390              :   else
   11391              :     {
   11392         3402 :       auto def_nunits = TYPE_VECTOR_SUBPARTS (TREE_TYPE (first_def));
   11393         3402 :       unsigned HOST_WIDE_INT vecno;
   11394         3402 :       poly_uint64 eltno;
   11395         3402 :       if (!can_div_trunc_p (poly_uint64 (identity_offset), def_nunits,
   11396              :                             &vecno, &eltno))
   11397              :         gcc_unreachable ();
   11398         3402 :       tree def = vecno & 1 ? second_def : first_def;
   11399         3402 :       if (!types_compatible_p (TREE_TYPE (def), vectype))
   11400              :         {
   11401              :           /* For identity permutes we still need to handle the case
   11402              :              of offsetted extracts or concats.  */
   11403          324 :           tree perm_dest = make_ssa_name (vectype);
   11404          324 :           unsigned HOST_WIDE_INT c;
   11405          324 :           if (known_le (TYPE_VECTOR_SUBPARTS (vectype), def_nunits))
   11406              :             {
   11407          320 :               unsigned HOST_WIDE_INT elsz
   11408          320 :                 = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (def))));
   11409          640 :               tree lowpart = build3 (BIT_FIELD_REF, vectype, def,
   11410          320 :                                      TYPE_SIZE (vectype),
   11411          320 :                                      bitsize_int (eltno * elsz));
   11412          320 :               perm_stmt = gimple_build_assign (perm_dest, lowpart);
   11413              :             }
   11414            4 :           else if (constant_multiple_p (TYPE_VECTOR_SUBPARTS (vectype),
   11415            4 :                                         def_nunits, &c) && c == 2)
   11416              :             {
   11417            4 :               gcc_assert (known_eq (identity_offset, 0U));
   11418            4 :               tree ctor = build_constructor_va (vectype, 2,
   11419              :                                                 NULL_TREE, first_def,
   11420              :                                                 NULL_TREE, second_def);
   11421            4 :               perm_stmt = gimple_build_assign (perm_dest, ctor);
   11422              :             }
   11423              :           else
   11424            0 :             gcc_unreachable ();
   11425              :         }
   11426              :       else
   11427              :         {
   11428         3078 :           gcc_assert (known_eq (eltno, 0U));
   11429         3078 :           node->push_vec_def (def);
   11430         3078 :           return;
   11431              :         }
   11432              :     }
   11433        28449 :   vect_finish_stmt_generation (vinfo, NULL, perm_stmt, gsi);
   11434              :   /* Store the vector statement in NODE.  */
   11435        28449 :   node->push_vec_def (perm_stmt);
   11436              : }
   11437              : 
   11438              : /* Subroutine of vectorizable_slp_permutation.  Check whether the target
   11439              :    can perform permutation PERM on the (1 or 2) input nodes in CHILDREN.
   11440              :    If GSI is nonnull, emit the permutation there.
   11441              : 
   11442              :    When GSI is null, the only purpose of NODE is to give properties
   11443              :    of the result, such as the vector type and number of SLP lanes.
   11444              :    The node does not need to be a VEC_PERM_EXPR.
   11445              : 
   11446              :    If the target supports the operation, return the number of individual
   11447              :    VEC_PERM_EXPRs needed, otherwise return -1.  Print information to the
   11448              :    dump file if DUMP_P is true.  */
   11449              : 
   11450              : static int
   11451       454504 : vectorizable_slp_permutation_1 (vec_info *vinfo, gimple_stmt_iterator *gsi,
   11452              :                                 slp_tree node, lane_permutation_t &perm,
   11453              :                                 vec<slp_tree> &children, bool dump_p)
   11454              : {
   11455       454504 :   tree vectype = SLP_TREE_VECTYPE (node);
   11456              : 
   11457              :   /* ???  We currently only support all same vector input types
   11458              :      while the SLP IL should really do a concat + select and thus accept
   11459              :      arbitrary mismatches.  */
   11460       454504 :   slp_tree child;
   11461       454504 :   unsigned i;
   11462       454504 :   poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
   11463       454504 :   bool repeating_p = multiple_p (nunits, SLP_TREE_LANES (node));
   11464              :   /* True if we're permuting a single input of 2N vectors down
   11465              :      to N vectors.  This case doesn't generalize beyond 2 since
   11466              :      VEC_PERM_EXPR only takes 2 inputs.  */
   11467       454504 :   bool pack_p = false;
   11468              :   /* If we're permuting inputs of N vectors each into X*N outputs,
   11469              :      this is the value of X, otherwise it is 1.  */
   11470       454504 :   unsigned int unpack_factor = 1;
   11471       454504 :   tree op_vectype = NULL_TREE;
   11472       456068 :   FOR_EACH_VEC_ELT (children, i, child)
   11473       455990 :     if (SLP_TREE_VECTYPE (child))
   11474              :       {
   11475              :         op_vectype = SLP_TREE_VECTYPE (child);
   11476              :         break;
   11477              :       }
   11478       454504 :   if (!op_vectype)
   11479           78 :     op_vectype = vectype;
   11480       954060 :   FOR_EACH_VEC_ELT (children, i, child)
   11481              :     {
   11482       499556 :       if ((SLP_TREE_DEF_TYPE (child) != vect_internal_def
   11483        18953 :            && !vect_maybe_update_slp_op_vectype (child, op_vectype))
   11484       499556 :           || !types_compatible_p (SLP_TREE_VECTYPE (child), op_vectype)
   11485       999112 :           || !types_compatible_p (TREE_TYPE (vectype), TREE_TYPE (op_vectype)))
   11486              :         {
   11487            0 :           if (dump_p)
   11488            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   11489              :                              "Unsupported vector types in lane permutation\n");
   11490            0 :           return -1;
   11491              :         }
   11492       499556 :       auto op_nunits = TYPE_VECTOR_SUBPARTS (op_vectype);
   11493       499556 :       unsigned int this_unpack_factor;
   11494              :       /* Detect permutations of external, pre-existing vectors.  The external
   11495              :          node's SLP_TREE_LANES stores the total number of units in the vector,
   11496              :          or zero if the vector has variable length.
   11497              : 
   11498              :          We are expected to keep the original VEC_PERM_EXPR for such cases.
   11499              :          There is no repetition to model.  */
   11500       499556 :       if (SLP_TREE_DEF_TYPE (child) == vect_external_def
   11501       499556 :           && SLP_TREE_SCALAR_OPS (child).is_empty ())
   11502              :         repeating_p = false;
   11503              :       /* Check whether the input has twice as many lanes per vector.  */
   11504       483171 :       else if (children.length () == 1
   11505       483171 :                && known_eq (SLP_TREE_LANES (child) * nunits,
   11506              :                             SLP_TREE_LANES (node) * op_nunits * 2))
   11507              :         pack_p = true;
   11508              :       /* Check whether the output has N times as many lanes per vector.  */
   11509       499556 :       else if (constant_multiple_p (SLP_TREE_LANES (node) * op_nunits,
   11510       439354 :                                     SLP_TREE_LANES (child) * nunits,
   11511              :                                     &this_unpack_factor)
   11512       404509 :                && (i == 0 || unpack_factor == this_unpack_factor))
   11513              :         unpack_factor = this_unpack_factor;
   11514              :       else
   11515              :         repeating_p = false;
   11516              :     }
   11517              : 
   11518       909008 :   gcc_assert (perm.length () == SLP_TREE_LANES (node));
   11519              : 
   11520              :   /* Load-lanes permute.  This permute only acts as a forwarder to
   11521              :      select the correct vector def of the load-lanes load which
   11522              :      has the permuted vectors in its vector defs like
   11523              :      { v0, w0, r0, v1, w1, r1 ... } for a ld3.  All costs are
   11524              :      accounted for in the costing for the actual load so we
   11525              :      return zero here.  */
   11526       454504 :   if (node->ldst_lanes)
   11527              :     {
   11528            0 :       gcc_assert (children.length () == 1);
   11529            0 :       if (!gsi)
   11530              :         /* This is a trivial op always supported.  */
   11531              :         return 0;
   11532            0 :       slp_tree child = children[0];
   11533            0 :       unsigned vec_idx = (SLP_TREE_LANE_PERMUTATION (node)[0].second
   11534            0 :                           / SLP_TREE_LANES (node));
   11535            0 :       unsigned vec_num = SLP_TREE_LANES (child) / SLP_TREE_LANES (node);
   11536            0 :       unsigned nvectors = vect_get_num_copies (vinfo, node);
   11537            0 :       for (unsigned i = 0; i < nvectors; ++i)
   11538              :         {
   11539            0 :           tree def = SLP_TREE_VEC_DEFS (child)[i * vec_num  + vec_idx];
   11540            0 :           node->push_vec_def (def);
   11541              :         }
   11542              :       return 0;
   11543              :     }
   11544              : 
   11545              :   /* Set REPEATING_P to true if the permutations are cyclical wrt UNPACK_FACTOR
   11546              :      and if we can generate the vectors in a vector-length agnostic way.
   11547              :      This requires UNPACK_STEP == NUNITS / UNPACK_FACTOR to be known at
   11548              :      compile time.
   11549              : 
   11550              :      The significance of UNPACK_STEP is that, when PACK_P is false,
   11551              :      output vector I operates on a window of UNPACK_STEP elements from each
   11552              :      input, starting at lane UNPACK_STEP * (I % UNPACK_FACTOR).  For example,
   11553              :      when UNPACK_FACTOR is 2, the first output vector operates on lanes
   11554              :      [0, NUNITS / 2 - 1] of each input vector and the second output vector
   11555              :      operates on lanes [NUNITS / 2, NUNITS - 1] of each input vector.
   11556              : 
   11557              :      When REPEATING_P is true, NOUTPUTS holds the total number of outputs
   11558              :      that we actually need to generate.  */
   11559       454504 :   uint64_t noutputs = 0;
   11560       454504 :   poly_uint64 unpack_step = 0;
   11561       454504 :   loop_vec_info linfo = dyn_cast <loop_vec_info> (vinfo);
   11562       182935 :   if (!linfo
   11563       493546 :       || !multiple_p (nunits, unpack_factor, &unpack_step)
   11564       181995 :       || !constant_multiple_p (LOOP_VINFO_VECT_FACTOR (linfo)
   11565       181995 :                                * SLP_TREE_LANES (node), nunits, &noutputs))
   11566              :     repeating_p = false;
   11567              : 
   11568              :   /* We can handle the conditions described for REPEATING_P above for
   11569              :      both variable- and constant-length vectors.  The fallback requires
   11570              :      us to generate every element of every permute vector explicitly,
   11571              :      which is only possible for constant-length permute vectors.
   11572              : 
   11573              :      Set:
   11574              : 
   11575              :      - NPATTERNS and NELTS_PER_PATTERN to the encoding of the permute
   11576              :        mask vectors that we want to build.
   11577              : 
   11578              :      - NCOPIES to the number of copies of PERM that we need in order
   11579              :        to build the necessary permute mask vectors.  */
   11580       181995 :   uint64_t npatterns;
   11581       181995 :   unsigned nelts_per_pattern;
   11582       181995 :   uint64_t ncopies;
   11583       181995 :   if (repeating_p)
   11584              :     {
   11585              :       /* We need permute mask vectors that have the form:
   11586              : 
   11587              :            { X1, ..., Xn, X1 + n, ..., Xn + n, X1 + 2n, ..., Xn + 2n, ... }
   11588              : 
   11589              :          In other words, the original n-element permute in PERM is
   11590              :          "unrolled" to fill a full vector.  The stepped vector encoding
   11591              :          that we use for permutes requires 3n elements.  */
   11592       142953 :       npatterns = SLP_TREE_LANES (node);
   11593       142953 :       nelts_per_pattern = ncopies = 3;
   11594              :     }
   11595              :   else
   11596              :     {
   11597              :       /* Calculate every element of every permute mask vector explicitly,
   11598              :          instead of relying on the pattern described above.  */
   11599       311551 :       if (!nunits.is_constant (&npatterns)
   11600       311551 :           || !TYPE_VECTOR_SUBPARTS (op_vectype).is_constant ())
   11601              :         {
   11602              :           if (dump_p)
   11603              :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   11604              :                              "unsupported permutation %p on variable-length"
   11605              :                              " vectors\n", (void *) node);
   11606              :           return -1;
   11607              :         }
   11608       311551 :       nelts_per_pattern = ncopies = 1;
   11609       311551 :       if (linfo && !LOOP_VINFO_VECT_FACTOR (linfo).is_constant (&ncopies))
   11610              :         {
   11611              :           if (dump_p)
   11612              :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   11613              :                              "unsupported permutation %p for variable VF\n",
   11614              :                              (void *) node);
   11615              :           return -1;
   11616              :         }
   11617              :       pack_p = false;
   11618              :       unpack_factor = 1;
   11619              :     }
   11620       454504 :   unsigned olanes = unpack_factor * ncopies * SLP_TREE_LANES (node);
   11621       454504 :   gcc_assert (repeating_p || multiple_p (olanes, nunits));
   11622              : 
   11623              :   /* Compute the { { SLP operand, vector index}, lane } permutation sequence
   11624              :      from the { SLP operand, scalar lane } permutation as recorded in the
   11625              :      SLP node as intermediate step.  This part should already work
   11626              :      with SLP children with arbitrary number of lanes.  */
   11627       454504 :   auto_vec<std::pair<std::pair<unsigned, unsigned>, poly_uint64>> vperm;
   11628       454504 :   auto_vec<poly_uint64> active_lane;
   11629       454504 :   vperm.create (olanes);
   11630       454504 :   active_lane.safe_grow_cleared (children.length (), true);
   11631       917287 :   for (unsigned int ui = 0; ui < unpack_factor; ++ui)
   11632              :     {
   11633      1957746 :       for (unsigned j = 0; j < children.length (); ++j)
   11634       516090 :         active_lane[j] = ui * unpack_step;
   11635      1325969 :       for (unsigned i = 0; i < ncopies; ++i)
   11636              :         {
   11637      5437966 :           for (unsigned pi = 0; pi < perm.length (); ++pi)
   11638              :             {
   11639      1855797 :               std::pair<unsigned, unsigned> p = perm[pi];
   11640      1855797 :               tree vtype = SLP_TREE_VECTYPE (children[p.first]);
   11641      1855797 :               if (repeating_p)
   11642       834045 :                 vperm.quick_push ({{p.first, 0},
   11643       834045 :                                    p.second + active_lane[p.first]});
   11644              :               else
   11645              :                 {
   11646              :                   /* We checked above that the vectors are constant-length.  */
   11647      1021752 :                   unsigned vnunits = TYPE_VECTOR_SUBPARTS (vtype)
   11648      1021752 :                     .to_constant ();
   11649      1021752 :                   unsigned lane = active_lane[p.first].to_constant ();
   11650      1021752 :                   unsigned vi = (lane + p.second) / vnunits;
   11651      1021752 :                   unsigned vl = (lane + p.second) % vnunits;
   11652      1021752 :                   vperm.quick_push ({{p.first, vi}, vl});
   11653              :                 }
   11654              :             }
   11655              :           /* Advance to the next group.  */
   11656      1844107 :           for (unsigned j = 0; j < children.length (); ++j)
   11657       980921 :             active_lane[j] += SLP_TREE_LANES (children[j]);
   11658              :         }
   11659              :     }
   11660              : 
   11661       454504 :   if (dump_p)
   11662              :     {
   11663         8963 :       dump_printf_loc (MSG_NOTE, vect_location,
   11664              :                        "vectorizing permutation %p", (void *)node);
   11665        32466 :       for (unsigned i = 0; i < perm.length (); ++i)
   11666        23503 :         dump_printf (MSG_NOTE, " op%u[%u]", perm[i].first, perm[i].second);
   11667         8963 :       if (repeating_p)
   11668         7566 :         dump_printf (MSG_NOTE, " (repeat %d)", SLP_TREE_LANES (node));
   11669         8963 :       dump_printf (MSG_NOTE, "\n");
   11670         8963 :       dump_printf_loc (MSG_NOTE, vect_location, "as");
   11671        90454 :       for (unsigned i = 0; i < vperm.length (); ++i)
   11672              :         {
   11673        81491 :           if (i != 0
   11674        81491 :               && (repeating_p
   11675        55311 :                   ? multiple_p (i, npatterns)
   11676        60629 :                   : multiple_p (i, TYPE_VECTOR_SUBPARTS (vectype))))
   11677        24361 :             dump_printf (MSG_NOTE, ",");
   11678        81491 :           dump_printf (MSG_NOTE, " vops%u[%u][",
   11679        81491 :                        vperm[i].first.first, vperm[i].first.second);
   11680        81491 :           dump_dec (MSG_NOTE, vperm[i].second);
   11681        81491 :           dump_printf (MSG_NOTE, "]");
   11682              :         }
   11683         8963 :       dump_printf (MSG_NOTE, "\n");
   11684              :     }
   11685              : 
   11686              :   /* We can only handle two-vector permutes, everything else should
   11687              :      be lowered on the SLP level.  The following is closely inspired
   11688              :      by vect_transform_slp_perm_load and is supposed to eventually
   11689              :      replace it.
   11690              :      ???   As intermediate step do code-gen in the SLP tree representation
   11691              :      somehow?  */
   11692       454504 :   std::pair<unsigned, unsigned> first_vec = std::make_pair (-1U, -1U);
   11693       454504 :   std::pair<unsigned, unsigned> second_vec = std::make_pair (-1U, -1U);
   11694       454504 :   unsigned int index = 0;
   11695       454504 :   poly_uint64 mask_element;
   11696       454504 :   vec_perm_builder mask;
   11697       454504 :   mask.new_vector (nunits, npatterns, nelts_per_pattern);
   11698       454504 :   unsigned int count = mask.encoded_nelts ();
   11699       454504 :   mask.quick_grow (count);
   11700       454504 :   vec_perm_indices indices;
   11701       454504 :   unsigned nperms = 0;
   11702              :   /* When REPEATING_P is true, we only have UNPACK_FACTOR unique permute
   11703              :      vectors to check during analysis, but we need to generate NOUTPUTS
   11704              :      vectors during transformation.  */
   11705       454504 :   unsigned total_nelts = olanes;
   11706       454504 :   unsigned process_nelts = olanes;
   11707       454504 :   if (repeating_p)
   11708              :     {
   11709       142953 :       total_nelts = (total_nelts / unpack_factor) * noutputs;
   11710       142953 :       if (gsi)
   11711         9815 :         process_nelts = total_nelts;
   11712              :     }
   11713       454504 :   unsigned last_ei = (total_nelts - 1) % process_nelts;
   11714      2313027 :   for (unsigned i = 0; i < process_nelts; ++i)
   11715              :     {
   11716              :       /* VI is the input vector index when generating code for REPEATING_P.  */
   11717      1869139 :       unsigned vi = i / olanes * (pack_p ? 2 : 1);
   11718      1869139 :       unsigned ei = i % olanes;
   11719      1869139 :       mask_element = vperm[ei].second;
   11720      1869139 :       if (pack_p)
   11721              :         {
   11722              :           /* In this case, we have N outputs and the single child provides 2N
   11723              :              inputs.  Output X permutes inputs 2X and 2X+1.
   11724              : 
   11725              :              The mask indices are taken directly from the SLP permutation node.
   11726              :              Index X selects from the first vector if (X / NUNITS) % 2 == 0;
   11727              :              X selects from the second vector otherwise.  These conditions
   11728              :              are only known at compile time for constant-length vectors.  */
   11729              :           first_vec = std::make_pair (0, 0);
   11730              :           second_vec = std::make_pair (0, 1);
   11731              :         }
   11732      1699783 :       else if (first_vec.first == -1U
   11733      1699783 :                || first_vec == vperm[ei].first)
   11734      1505600 :         first_vec = vperm[ei].first;
   11735       194183 :       else if (second_vec.first == -1U
   11736       194183 :                || second_vec == vperm[ei].first)
   11737              :         {
   11738       193796 :           second_vec = vperm[ei].first;
   11739       193796 :           mask_element += nunits;
   11740              :         }
   11741              :       else
   11742              :         {
   11743          387 :           if (dump_p)
   11744            7 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   11745              :                              "permutation requires at "
   11746              :                              "least three vectors\n");
   11747          387 :           gcc_assert (!gsi);
   11748              :           return -1;
   11749              :         }
   11750              : 
   11751      1868752 :       mask[index++] = mask_element;
   11752              : 
   11753      1868752 :       if (index == count)
   11754              :         {
   11755       597579 :           indices.new_vector (mask, second_vec.first == -1U ? 1 : 2,
   11756              :                               TYPE_VECTOR_SUBPARTS (op_vectype));
   11757       597579 :           bool identity_p = (indices.series_p (0, 1, mask[0], 1)
   11758       932815 :                              && constant_multiple_p (mask[0], nunits));
   11759       597579 :           machine_mode vmode = TYPE_MODE (vectype);
   11760       597579 :           machine_mode op_vmode = TYPE_MODE (op_vectype);
   11761       597579 :           unsigned HOST_WIDE_INT c;
   11762       597579 :           if ((!identity_p
   11763       549856 :                && !can_vec_perm_const_p (vmode, op_vmode, indices))
   11764       597579 :               || (identity_p
   11765        47723 :                   && !known_le (nunits,
   11766              :                                 TYPE_VECTOR_SUBPARTS (op_vectype))
   11767        10237 :                   && (!constant_multiple_p (nunits,
   11768            8 :                                             TYPE_VECTOR_SUBPARTS (op_vectype),
   11769            8 :                                             &c) || c != 2)))
   11770              :             {
   11771        10229 :               if (dump_p)
   11772              :                 {
   11773          154 :                   dump_printf_loc (MSG_MISSED_OPTIMIZATION,
   11774              :                                    vect_location,
   11775              :                                    "unsupported vect permute { ");
   11776         1596 :                   for (i = 0; i < count; ++i)
   11777              :                     {
   11778         1442 :                       dump_dec (MSG_MISSED_OPTIMIZATION, mask[i]);
   11779         1442 :                       dump_printf (MSG_MISSED_OPTIMIZATION, " ");
   11780              :                     }
   11781          154 :                   dump_printf (MSG_MISSED_OPTIMIZATION, "}\n");
   11782              :                 }
   11783        10229 :               gcc_assert (!gsi);
   11784        10616 :               return -1;
   11785              :             }
   11786              : 
   11787       587350 :           if (!identity_p)
   11788       539627 :             nperms += CEIL (total_nelts, process_nelts) - (ei > last_ei);
   11789       587350 :           if (gsi)
   11790              :             {
   11791        31527 :               if (second_vec.first == -1U)
   11792         7271 :                 second_vec = first_vec;
   11793              : 
   11794        31527 :               slp_tree
   11795        31527 :                 first_node = children[first_vec.first],
   11796        31527 :                 second_node = children[second_vec.first];
   11797              : 
   11798        31527 :               tree mask_vec = NULL_TREE;
   11799        31527 :               if (!identity_p)
   11800        28125 :                 mask_vec = vect_gen_perm_mask_checked (vectype, indices);
   11801              : 
   11802        31527 :               tree first_def
   11803        31527 :                 = vect_get_slp_vect_def (first_node, first_vec.second + vi);
   11804        31527 :               tree second_def
   11805        31527 :                 = vect_get_slp_vect_def (second_node, second_vec.second + vi);
   11806        31527 :               vect_add_slp_permutation (vinfo, gsi, node, first_def,
   11807        31527 :                                         second_def, mask_vec, mask[0]);
   11808              :             }
   11809              : 
   11810              :           index = 0;
   11811              :           first_vec = std::make_pair (-1U, -1U);
   11812              :           second_vec = std::make_pair (-1U, -1U);
   11813              :         }
   11814              :     }
   11815              : 
   11816       443888 :   return nperms;
   11817       454504 : }
   11818              : 
   11819              : /* Vectorize the SLP permutations in NODE as specified
   11820              :    in SLP_TREE_LANE_PERMUTATION which is a vector of pairs of SLP
   11821              :    child number and lane number.
   11822              :    Interleaving of two two-lane two-child SLP subtrees (not supported):
   11823              :      [ { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } ]
   11824              :    A blend of two four-lane two-child SLP subtrees:
   11825              :      [ { 0, 0 }, { 1, 1 }, { 0, 2 }, { 1, 3 } ]
   11826              :    Highpart of a four-lane one-child SLP subtree (not supported):
   11827              :      [ { 0, 2 }, { 0, 3 } ]
   11828              :    Where currently only a subset is supported by code generating below.  */
   11829              : 
   11830              : bool
   11831        99041 : vectorizable_slp_permutation (vec_info *vinfo, gimple_stmt_iterator *gsi,
   11832              :                               slp_tree node, stmt_vector_for_cost *cost_vec)
   11833              : {
   11834        99041 :   tree vectype = SLP_TREE_VECTYPE (node);
   11835        99041 :   lane_permutation_t &perm = SLP_TREE_LANE_PERMUTATION (node);
   11836        99041 :   int nperms = vectorizable_slp_permutation_1 (vinfo, gsi, node, perm,
   11837        99041 :                                                SLP_TREE_CHILDREN (node),
   11838              :                                                dump_enabled_p ());
   11839        99041 :   if (nperms < 0)
   11840              :     return false;
   11841              : 
   11842        97418 :   if (!gsi && nperms != 0)
   11843        74417 :     record_stmt_cost (cost_vec, nperms, vec_perm, node, vectype, 0, vect_body);
   11844              : 
   11845              :   return true;
   11846              : }
   11847              : 
   11848              : /* Vectorize SLP NODE.  */
   11849              : 
   11850              : static void
   11851      1494661 : vect_schedule_slp_node (vec_info *vinfo,
   11852              :                         slp_tree node, slp_instance instance)
   11853              : {
   11854      1494661 :   gimple_stmt_iterator si;
   11855      1494661 :   int i;
   11856      1494661 :   slp_tree child;
   11857              : 
   11858              :   /* Vectorize externals and constants.  */
   11859      1494661 :   if (SLP_TREE_DEF_TYPE (node) == vect_constant_def
   11860      1494661 :       || SLP_TREE_DEF_TYPE (node) == vect_external_def)
   11861              :     {
   11862              :       /* ???  vectorizable_shift can end up using a scalar operand which is
   11863              :          currently denoted as !SLP_TREE_VECTYPE.  No need to vectorize the
   11864              :          node in this case.  */
   11865       506615 :       if (!SLP_TREE_VECTYPE (node))
   11866       506615 :         return;
   11867              : 
   11868              :       /* There are two reasons vector defs might already exist.  The first
   11869              :          is that we are vectorizing an existing vector def.  The second is
   11870              :          when performing BB vectorization shared constant/external nodes
   11871              :          are not split apart during partitioning so during the code-gen
   11872              :          DFS walk we can end up visiting them twice.  */
   11873       499444 :       if (! SLP_TREE_VEC_DEFS (node).exists ())
   11874       498514 :         vect_create_constant_vectors (vinfo, node);
   11875       499444 :       return;
   11876              :     }
   11877              : 
   11878       988046 :   stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node);
   11879              : 
   11880       988046 :   gcc_assert (SLP_TREE_VEC_DEFS (node).is_empty ());
   11881       988046 :   if (SLP_TREE_VECTYPE (node))
   11882       988040 :     SLP_TREE_VEC_DEFS (node).create (vect_get_num_copies (vinfo, node));
   11883              : 
   11884       988046 :   if (!SLP_TREE_PERMUTE_P (node) && STMT_VINFO_DATA_REF (stmt_info))
   11885              :     {
   11886              :       /* Vectorized loads go before the first scalar load to make it
   11887              :          ready early, vectorized stores go before the last scalar
   11888              :          stmt which is where all uses are ready.  */
   11889       722278 :       stmt_vec_info last_stmt_info = NULL;
   11890       722278 :       if (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)))
   11891       169450 :         last_stmt_info = vect_find_first_scalar_stmt_in_slp (node);
   11892              :       else /* DR_IS_WRITE */
   11893       552828 :         last_stmt_info = vect_find_last_scalar_stmt_in_slp (node);
   11894       722278 :       si = gsi_for_stmt (last_stmt_info->stmt);
   11895       722278 :     }
   11896       265768 :   else if (!SLP_TREE_PERMUTE_P (node)
   11897       249102 :            && (SLP_TREE_TYPE (node) == cycle_phi_info_type
   11898              :                || SLP_TREE_TYPE (node) == induc_vec_info_type
   11899              :                || SLP_TREE_TYPE (node) == phi_info_type))
   11900              :     {
   11901              :       /* For PHI node vectorization we do not use the insertion iterator.  */
   11902        54684 :       si = gsi_none ();
   11903              :     }
   11904              :   else
   11905              :     {
   11906              :       /* Emit other stmts after the children vectorized defs which is
   11907              :          earliest possible.  */
   11908              :       gimple *last_stmt = NULL;
   11909       586720 :       FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
   11910       375636 :         if (SLP_TREE_DEF_TYPE (child) == vect_internal_def)
   11911              :           {
   11912              :             /* For fold-left reductions we are retaining the scalar
   11913              :                reduction PHI but we still have SLP_TREE_NUM_VEC_STMTS
   11914              :                set so the representation isn't perfect.  Resort to the
   11915              :                last scalar def here.  */
   11916       299992 :             if (SLP_TREE_VEC_DEFS (child).is_empty ())
   11917              :               {
   11918          940 :                 gcc_assert (SLP_TREE_TYPE (child) == cycle_phi_info_type);
   11919          940 :                 gphi *phi = as_a <gphi *>
   11920          940 :                               (vect_find_last_scalar_stmt_in_slp (child)->stmt);
   11921          940 :                 if (!last_stmt)
   11922              :                   last_stmt = phi;
   11923          721 :                 else if (vect_stmt_dominates_stmt_p (last_stmt, phi))
   11924              :                   last_stmt = phi;
   11925          710 :                 else if (vect_stmt_dominates_stmt_p (phi, last_stmt))
   11926              :                   ;
   11927              :                 else
   11928            0 :                   gcc_unreachable ();
   11929              :               }
   11930              :             /* We are emitting all vectorized stmts in the same place and
   11931              :                the last one is the last.
   11932              :                ???  Unless we have a load permutation applied and that
   11933              :                figures to re-use an earlier generated load.  */
   11934              :             unsigned j;
   11935              :             tree vdef;
   11936       708432 :             FOR_EACH_VEC_ELT (SLP_TREE_VEC_DEFS (child), j, vdef)
   11937       408440 :               if (TREE_CODE (vdef) == SSA_NAME
   11938       408440 :                   && !SSA_NAME_IS_DEFAULT_DEF (vdef))
   11939              :                 {
   11940       408388 :                   gimple *vstmt = SSA_NAME_DEF_STMT (vdef);
   11941       408388 :                   if (!last_stmt)
   11942              :                     last_stmt = vstmt;
   11943       209038 :                   else if (vect_stmt_dominates_stmt_p (last_stmt, vstmt))
   11944              :                     last_stmt = vstmt;
   11945        46642 :                   else if (vect_stmt_dominates_stmt_p (vstmt, last_stmt))
   11946              :                     ;
   11947              :                   else
   11948            0 :                     gcc_unreachable ();
   11949              :                 }
   11950              :           }
   11951        75644 :         else if (!SLP_TREE_VECTYPE (child))
   11952              :           {
   11953              :             /* For externals we use unvectorized at all scalar defs.  */
   11954              :             unsigned j;
   11955              :             tree def;
   11956        15642 :             FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (child), j, def)
   11957              :               /* If the stmt is not inside the region do not
   11958              :                  use it as possible insertion point.  */
   11959         9099 :               if (auto stmt_info = vinfo->lookup_def (def))
   11960              :                 {
   11961          250 :                   gimple *stmt = stmt_info->stmt;
   11962          250 :                   if (!last_stmt)
   11963              :                     last_stmt = stmt;
   11964          230 :                   else if (vect_stmt_dominates_stmt_p (last_stmt, stmt))
   11965              :                     last_stmt = stmt;
   11966           26 :                   else if (vect_stmt_dominates_stmt_p (stmt, last_stmt))
   11967              :                     ;
   11968              :                   else
   11969            0 :                     gcc_unreachable ();
   11970              :                 }
   11971              :           }
   11972              :         else
   11973              :           {
   11974              :             /* For externals we have to look at all defs since their
   11975              :                insertion place is decided per vector.  But beware
   11976              :                of pre-existing vectors where we need to make sure
   11977              :                we do not insert before the region boundary.  */
   11978        69101 :             if (SLP_TREE_SCALAR_OPS (child).is_empty ()
   11979          698 :                 && !vinfo->lookup_def (SLP_TREE_VEC_DEFS (child)[0]))
   11980              :               ;
   11981              :             else
   11982              :               {
   11983              :                 unsigned j;
   11984              :                 tree vdef;
   11985       541709 :                 FOR_EACH_VEC_ELT (SLP_TREE_VEC_DEFS (child), j, vdef)
   11986        97103 :                   if (TREE_CODE (vdef) == SSA_NAME
   11987        97103 :                       && !SSA_NAME_IS_DEFAULT_DEF (vdef))
   11988              :                     {
   11989        21117 :                       gimple *vstmt = SSA_NAME_DEF_STMT (vdef);
   11990        21117 :                       if (!last_stmt)
   11991              :                         last_stmt = vstmt;
   11992        11386 :                       else if (vect_stmt_dominates_stmt_p (last_stmt, vstmt))
   11993              :                         last_stmt = vstmt;
   11994         8985 :                       else if (vect_stmt_dominates_stmt_p (vstmt, last_stmt))
   11995              :                         ;
   11996              :                       else
   11997            0 :                         gcc_unreachable ();
   11998              :                     }
   11999              :               }
   12000              :           }
   12001              : 
   12002              :       /* We split regions to vectorize at control altering stmts
   12003              :          with a definition so this can only be an external.  */
   12004       211084 :       gcc_checking_assert (!last_stmt
   12005              :                            || !is_ctrl_altering_stmt (last_stmt));
   12006              : 
   12007       211084 :       if (is_a <bb_vec_info> (vinfo)
   12008        20835 :           && !SLP_TREE_PERMUTE_P (node)
   12009        19170 :           && (!last_stmt
   12010        19150 :               || gimple_bb (last_stmt) != gimple_bb (stmt_info->stmt))
   12011       212759 :           && gimple_could_trap_p (stmt_info->stmt))
   12012              :         {
   12013              :           /* We've constrained possibly trapping operations to all come
   12014              :              from the same basic-block, if vectorized defs would allow earlier
   12015              :              scheduling still force vectorized stmts to the original block.
   12016              :              This is only necessary for BB vectorization since for loop vect
   12017              :              all operations are in a single BB and scalar stmt based
   12018              :              placement doesn't play well with epilogue vectorization.  */
   12019          137 :           gcc_assert (!last_stmt
   12020              :                       || dominated_by_p (CDI_DOMINATORS,
   12021              :                                          gimple_bb (stmt_info->stmt),
   12022              :                                          gimple_bb (last_stmt)));
   12023          137 :           si = gsi_after_labels (gimple_bb (stmt_info->stmt));
   12024              :         }
   12025              :       /* When there is no in-region child def to guide placement, insert
   12026              :          at region boundary.  */
   12027       210947 :       else if (!last_stmt)
   12028         1756 :         si = gsi_after_labels (vinfo->bbs[0]);
   12029       209191 :       else if (is_a <gphi *> (last_stmt))
   12030        14560 :         si = gsi_after_labels (gimple_bb (last_stmt));
   12031              :       else
   12032              :         {
   12033       194631 :           si = gsi_for_stmt (last_stmt);
   12034              :           /* We use gsi_insert_before, so when last_stmt is a vector
   12035              :              def we have to advance (or use gsi_insert_after).  */
   12036       194631 :           gsi_next (&si);
   12037              : 
   12038       194631 :           if (auto loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
   12039              :             {
   12040              :               /* Avoid scheduling stmts to random places in the CFG, any
   12041              :                  stmt dominance check we performed is possibly wrong as UIDs
   12042              :                  are not initialized for all of the function for loop
   12043              :                  vectorization.  Instead append to the loop preheader.  */
   12044       174344 :               if ((LOOP_VINFO_LOOP (loop_vinfo)->header
   12045       174344 :                    != gimple_bb (last_stmt))
   12046       177489 :                   && dominated_by_p (CDI_DOMINATORS,
   12047              :                                      LOOP_VINFO_LOOP (loop_vinfo)->header,
   12048         3145 :                                      gimple_bb (last_stmt)))
   12049         1262 :                 si = gsi_end_bb (loop_preheader_edge
   12050          631 :                                    (LOOP_VINFO_LOOP (loop_vinfo))->src);
   12051              :               /* Avoid scheduling internal defs outside of the loop when
   12052              :                  we might have only implicitly tracked loop mask/len defs.  */
   12053           76 :               if (LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)
   12054       174344 :                   || LOOP_VINFO_FULLY_WITH_LENGTH_P (loop_vinfo))
   12055              :                 {
   12056           76 :                   gimple_stmt_iterator si2
   12057           76 :                     = gsi_after_labels (LOOP_VINFO_LOOP (loop_vinfo)->header);
   12058           76 :                   if ((gsi_end_p (si2)
   12059            0 :                        && (LOOP_VINFO_LOOP (loop_vinfo)->header
   12060            0 :                            != gimple_bb (last_stmt))
   12061            0 :                        && dominated_by_p (CDI_DOMINATORS,
   12062              :                                           LOOP_VINFO_LOOP (loop_vinfo)->header,
   12063            0 :                                           gimple_bb (last_stmt)))
   12064           76 :                       || (!gsi_end_p (si2)
   12065           76 :                           && last_stmt != *si2
   12066           73 :                           && vect_stmt_dominates_stmt_p (last_stmt, *si2)))
   12067            3 :                     si = si2;
   12068              :                 }
   12069              :             }
   12070              :         }
   12071              :     }
   12072              : 
   12073       988046 :   if (dump_enabled_p ())
   12074              :     {
   12075        71827 :       if (stmt_info)
   12076        71775 :         dump_printf_loc (MSG_NOTE, vect_location,
   12077              :                          "------>vectorizing SLP node starting from: %G",
   12078              :                          stmt_info->stmt);
   12079              :       else
   12080              :         {
   12081           52 :           dump_printf_loc (MSG_NOTE, vect_location,
   12082              :                            "------>vectorizing SLP node:\n");
   12083           52 :           vect_print_slp_tree (MSG_NOTE, vect_location, node);
   12084              :         }
   12085              :     }
   12086       988046 :   vect_transform_stmt (vinfo, stmt_info, &si, node, instance);
   12087              : }
   12088              : 
   12089              : /* Replace scalar calls from SLP node NODE with setting of their lhs to zero.
   12090              :    For loop vectorization this is done in vectorizable_call, but for SLP
   12091              :    it needs to be deferred until end of vect_schedule_slp, because multiple
   12092              :    SLP instances may refer to the same scalar stmt.  */
   12093              : 
   12094              : static void
   12095       604137 : vect_remove_slp_scalar_calls (vec_info *vinfo,
   12096              :                               slp_tree node, hash_set<slp_tree> &visited)
   12097              : {
   12098       604137 :   gimple *new_stmt;
   12099       604137 :   gimple_stmt_iterator gsi;
   12100       604137 :   tree lhs;
   12101              : 
   12102       604137 :   if (!node || SLP_TREE_DEF_TYPE (node) != vect_internal_def)
   12103       189094 :     return;
   12104              : 
   12105       458708 :   if (visited.add (node))
   12106              :     return;
   12107              : 
   12108      1546891 :   for (auto child : SLP_TREE_CHILDREN (node))
   12109       513742 :     vect_remove_slp_scalar_calls (vinfo, child, visited);
   12110              : 
   12111      1724710 :   for (auto stmt_info : SLP_TREE_SCALAR_STMTS (node))
   12112              :     {
   12113       487859 :       if (!stmt_info)
   12114         3978 :         continue;
   12115       483881 :       stmt_info = vect_orig_stmt (stmt_info);
   12116       483881 :       gcall *stmt = dyn_cast <gcall *> (stmt_info->stmt);
   12117         5142 :       if (!stmt || gimple_bb (stmt) == NULL)
   12118       478781 :         continue;
   12119         5100 :       lhs = gimple_call_lhs (stmt);
   12120         5100 :       if (lhs)
   12121         4529 :         new_stmt = gimple_build_assign (lhs, build_zero_cst (TREE_TYPE (lhs)));
   12122              :       else
   12123          571 :         new_stmt = gimple_build_nop ();
   12124         5100 :       unlink_stmt_vdef (stmt_info->stmt);
   12125         5100 :       gsi = gsi_for_stmt (stmt);
   12126         5100 :       vinfo->replace_stmt (&gsi, stmt_info, new_stmt);
   12127         5100 :       if (lhs)
   12128         4529 :         SSA_NAME_DEF_STMT (lhs) = new_stmt;
   12129              :     }
   12130              : }
   12131              : 
   12132              : static void
   12133        90395 : vect_remove_slp_scalar_calls (vec_info *vinfo, slp_tree node)
   12134              : {
   12135        90395 :   hash_set<slp_tree> visited;
   12136        90395 :   vect_remove_slp_scalar_calls (vinfo, node, visited);
   12137        90395 : }
   12138              : 
   12139              : /* Vectorize the instance root.  */
   12140              : 
   12141              : void
   12142        13458 : vectorize_slp_instance_root_stmt (vec_info *vinfo, slp_tree node, slp_instance instance)
   12143              : {
   12144        13458 :   gassign *rstmt = NULL;
   12145              : 
   12146        13458 :   if (instance->kind == slp_inst_kind_ctor)
   12147              :     {
   12148         5467 :       if (SLP_TREE_VEC_DEFS (node).length () == 1)
   12149              :         {
   12150         5422 :           tree vect_lhs = SLP_TREE_VEC_DEFS (node)[0];
   12151         5422 :           tree root_lhs = gimple_get_lhs (instance->root_stmts[0]->stmt);
   12152         5422 :           if (!useless_type_conversion_p (TREE_TYPE (root_lhs),
   12153         5422 :                                           TREE_TYPE (vect_lhs)))
   12154            0 :             vect_lhs = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (root_lhs),
   12155              :                                vect_lhs);
   12156         5422 :           rstmt = gimple_build_assign (root_lhs, vect_lhs);
   12157              :         }
   12158              :       else
   12159              :         {
   12160           45 :           gcc_assert (SLP_TREE_VEC_DEFS (node).length () > 1);
   12161           45 :           tree child_def;
   12162           45 :           int j;
   12163           45 :           vec<constructor_elt, va_gc> *v;
   12164           45 :           vec_alloc (v, SLP_TREE_VEC_DEFS (node).length ());
   12165              : 
   12166              :           /* A CTOR can handle V16HI composition from VNx8HI so we
   12167              :              do not need to convert vector elements if the types
   12168              :              do not match.  */
   12169          135 :           FOR_EACH_VEC_ELT (SLP_TREE_VEC_DEFS (node), j, child_def)
   12170           90 :             CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, child_def);
   12171           45 :           tree lhs = gimple_get_lhs (instance->root_stmts[0]->stmt);
   12172           45 :           tree rtype
   12173           45 :             = TREE_TYPE (gimple_assign_rhs1 (instance->root_stmts[0]->stmt));
   12174           45 :           tree r_constructor = build_constructor (rtype, v);
   12175           45 :           rstmt = gimple_build_assign (lhs, r_constructor);
   12176              :         }
   12177              :     }
   12178         7991 :   else if (instance->kind == slp_inst_kind_bb_reduc)
   12179              :     {
   12180              :       /* Largely inspired by reduction chain epilogue handling in
   12181              :          vect_create_epilog_for_reduction.  */
   12182         6399 :       vec<tree> vec_defs = vNULL;
   12183         6399 :       vect_get_slp_defs (node, &vec_defs);
   12184         6399 :       enum tree_code reduc_code
   12185         6399 :         = gimple_assign_rhs_code (instance->root_stmts[0]->stmt);
   12186              :       /* ???  We actually have to reflect signs somewhere.  */
   12187         6399 :       if (reduc_code == MINUS_EXPR)
   12188            0 :         reduc_code = PLUS_EXPR;
   12189         6399 :       gimple_seq epilogue = NULL;
   12190              :       /* We may end up with more than one vector result, reduce them
   12191              :          to one vector.  */
   12192         6399 :       tree vec_def = vec_defs[0];
   12193         6399 :       tree vectype = TREE_TYPE (vec_def);
   12194         6399 :       tree compute_vectype = vectype;
   12195         6399 :       bool pun_for_overflow_p = (ANY_INTEGRAL_TYPE_P (vectype)
   12196         5275 :                                  && TYPE_OVERFLOW_UNDEFINED (vectype)
   12197         9958 :                                  && operation_can_overflow (reduc_code));
   12198         3007 :       if (pun_for_overflow_p)
   12199              :         {
   12200         3007 :           compute_vectype = unsigned_type_for (vectype);
   12201         3007 :           vec_def = gimple_build (&epilogue, VIEW_CONVERT_EXPR,
   12202              :                                   compute_vectype, vec_def);
   12203              :         }
   12204         8897 :       for (unsigned i = 1; i < vec_defs.length (); ++i)
   12205              :         {
   12206         2498 :           tree def = vec_defs[i];
   12207         2498 :           if (pun_for_overflow_p)
   12208         2293 :             def = gimple_build (&epilogue, VIEW_CONVERT_EXPR,
   12209              :                                 compute_vectype, def);
   12210         2498 :           vec_def = gimple_build (&epilogue, reduc_code, compute_vectype,
   12211              :                                   vec_def, def);
   12212              :         }
   12213         6399 :       vec_defs.release ();
   12214              :       /* ???  Support other schemes than direct internal fn or two
   12215              :          element vectors.  */
   12216         6399 :       tree scalar_def;
   12217         6399 :       internal_fn reduc_fn;
   12218         6399 :       if (!reduction_fn_for_scalar_code (reduc_code, &reduc_fn)
   12219         6399 :           || reduc_fn == IFN_LAST
   12220        12798 :           || !direct_internal_fn_supported_p (reduc_fn, compute_vectype,
   12221              :                                               OPTIMIZE_FOR_BOTH))
   12222              :         {
   12223         1633 :           gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (compute_vectype), 2u));
   12224         1633 :           tree tem0 = gimple_build (&epilogue, BIT_FIELD_REF,
   12225         1633 :                                     TREE_TYPE (compute_vectype), vec_def,
   12226         1633 :                                     TYPE_SIZE (TREE_TYPE (compute_vectype)),
   12227         1633 :                                     bitsize_zero_node);
   12228         1633 :           tree tem1 = gimple_build (&epilogue, BIT_FIELD_REF,
   12229         1633 :                                     TREE_TYPE (compute_vectype), vec_def,
   12230         1633 :                                     TYPE_SIZE (TREE_TYPE (compute_vectype)),
   12231         1633 :                                     TYPE_SIZE (TREE_TYPE (compute_vectype)));
   12232         1633 :           scalar_def = gimple_build (&epilogue, reduc_code,
   12233         1633 :                                      TREE_TYPE (compute_vectype), tem0, tem1);
   12234              :         }
   12235              :       else
   12236         4766 :         scalar_def = gimple_build (&epilogue, as_combined_fn (reduc_fn),
   12237         4766 :                                    TREE_TYPE (compute_vectype), vec_def);
   12238         6399 :       if (!SLP_INSTANCE_REMAIN_DEFS (instance).is_empty ())
   12239              :         {
   12240         3458 :           tree rem_def = NULL_TREE;
   12241        14402 :           for (auto def : SLP_INSTANCE_REMAIN_DEFS (instance))
   12242              :             {
   12243        10944 :               def = gimple_convert (&epilogue, TREE_TYPE (scalar_def), def);
   12244        10944 :               if (!rem_def)
   12245              :                 rem_def = def;
   12246              :               else
   12247         7486 :                 rem_def = gimple_build (&epilogue, reduc_code,
   12248         7486 :                                         TREE_TYPE (scalar_def),
   12249              :                                         rem_def, def);
   12250              :             }
   12251         3458 :           scalar_def = gimple_build (&epilogue, reduc_code,
   12252         3458 :                                      TREE_TYPE (scalar_def),
   12253              :                                      scalar_def, rem_def);
   12254              :         }
   12255         6399 :       scalar_def = gimple_convert (&epilogue,
   12256         6399 :                                    TREE_TYPE (vectype), scalar_def);
   12257         6399 :       gimple_stmt_iterator rgsi = gsi_for_stmt (instance->root_stmts[0]->stmt);
   12258         6399 :       gsi_insert_seq_before (&rgsi, epilogue, GSI_SAME_STMT);
   12259         6399 :       gimple_assign_set_rhs_from_tree (&rgsi, scalar_def);
   12260         6399 :       update_stmt (gsi_stmt (rgsi));
   12261         6399 :       return;
   12262              :     }
   12263         1592 :   else if (instance->kind == slp_inst_kind_gcond)
   12264              :     {
   12265              :       /* Only support a single root for now as we can't codegen CFG yet and so we
   12266              :          can't support lane > 1 at this time.  */
   12267         1592 :       gcc_assert (instance->root_stmts.length () == 1);
   12268         1592 :       auto root_stmt_info = instance->root_stmts[0];
   12269         1592 :       auto last_stmt = STMT_VINFO_STMT (vect_orig_stmt (root_stmt_info));
   12270         1592 :       gimple_stmt_iterator rgsi = gsi_for_stmt (last_stmt);
   12271         1592 :       gcc_assert (!SLP_TREE_VEC_DEFS (node).is_empty ());
   12272         1592 :       bool res = vectorizable_early_exit (as_a <loop_vec_info> (vinfo),
   12273              :                                           root_stmt_info, &rgsi, node, NULL);
   12274         1592 :       gcc_assert (res);
   12275         1592 :       return;
   12276              :     }
   12277              :   else
   12278            0 :     gcc_unreachable ();
   12279              : 
   12280         5467 :   gcc_assert (rstmt);
   12281              : 
   12282         5467 :   gimple_stmt_iterator rgsi = gsi_for_stmt (instance->root_stmts[0]->stmt);
   12283         5467 :   gsi_replace (&rgsi, rstmt, true);
   12284              : }
   12285              : 
   12286              : struct slp_scc_info
   12287              : {
   12288              :   bool on_stack;
   12289              :   int dfs;
   12290              :   int lowlink;
   12291              : };
   12292              : 
   12293              : /* Schedule the SLP INSTANCE doing a DFS walk and collecting SCCs.  */
   12294              : 
   12295              : static void
   12296      1494661 : vect_schedule_scc (vec_info *vinfo, slp_tree node, slp_instance instance,
   12297              :                    hash_map<slp_tree, slp_scc_info> &scc_info,
   12298              :                    int &maxdfs, vec<slp_tree> &stack)
   12299              : {
   12300      1494661 :   bool existed_p;
   12301      1494661 :   slp_scc_info *info = &scc_info.get_or_insert (node, &existed_p);
   12302      1494661 :   gcc_assert (!existed_p);
   12303      1494661 :   info->dfs = maxdfs;
   12304      1494661 :   info->lowlink = maxdfs;
   12305      1494661 :   maxdfs++;
   12306              : 
   12307              :   /* Leaf.  */
   12308      1494661 :   if (SLP_TREE_DEF_TYPE (node) != vect_internal_def)
   12309              :     {
   12310       506615 :       info->on_stack = false;
   12311       506615 :       vect_schedule_slp_node (vinfo, node, instance);
   12312      1045096 :       return;
   12313              :     }
   12314              : 
   12315       988046 :   info->on_stack = true;
   12316       988046 :   stack.safe_push (node);
   12317              : 
   12318       988046 :   unsigned i;
   12319       988046 :   slp_tree child;
   12320              :   /* DFS recurse.  */
   12321      2038306 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
   12322              :     {
   12323      1050260 :       if (!child)
   12324        55513 :         continue;
   12325       994747 :       slp_scc_info *child_info = scc_info.get (child);
   12326       994747 :       if (!child_info)
   12327              :         {
   12328       903044 :           vect_schedule_scc (vinfo, child, instance, scc_info, maxdfs, stack);
   12329              :           /* Recursion might have re-allocated the node.  */
   12330       903044 :           info = scc_info.get (node);
   12331       903044 :           child_info = scc_info.get (child);
   12332       903044 :           info->lowlink = MIN (info->lowlink, child_info->lowlink);
   12333              :         }
   12334        91703 :       else if (child_info->on_stack)
   12335        25605 :         info->lowlink = MIN (info->lowlink, child_info->dfs);
   12336              :     }
   12337       988046 :   if (info->lowlink != info->dfs)
   12338              :     return;
   12339              : 
   12340       956180 :   auto_vec<slp_tree, 4> phis_to_fixup;
   12341              : 
   12342              :   /* Singleton.  */
   12343       956180 :   if (stack.last () == node)
   12344              :     {
   12345       932250 :       stack.pop ();
   12346       932250 :       info->on_stack = false;
   12347       932250 :       vect_schedule_slp_node (vinfo, node, instance);
   12348       932250 :       if (!SLP_TREE_PERMUTE_P (node)
   12349       932250 :           && is_a <gphi *> (SLP_TREE_REPRESENTATIVE (node)->stmt))
   12350        30883 :         phis_to_fixup.quick_push (node);
   12351              :     }
   12352              :   else
   12353              :     {
   12354              :       /* SCC.  */
   12355        23930 :       int last_idx = stack.length () - 1;
   12356        55796 :       while (stack[last_idx] != node)
   12357        31866 :         last_idx--;
   12358              :       /* We can break the cycle at PHIs who have at least one child
   12359              :          code generated.  Then we could re-start the DFS walk until
   12360              :          all nodes in the SCC are covered (we might have new entries
   12361              :          for only back-reachable nodes).  But it's simpler to just
   12362              :          iterate and schedule those that are ready.  */
   12363        23930 :       unsigned todo = stack.length () - last_idx;
   12364        24271 :       do
   12365              :         {
   12366       106130 :           for (int idx = stack.length () - 1; idx >= last_idx; --idx)
   12367              :             {
   12368        57588 :               slp_tree entry = stack[idx];
   12369        57588 :               if (!entry)
   12370          958 :                 continue;
   12371        56630 :               bool phi = (!SLP_TREE_PERMUTE_P (entry)
   12372        56630 :                           && is_a <gphi *> (SLP_TREE_REPRESENTATIVE (entry)->stmt));
   12373        56630 :               bool ready = !phi;
   12374       143285 :               FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (entry), i, child)
   12375       111835 :                   if (!child)
   12376              :                     {
   12377        23029 :                       gcc_assert (phi);
   12378              :                       ready = true;
   12379              :                       break;
   12380              :                     }
   12381        88806 :                   else if (scc_info.get (child)->on_stack)
   12382              :                     {
   12383        24111 :                       if (!phi)
   12384              :                         {
   12385              :                           ready = false;
   12386              :                           break;
   12387              :                         }
   12388              :                     }
   12389              :                   else
   12390              :                     {
   12391        64695 :                       if (phi)
   12392              :                         {
   12393              :                           ready = true;
   12394              :                           break;
   12395              :                         }
   12396              :                     }
   12397        33601 :               if (ready)
   12398              :                 {
   12399        55796 :                   vect_schedule_slp_node (vinfo, entry, instance);
   12400        55796 :                   scc_info.get (entry)->on_stack = false;
   12401        55796 :                   stack[idx] = NULL;
   12402        55796 :                   todo--;
   12403        55796 :                   if (phi)
   12404        24376 :                     phis_to_fixup.safe_push (entry);
   12405              :                 }
   12406              :             }
   12407              :         }
   12408        24271 :       while (todo != 0);
   12409              : 
   12410              :       /* Pop the SCC.  */
   12411        23930 :       stack.truncate (last_idx);
   12412              :     }
   12413              : 
   12414              :   /* Now fixup the backedge def of the vectorized PHIs in this SCC.  */
   12415              :   slp_tree phi_node;
   12416      1967619 :   FOR_EACH_VEC_ELT (phis_to_fixup, i, phi_node)
   12417              :     {
   12418        55259 :       gphi *phi = as_a <gphi *> (SLP_TREE_REPRESENTATIVE (phi_node)->stmt);
   12419        55259 :       edge_iterator ei;
   12420        55259 :       edge e;
   12421       174657 :       FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
   12422              :         {
   12423       119398 :           unsigned dest_idx = e->dest_idx;
   12424       119398 :           child = SLP_TREE_CHILDREN (phi_node)[dest_idx];
   12425       119398 :           if (!child || SLP_TREE_DEF_TYPE (child) != vect_internal_def)
   12426        66758 :             continue;
   12427        52640 :           unsigned n = SLP_TREE_VEC_DEFS (phi_node).length ();
   12428              :           /* Simply fill all args.  */
   12429        52640 :           if (STMT_VINFO_DEF_TYPE (SLP_TREE_REPRESENTATIVE (phi_node))
   12430              :               != vect_first_order_recurrence)
   12431       113127 :             for (unsigned i = 0; i < n; ++i)
   12432              :               {
   12433        60532 :                 tree phidef = SLP_TREE_VEC_DEFS (phi_node)[i];
   12434        60532 :                 gphi *phi = as_a <gphi *> (SSA_NAME_DEF_STMT (phidef));
   12435        60532 :                 add_phi_arg (phi, vect_get_slp_vect_def (child, i),
   12436              :                              e, gimple_phi_arg_location (phi, dest_idx));
   12437              :               }
   12438              :           else
   12439              :             {
   12440              :               /* Unless it is a first order recurrence which needs
   12441              :                  args filled in for both the PHI node and the permutes.  */
   12442           45 :               gimple *perm
   12443           45 :                 = SSA_NAME_DEF_STMT (SLP_TREE_VEC_DEFS (phi_node)[0]);
   12444           45 :               gimple *rphi = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (perm));
   12445           45 :               add_phi_arg (as_a <gphi *> (rphi),
   12446              :                            vect_get_slp_vect_def (child, n - 1),
   12447              :                            e, gimple_phi_arg_location (phi, dest_idx));
   12448          127 :               for (unsigned i = 0; i < n; ++i)
   12449              :                 {
   12450           82 :                   gimple *perm
   12451           82 :                     = SSA_NAME_DEF_STMT (SLP_TREE_VEC_DEFS (phi_node)[i]);
   12452           82 :                   if (i > 0)
   12453           37 :                     gimple_assign_set_rhs1 (perm,
   12454              :                                             vect_get_slp_vect_def (child, i - 1));
   12455           82 :                   gimple_assign_set_rhs2 (perm,
   12456              :                                           vect_get_slp_vect_def (child, i));
   12457           82 :                   update_stmt (perm);
   12458              :                 }
   12459              :             }
   12460              :         }
   12461              :     }
   12462       956180 : }
   12463              : 
   12464              : /* Generate vector code for SLP_INSTANCES in the loop/basic block.  */
   12465              : 
   12466              : void
   12467       551583 : vect_schedule_slp (vec_info *vinfo, const vec<slp_instance> &slp_instances)
   12468              : {
   12469       551583 :   slp_instance instance;
   12470       551583 :   unsigned int i;
   12471              : 
   12472       551583 :   hash_map<slp_tree, slp_scc_info> scc_info;
   12473       551583 :   int maxdfs = 0;
   12474      1143333 :   FOR_EACH_VEC_ELT (slp_instances, i, instance)
   12475              :     {
   12476       591750 :       slp_tree node = SLP_INSTANCE_TREE (instance);
   12477       591750 :       if (dump_enabled_p ())
   12478              :         {
   12479        16097 :           dump_printf_loc (MSG_NOTE, vect_location,
   12480              :                            "Vectorizing SLP tree:\n");
   12481              :           /* ???  Dump all?  */
   12482        16097 :           if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ())
   12483          485 :             dump_printf_loc (MSG_NOTE, vect_location, "Root stmt: %G",
   12484          485 :                          SLP_INSTANCE_ROOT_STMTS (instance)[0]->stmt);
   12485        16097 :           vect_print_slp_graph (MSG_NOTE, vect_location,
   12486              :                                 SLP_INSTANCE_TREE (instance));
   12487              :         }
   12488              :       /* Schedule the tree of INSTANCE, scheduling SCCs in a way to
   12489              :          have a PHI be the node breaking the cycle.  */
   12490       591750 :       auto_vec<slp_tree> stack;
   12491       591750 :       if (!scc_info.get (node))
   12492       591617 :         vect_schedule_scc (vinfo, node, instance, scc_info, maxdfs, stack);
   12493              : 
   12494       591750 :       if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ())
   12495        13458 :         vectorize_slp_instance_root_stmt (vinfo, node, instance);
   12496              : 
   12497       591750 :       if (dump_enabled_p ())
   12498        16097 :         dump_printf_loc (MSG_NOTE, vect_location,
   12499              :                          "vectorizing stmts using SLP.\n");
   12500       591750 :     }
   12501              : 
   12502      1694916 :   FOR_EACH_VEC_ELT (slp_instances, i, instance)
   12503              :     {
   12504       591750 :       slp_tree root = SLP_INSTANCE_TREE (instance);
   12505       591750 :       stmt_vec_info store_info;
   12506       591750 :       unsigned int j;
   12507              : 
   12508              :       /* Remove scalar call stmts.  Do not do this for basic-block
   12509              :          vectorization as not all uses may be vectorized.
   12510              :          ???  Why should this be necessary?  DCE should be able to
   12511              :          remove the stmts itself.
   12512              :          ???  For BB vectorization we can as well remove scalar
   12513              :          stmts starting from the SLP tree root if they have no
   12514              :          uses.  */
   12515       591750 :       if (is_a <loop_vec_info> (vinfo))
   12516        90395 :         vect_remove_slp_scalar_calls (vinfo, root);
   12517              : 
   12518              :       /* Remove vectorized stores original scalar stmts.  */
   12519      2635564 :       for (j = 0; SLP_TREE_SCALAR_STMTS (root).iterate (j, &store_info); j++)
   12520              :         {
   12521      1490986 :           if (!store_info
   12522      1490972 :               || !STMT_VINFO_DATA_REF (store_info)
   12523      1461654 :               || !DR_IS_WRITE (STMT_VINFO_DATA_REF (store_info)))
   12524              :             break;
   12525              : 
   12526      1452064 :           store_info = vect_orig_stmt (store_info);
   12527              :           /* Free the attached stmt_vec_info and remove the stmt.  */
   12528      1452064 :           vinfo->remove_stmt (store_info);
   12529              : 
   12530              :           /* Invalidate SLP_TREE_REPRESENTATIVE in case we released it
   12531              :              to not crash in vect_free_slp_tree later.  */
   12532      1452064 :           if (SLP_TREE_REPRESENTATIVE (root) == store_info)
   12533       552489 :             SLP_TREE_REPRESENTATIVE (root) = NULL;
   12534              :         }
   12535              :     }
   12536       551583 : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.