LCOV - code coverage report
Current view: top level - gcc - tree-vect-slp.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.1 % 6186 5762
Test Date: 2026-10-17 16:30:31 Functions: 95.2 % 186 177
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      1146012 : vect_slp_init (void)
      78              : {
      79      1146012 :   slp_tree_pool = new object_allocator<_slp_tree> ("SLP nodes");
      80      1146012 : }
      81              : 
      82              : void
      83      1146012 : vect_slp_fini (void)
      84              : {
      85      1839626 :   while (slp_first_node)
      86       693614 :     delete slp_first_node;
      87      2292024 :   delete slp_tree_pool;
      88      1146012 :   slp_tree_pool = NULL;
      89      1146012 : }
      90              : 
      91              : void *
      92      8297432 : _slp_tree::operator new (size_t n)
      93              : {
      94      8297432 :   gcc_assert (n == sizeof (_slp_tree));
      95      8297432 :   return slp_tree_pool->allocate_raw ();
      96              : }
      97              : 
      98              : void
      99      8297432 : _slp_tree::operator delete (void *node, size_t n)
     100              : {
     101      8297432 :   gcc_assert (n == sizeof (_slp_tree));
     102      8297432 :   slp_tree_pool->remove_raw (node);
     103      8297432 : }
     104              : 
     105              : 
     106              : /* Initialize a SLP node.  */
     107              : 
     108      8297432 : _slp_tree::_slp_tree ()
     109              : {
     110      8297432 :   this->prev_node = NULL;
     111      8297432 :   if (slp_first_node)
     112      7251039 :     slp_first_node->prev_node = this;
     113      8297432 :   this->next_node = slp_first_node;
     114      8297432 :   slp_first_node = this;
     115      8297432 :   SLP_TREE_SCALAR_STMTS (this) = vNULL;
     116      8297432 :   SLP_TREE_SCALAR_OPS (this) = vNULL;
     117      8297432 :   SLP_TREE_LIVE_LANES (this) = vNULL;
     118      8297432 :   SLP_TREE_VEC_DEFS (this) = vNULL;
     119      8297432 :   SLP_TREE_CHILDREN (this) = vNULL;
     120      8297432 :   SLP_TREE_LOAD_PERMUTATION (this) = vNULL;
     121      8297432 :   SLP_TREE_LANE_PERMUTATION (this) = vNULL;
     122      8297432 :   SLP_TREE_DEF_TYPE (this) = vect_uninitialized_def;
     123      8297432 :   SLP_TREE_CODE (this) = ERROR_MARK;
     124      8297432 :   SLP_TREE_GS_SCALE (this) = 0;
     125      8297432 :   SLP_TREE_GS_BASE (this) = NULL_TREE;
     126      8297432 :   this->ldst_lanes = false;
     127      8297432 :   this->avoid_stlf_fail = false;
     128      8297432 :   SLP_TREE_VECTYPE (this) = NULL_TREE;
     129      8297432 :   SLP_TREE_REPRESENTATIVE (this) = NULL;
     130      8297432 :   this->cycle_info.id = -1;
     131      8297432 :   this->cycle_info.reduc_idx = -1;
     132      8297432 :   SLP_TREE_REF_COUNT (this) = 1;
     133      8297432 :   this->failed = NULL;
     134      8297432 :   this->lanes = 0;
     135      8297432 :   SLP_TREE_TYPE (this) = undef_vec_info_type;
     136      8297432 :   this->data = NULL;
     137      8297432 :   this->si = NULL;
     138      8297432 : }
     139              : 
     140              : /* Tear down a SLP node.  */
     141              : 
     142      8297432 : _slp_tree::~_slp_tree ()
     143              : {
     144      8297432 :   if (this->prev_node)
     145      5061030 :     this->prev_node->next_node = this->next_node;
     146              :   else
     147      3236402 :     slp_first_node = this->next_node;
     148      8297432 :   if (this->next_node)
     149      6263940 :     this->next_node->prev_node = this->prev_node;
     150      8297432 :   SLP_TREE_CHILDREN (this).release ();
     151      8297432 :   SLP_TREE_SCALAR_STMTS (this).release ();
     152      8297432 :   SLP_TREE_SCALAR_OPS (this).release ();
     153      8297432 :   SLP_TREE_LIVE_LANES (this).release ();
     154      8297432 :   SLP_TREE_VEC_DEFS (this).release ();
     155      8297432 :   SLP_TREE_LOAD_PERMUTATION (this).release ();
     156      8297432 :   SLP_TREE_LANE_PERMUTATION (this).release ();
     157      8297432 :   if (this->failed)
     158      2199736 :     free (failed);
     159      8297432 :   if (this->data)
     160      1287202 :     delete this->data;
     161      8297432 : }
     162              : 
     163              : /* Push the single SSA definition in DEF to the vector of vector defs.  */
     164              : 
     165              : void
     166       522688 : _slp_tree::push_vec_def (gimple *def)
     167              : {
     168       522688 :   if (gphi *phi = dyn_cast <gphi *> (def))
     169        57679 :     vec_defs.quick_push (gimple_phi_result (phi));
     170              :   else
     171              :     {
     172       465009 :       def_operand_p defop = single_ssa_def_operand (def, SSA_OP_ALL_DEFS);
     173       465009 :       vec_defs.quick_push (get_def_from_ptr (defop));
     174              :     }
     175       522688 : }
     176              : 
     177              : /* Recursively free the memory allocated for the SLP tree rooted at NODE.  */
     178              : 
     179              : void
     180     15680010 : vect_free_slp_tree (slp_tree node)
     181              : {
     182     15680010 :   int i;
     183     15680010 :   slp_tree child;
     184              : 
     185     15680010 :   if (--SLP_TREE_REF_COUNT (node) != 0)
     186     15680010 :     return;
     187              : 
     188     11808526 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
     189      4204708 :     if (child)
     190      3817236 :       vect_free_slp_tree (child);
     191              : 
     192      7603818 :   delete node;
     193              : }
     194              : 
     195              : /* Return a location suitable for dumpings related to the SLP instance.  */
     196              : 
     197              : dump_user_location_t
     198      3556387 : _slp_instance::location () const
     199              : {
     200      3556387 :   if (!root_stmts.is_empty ())
     201       414664 :     return root_stmts[0]->stmt;
     202              :   else
     203      3141723 :     return SLP_TREE_SCALAR_STMTS (root)[0]->stmt;
     204              : }
     205              : 
     206              : 
     207              : /* Free the memory allocated for the SLP instance.  */
     208              : 
     209              : void
     210      1643704 : vect_free_slp_instance (slp_instance instance)
     211              : {
     212      1643704 :   vect_free_slp_tree (SLP_INSTANCE_TREE (instance));
     213      1643704 :   SLP_INSTANCE_LOADS (instance).release ();
     214      1643704 :   SLP_INSTANCE_ROOT_STMTS (instance).release ();
     215      1643704 :   SLP_INSTANCE_REMAIN_DEFS (instance).release ();
     216      1643704 :   instance->subgraph_entries.release ();
     217      1643704 :   instance->cost_vec.release ();
     218      1643704 :   free (instance);
     219      1643704 : }
     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        97773 : vect_create_new_slp_node (unsigned nops, tree_code code)
     227              : {
     228        97773 :   gcc_assert (code == ERROR_MARK || code == VEC_PERM_EXPR);
     229        97773 :   slp_tree node = new _slp_tree;
     230        97773 :   SLP_TREE_SCALAR_STMTS (node) = vNULL;
     231        97773 :   SLP_TREE_CHILDREN (node).create (nops);
     232        97773 :   SLP_TREE_DEF_TYPE (node) = vect_internal_def;
     233        97773 :   SLP_TREE_CODE (node) = code;
     234        97773 :   return node;
     235              : }
     236              : 
     237              : /* Create a SLP node inplace at NODE for SCALAR_STMTS and NOPS children.  */
     238              : 
     239              : static slp_tree
     240      4007655 : vect_create_new_slp_node (slp_tree node,
     241              :                           vec<stmt_vec_info> scalar_stmts, unsigned nops)
     242              : {
     243      4007655 :   SLP_TREE_SCALAR_STMTS (node) = scalar_stmts;
     244      4007655 :   SLP_TREE_CHILDREN (node).create (nops);
     245      4007655 :   SLP_TREE_DEF_TYPE (node) = vect_internal_def;
     246      4007655 :   SLP_TREE_REPRESENTATIVE (node) = scalar_stmts[0];
     247      4007655 :   SLP_TREE_LANES (node) = scalar_stmts.length ();
     248      4007655 :   return node;
     249              : }
     250              : 
     251              : /* Create an SLP node for SCALAR_STMTS and NOPS children.  */
     252              : 
     253              : static slp_tree
     254         8384 : vect_create_new_slp_node (vec<stmt_vec_info> scalar_stmts, unsigned nops)
     255              : {
     256         8384 :   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      1980141 : vect_create_new_slp_node (slp_tree node, vec<tree> ops)
     264              : {
     265      1980141 :   SLP_TREE_SCALAR_OPS (node) = ops;
     266      1980141 :   SLP_TREE_DEF_TYPE (node) = vect_external_def;
     267            0 :   SLP_TREE_LANES (node) = ops.length ();
     268      1980141 :   return node;
     269              : }
     270              : 
     271              : /* Create a vect_external_def SLP node for scalar operands OPS.  */
     272              : 
     273              : static slp_tree
     274      1980141 : vect_create_new_slp_node (vec<tree> ops)
     275              : {
     276      1980141 :   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      3687985 : vect_create_oprnd_info (int nops, int group_size)
     304              : {
     305      3687985 :   int i;
     306      3687985 :   slp_oprnd_info oprnd_info;
     307      3687985 :   vec<slp_oprnd_info> oprnds_info;
     308              : 
     309      3687985 :   oprnds_info.create (nops);
     310     13201610 :   for (i = 0; i < nops; i++)
     311              :     {
     312      5825640 :       oprnd_info = XNEW (struct _slp_oprnd_info);
     313      5825640 :       oprnd_info->def_stmts.create (group_size);
     314      5825640 :       oprnd_info->ops.create (group_size);
     315      5825640 :       oprnd_info->first_dt = vect_uninitialized_def;
     316      5825640 :       oprnd_info->first_op_type = NULL_TREE;
     317      5825640 :       oprnd_info->any_pattern = false;
     318      5825640 :       oprnd_info->first_gs_p = false;
     319      5825640 :       oprnds_info.quick_push (oprnd_info);
     320              :     }
     321              : 
     322      3687985 :   return oprnds_info;
     323              : }
     324              : 
     325              : 
     326              : /* Free operands info.  */
     327              : 
     328              : static void
     329      3564546 : vect_free_oprnd_info (vec<slp_oprnd_info> &oprnds_info)
     330              : {
     331      3564546 :   int i;
     332      3564546 :   slp_oprnd_info oprnd_info;
     333              : 
     334      9258309 :   FOR_EACH_VEC_ELT (oprnds_info, i, oprnd_info)
     335              :     {
     336      5693763 :       oprnd_info->def_stmts.release ();
     337      5693763 :       oprnd_info->ops.release ();
     338      5693763 :       XDELETE (oprnd_info);
     339              :     }
     340              : 
     341      3564546 :   oprnds_info.release ();
     342      3564546 : }
     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      3695625 : vect_slp_node_weight (vec_info *vinfo, slp_tree node)
     349              : {
     350      3695625 :   stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node);
     351      3695625 :   basic_block bb;
     352              :   /* ???  This is imprecise, VEC_PERM nodes do not have a representative
     353              :      but are laid out close to their children.  */
     354      3695625 :   if (!stmt_info)
     355       143099 :     bb = vinfo->bbs[0];
     356              :   else
     357      4031362 :     bb = gimple_bb (vect_orig_stmt (stmt_info)->stmt);
     358      3695625 :   return bb->count.to_sreal_scale (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count);
     359              : }
     360              : 
     361              : /* Return true if STMTS contains a pattern statement.  */
     362              : 
     363              : static bool
     364        30202 : vect_contains_pattern_stmt_p (vec<stmt_vec_info> stmts)
     365              : {
     366        30202 :   stmt_vec_info stmt_info;
     367        30202 :   unsigned int i;
     368        88002 :   FOR_EACH_VEC_ELT (stmts, i, stmt_info)
     369        65271 :     if (stmt_info && is_pattern_stmt_p (stmt_info))
     370              :       return true;
     371              :   return false;
     372              : }
     373              : 
     374              : /* Return true when all lanes in the external or constant NODE have
     375              :    the same value.  */
     376              : 
     377              : static bool
     378       647938 : vect_slp_tree_uniform_p (slp_tree node)
     379              : {
     380       647938 :   gcc_assert (SLP_TREE_DEF_TYPE (node) == vect_constant_def
     381              :               || SLP_TREE_DEF_TYPE (node) == vect_external_def);
     382              : 
     383              :   /* Pre-existing vectors.  */
     384       647938 :   if (SLP_TREE_SCALAR_OPS (node).is_empty ())
     385              :     return false;
     386              : 
     387              :   unsigned i;
     388              :   tree op, first = NULL_TREE;
     389      1485540 :   FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
     390      1326668 :     if (!first)
     391              :       first = op;
     392       678730 :     else if (!operand_equal_p (first, op, 0))
     393              :       return false;
     394              : 
     395              :   return true;
     396              : }
     397              : 
     398              : /* Find the place of the data-ref in STMT_INFO in the interleaving chain
     399              :    that starts from FIRST_STMT_INFO.  Return -1 if the data-ref is not a part
     400              :    of the chain.  */
     401              : 
     402              : int
     403       754663 : vect_get_place_in_interleaving_chain (stmt_vec_info stmt_info,
     404              :                                       stmt_vec_info first_stmt_info)
     405              : {
     406       754663 :   stmt_vec_info next_stmt_info = first_stmt_info;
     407       754663 :   int result = 0;
     408              : 
     409       754663 :   if (first_stmt_info != DR_GROUP_FIRST_ELEMENT (stmt_info))
     410              :     return -1;
     411              : 
     412      2134984 :   do
     413              :     {
     414      2134984 :       if (next_stmt_info == stmt_info)
     415              :         return result;
     416      1380321 :       next_stmt_info = DR_GROUP_NEXT_ELEMENT (next_stmt_info);
     417      1380321 :       if (next_stmt_info)
     418      1380321 :         result += DR_GROUP_GAP (next_stmt_info);
     419              :     }
     420      1380321 :   while (next_stmt_info);
     421              : 
     422              :   return -1;
     423              : }
     424              : 
     425              : /* Check whether it is possible to load COUNT elements of type ELT_TYPE
     426              :    using the method implemented by duplicate_and_interleave.  Return true
     427              :    if so, returning the number of intermediate vectors in *NVECTORS_OUT
     428              :    (if nonnull) and the type of each intermediate vector in *VECTOR_TYPE_OUT
     429              :    (if nonnull).  */
     430              : 
     431              : bool
     432            0 : can_duplicate_and_interleave_p (vec_info *vinfo, unsigned int count,
     433              :                                 tree elt_type, unsigned int *nvectors_out,
     434              :                                 tree *vector_type_out,
     435              :                                 tree *permutes)
     436              : {
     437            0 :   tree base_vector_type = get_vectype_for_scalar_type (vinfo, elt_type, count);
     438            0 :   if (!base_vector_type || !VECTOR_MODE_P (TYPE_MODE (base_vector_type)))
     439              :     return false;
     440              : 
     441            0 :   machine_mode base_vector_mode = TYPE_MODE (base_vector_type);
     442            0 :   poly_int64 elt_bytes = count * GET_MODE_UNIT_SIZE (base_vector_mode);
     443            0 :   unsigned int nvectors = 1;
     444            0 :   for (;;)
     445              :     {
     446            0 :       scalar_int_mode int_mode;
     447            0 :       poly_int64 elt_bits = elt_bytes * BITS_PER_UNIT;
     448            0 :       if (int_mode_for_size (elt_bits, 1).exists (&int_mode))
     449              :         {
     450              :           /* Get the natural vector type for this SLP group size.  */
     451            0 :           tree int_type = build_nonstandard_integer_type
     452            0 :             (GET_MODE_BITSIZE (int_mode), 1);
     453            0 :           tree vector_type
     454            0 :             = get_vectype_for_scalar_type (vinfo, int_type, count);
     455            0 :           poly_int64 half_nelts;
     456            0 :           if (vector_type
     457            0 :               && VECTOR_MODE_P (TYPE_MODE (vector_type))
     458            0 :               && known_eq (GET_MODE_SIZE (TYPE_MODE (vector_type)),
     459              :                            GET_MODE_SIZE (base_vector_mode))
     460            0 :               && multiple_p (GET_MODE_NUNITS (TYPE_MODE (vector_type)),
     461              :                              2, &half_nelts))
     462              :             {
     463              :               /* Try fusing consecutive sequences of COUNT / NVECTORS elements
     464              :                  together into elements of type INT_TYPE and using the result
     465              :                  to build NVECTORS vectors.  */
     466            0 :               poly_uint64 nelts = GET_MODE_NUNITS (TYPE_MODE (vector_type));
     467            0 :               vec_perm_builder sel1 (nelts, 2, 3);
     468            0 :               vec_perm_builder sel2 (nelts, 2, 3);
     469              : 
     470            0 :               for (unsigned int i = 0; i < 3; ++i)
     471              :                 {
     472            0 :                   sel1.quick_push (i);
     473            0 :                   sel1.quick_push (i + nelts);
     474            0 :                   sel2.quick_push (half_nelts + i);
     475            0 :                   sel2.quick_push (half_nelts + i + nelts);
     476              :                 }
     477            0 :               vec_perm_indices indices1 (sel1, 2, nelts);
     478            0 :               vec_perm_indices indices2 (sel2, 2, nelts);
     479            0 :               machine_mode vmode = TYPE_MODE (vector_type);
     480            0 :               if (can_vec_perm_const_p (vmode, vmode, indices1)
     481            0 :                   && can_vec_perm_const_p (vmode, vmode, indices2))
     482              :                 {
     483            0 :                   if (nvectors_out)
     484            0 :                     *nvectors_out = nvectors;
     485            0 :                   if (vector_type_out)
     486            0 :                     *vector_type_out = vector_type;
     487            0 :                   if (permutes)
     488              :                     {
     489            0 :                       permutes[0] = vect_gen_perm_mask_checked (vector_type,
     490              :                                                                 indices1);
     491            0 :                       permutes[1] = vect_gen_perm_mask_checked (vector_type,
     492              :                                                                 indices2);
     493              :                     }
     494            0 :                   return true;
     495              :                 }
     496            0 :             }
     497              :         }
     498            0 :       if (!multiple_p (elt_bytes, 2, &elt_bytes))
     499              :         return false;
     500            0 :       nvectors *= 2;
     501              :       /* We need to be able to fuse COUNT / NVECTORS elements together.  */
     502            0 :       if (!multiple_p (count, nvectors))
     503              :         return false;
     504              :     }
     505              : }
     506              : 
     507              : /* Return true if DTA and DTB match.  */
     508              : 
     509              : static bool
     510     17706985 : vect_def_types_match (enum vect_def_type dta, enum vect_def_type dtb)
     511              : {
     512     17706985 :   return (dta == dtb
     513       417686 :           || ((dta == vect_external_def || dta == vect_constant_def)
     514       268264 :               && (dtb == vect_external_def || dtb == vect_constant_def)));
     515              : }
     516              : 
     517              : #define GATHER_SCATTER_OFFSET (-3)
     518              : 
     519              : /* For most SLP statements, there is a one-to-one mapping between
     520              :    gimple arguments and child nodes.  If that is not true for STMT,
     521              :    return an array that contains:
     522              : 
     523              :    - the number of child nodes, followed by
     524              :    - for each child node, the index of the argument associated with that node.
     525              :      The special index -1 is the first operand of an embedded comparison and
     526              :      the special index -2 is the second operand of an embedded comparison.
     527              :      The special index -3 is the offset of a gather as analyzed by
     528              :      vect_check_gather_scatter.
     529              : 
     530              :    SWAP is as for vect_get_and_check_slp_defs.  */
     531              : 
     532              : static const int *
     533     25975970 : vect_get_operand_map (const gimple *stmt, bool gather_scatter_p,
     534              :                       unsigned char swap)
     535              : {
     536     25975970 :   static const int no_arg_map[] = { 0 };
     537     25975970 :   static const int arg0_map[] = { 1, 0 };
     538     25975970 :   static const int arg2_map[] = { 1, 2 };
     539     25975970 :   static const int arg2_arg3_map[] = { 2, 2, 3 };
     540     25975970 :   static const int arg2_arg4_map[] = { 2, 2, 4 };
     541     25975970 :   static const int arg2_arg5_arg6_map[] = { 3, 2, 5, 6 };
     542     25975970 :   static const int arg2_arg4_arg5_map[] = { 3, 2, 4, 5 };
     543     25975970 :   static const int arg3_arg2_map[] = { 2, 3, 2 };
     544     25975970 :   static const int op00_map[] = { 1, -1 };
     545     25975970 :   static const int op1_op0_map[] = { 2, 1, 0 };
     546     25975970 :   static const int off_map[] = { 1, GATHER_SCATTER_OFFSET };
     547     25975970 :   static const int off_op0_map[] = { 2, GATHER_SCATTER_OFFSET, 0 };
     548     25975970 :   static const int off_arg2_arg3_map[] = { 3, GATHER_SCATTER_OFFSET, 2, 3 };
     549     25975970 :   static const int off_arg3_arg2_map[] = { 3, GATHER_SCATTER_OFFSET, 3, 2 };
     550     25975970 :   static const int mask_call_maps[6][7] = {
     551              :         { 1, 1, },
     552              :         { 2, 1, 2, },
     553              :         { 3, 1, 2, 3, },
     554              :         { 4, 1, 2, 3, 4, },
     555              :         { 5, 1, 2, 3, 4, 5, },
     556              :         { 6, 1, 2, 3, 4, 5, 6 },
     557              :   };
     558              : 
     559     25975970 :   gcc_checking_assert (!swap
     560              :                        || !is_gimple_assign (stmt)
     561              :                        || TREE_CODE_CLASS
     562              :                             (gimple_assign_rhs_code (stmt)) == tcc_comparison
     563              :                        || commutative_tree_code
     564              :                             (gimple_assign_rhs_code (stmt)));
     565              : 
     566     25975970 :   if (auto assign = dyn_cast<const gassign *> (stmt))
     567              :     {
     568     24429721 :       tree_code code = gimple_assign_rhs_code (assign);
     569     24429721 :       if (code == COND_EXPR
     570     24429721 :           && COMPARISON_CLASS_P (gimple_assign_rhs1 (assign)))
     571            0 :         gcc_unreachable ();
     572     24429721 :       else if ((TREE_CODE_CLASS (code) == tcc_comparison
     573     22891631 :                 || commutative_tree_code (code))
     574     33571754 :                && swap)
     575              :         return op1_op0_map;
     576     24387621 :       else if (code == VIEW_CONVERT_EXPR)
     577              :         return op00_map;
     578     24378133 :       else if (gather_scatter_p)
     579        46969 :         return (TREE_CODE (gimple_assign_lhs (assign)) != SSA_NAME
     580        46969 :                 ? off_op0_map : off_map);
     581              :     }
     582      1546249 :   else if (auto call = dyn_cast<const gcall *> (stmt))
     583              :     {
     584       170818 :       if (gimple_call_internal_p (call))
     585        94123 :         switch (gimple_call_internal_fn (call))
     586              :           {
     587        13928 :           case IFN_MASK_LOAD:
     588        13928 :             return gather_scatter_p ? off_arg2_arg3_map : arg2_arg3_map;
     589              : 
     590            0 :           case IFN_GATHER_LOAD:
     591            0 :             return arg2_map;
     592              : 
     593            0 :           case IFN_MASK_GATHER_LOAD:
     594            0 :           case IFN_MASK_LEN_GATHER_LOAD:
     595            0 :             return arg2_arg5_arg6_map;
     596              : 
     597            0 :           case IFN_SCATTER_STORE:
     598            0 :             return arg2_arg4_map;
     599              : 
     600            0 :           case IFN_MASK_SCATTER_STORE:
     601            0 :           case IFN_MASK_LEN_SCATTER_STORE:
     602            0 :             return arg2_arg4_arg5_map;
     603              : 
     604         9200 :           case IFN_MASK_STORE:
     605         9200 :             return gather_scatter_p ? off_arg3_arg2_map : arg3_arg2_map;
     606              : 
     607          996 :           case IFN_MASK_CALL:
     608          996 :             {
     609          996 :               unsigned nargs = gimple_call_num_args (call);
     610          996 :               if (nargs >= 2 && nargs <= 7)
     611          996 :                 return mask_call_maps[nargs-2];
     612              :               else
     613              :                 return nullptr;
     614              :             }
     615              : 
     616          278 :           case IFN_CLZ:
     617          278 :           case IFN_CTZ:
     618          278 :             return arg0_map;
     619              : 
     620         7308 :           case IFN_GOMP_SIMD_LANE:
     621         7308 :             return no_arg_map;
     622              : 
     623              :           default:
     624              :             break;
     625              :           }
     626              :     }
     627              :   return nullptr;
     628              : }
     629              : 
     630              : static const int *
     631     25956921 : vect_get_operand_map (const stmt_vec_info stmt, unsigned char swap = 0)
     632              : {
     633            0 :   return vect_get_operand_map (stmt->stmt, STMT_VINFO_GATHER_SCATTER_P (stmt),
     634            0 :                                swap);
     635              : }
     636              : 
     637              : /* Return the SLP node child index for operand OP of STMT.  */
     638              : 
     639              : int
     640      1395573 : vect_slp_child_index_for_operand (const stmt_vec_info stmt, int op)
     641              : {
     642      1395573 :   const int *opmap = vect_get_operand_map (stmt);
     643      1395573 :   if (!opmap)
     644              :     return op;
     645        20323 :   for (int i = 1; i < 1 + opmap[0]; ++i)
     646        20323 :     if (opmap[i] == op)
     647        11561 :       return i - 1;
     648            0 :   gcc_unreachable ();
     649              : }
     650              : 
     651              : /* Helper class for mapping of GIMPLE operands to SLP children.  */
     652              : /* ???  Add vect_slp_child_index_for_operand here and amend opmaps
     653              :    with the full reverse mapping and indicating the position of the
     654              :    first commutative operand index, eliding the swap_p argument from
     655              :    vect_get_operand_map.  Adjust all consumers.  */
     656              : 
     657              : struct slp_oprnds {
     658              :   slp_oprnds (stmt_vec_info);
     659              :   tree get_op_for_slp_child (stmt_vec_info, unsigned);
     660              :   const int *opmap;
     661              :   const unsigned int num_slp_children;
     662              : };
     663              : 
     664      4645434 : slp_oprnds::slp_oprnds (stmt_vec_info stmt_info)
     665      4645434 :   : opmap (vect_get_operand_map (stmt_info)),
     666      4645434 :     num_slp_children (opmap ? opmap[0] : gimple_num_args (stmt_info->stmt))
     667              : {
     668      4645434 : }
     669              : 
     670              : /* For SLP child number N get the corresponding tree operand from GIMPLE
     671              :    statement described by STMT_INFO.  */
     672              : 
     673              : tree
     674      5183731 : slp_oprnds::get_op_for_slp_child (stmt_vec_info stmt_info, unsigned n)
     675              : {
     676      5183731 :   gcc_assert (n < num_slp_children);
     677      5183731 :   int opno = opmap ? opmap[n + 1] : (int) n;
     678      5183731 :   if (opno == GATHER_SCATTER_OFFSET)
     679            0 :     gcc_unreachable (); // TODO
     680      5183731 :   else if (opno < 0)
     681         2602 :     return TREE_OPERAND (gimple_arg (stmt_info->stmt, 0), -1 - opno);
     682              :   else
     683      5181129 :     return gimple_arg (stmt_info->stmt, opno);
     684              : }
     685              : 
     686              : /* Get the defs for the rhs of STMT (collect them in OPRNDS_INFO), check that
     687              :    they are of a valid type and that they match the defs of the first stmt of
     688              :    the SLP group (stored in OPRNDS_INFO).  This function tries to match stmts
     689              :    by swapping operands of STMTS[STMT_NUM] when possible.  Non-zero SWAP
     690              :    indicates swap is required for cond_expr stmts.  Specifically, SWAP
     691              :    is 1 if STMT is cond and operands of comparison need to be swapped;
     692              :    SWAP is 2 if STMT is cond and code of comparison needs to be inverted.
     693              : 
     694              :    If there was a fatal error return -1; if the error could be corrected by
     695              :    swapping operands of father node of this one, return 1; if everything is
     696              :    ok return 0.  */
     697              : static int
     698     13720414 : vect_get_and_check_slp_defs (vec_info *vinfo, tree vectype, unsigned char swap,
     699              :                              bool *skip_args,
     700              :                              vec<stmt_vec_info> stmts, unsigned stmt_num,
     701              :                              vec<slp_oprnd_info> *oprnds_info,
     702              :                              bool soft_fail)
     703              : {
     704     13720414 :   stmt_vec_info stmt_info = stmts[stmt_num];
     705     13720414 :   tree oprnd;
     706     13720414 :   unsigned int i, number_of_oprnds;
     707     13720414 :   enum vect_def_type dt = vect_uninitialized_def;
     708     13720414 :   slp_oprnd_info oprnd_info;
     709     13720414 :   gather_scatter_info gs_info;
     710     13720414 :   unsigned int gs_op = -1u;
     711     13720414 :   unsigned int commutative_op = -1U;
     712     13720414 :   bool first = stmt_num == 0;
     713              : 
     714     13720414 :   if (!stmt_info)
     715              :     {
     716            0 :       for (auto oi : *oprnds_info)
     717              :         {
     718            0 :           oi->def_stmts.quick_push (NULL);
     719            0 :           oi->ops.quick_push (NULL_TREE);
     720              :         }
     721              :       return 0;
     722              :     }
     723              : 
     724     13720414 :   if (!is_a<gcall *> (stmt_info->stmt)
     725              :       && !is_a<gassign *> (stmt_info->stmt)
     726              :       && !is_a<gphi *> (stmt_info->stmt))
     727              :     return -1;
     728              : 
     729     13720414 :   number_of_oprnds = gimple_num_args (stmt_info->stmt);
     730     13720414 :   const int *map = vect_get_operand_map (stmt_info, swap);
     731     13720414 :   if (map)
     732        79255 :     number_of_oprnds = *map++;
     733     13720414 :   if (gcall *stmt = dyn_cast <gcall *> (stmt_info->stmt))
     734              :     {
     735        54372 :       if (gimple_call_internal_p (stmt))
     736              :         {
     737        33903 :           internal_fn ifn = gimple_call_internal_fn (stmt);
     738        33903 :           commutative_op = first_commutative_argument (ifn);
     739        33903 :           if (internal_gather_scatter_fn_p (ifn))
     740              :             {
     741            0 :               vect_describe_gather_scatter_call
     742            0 :                 (stmt_info,
     743            0 :                  first ? &(*oprnds_info)[0]->first_gs_info : &gs_info);
     744            0 :               if (first)
     745            0 :                 (*oprnds_info)[0]->first_gs_p = true;
     746              :               gs_op = 0;
     747              :             }
     748              :         }
     749              :     }
     750     13666042 :   else if (gassign *stmt = dyn_cast <gassign *> (stmt_info->stmt))
     751              :     {
     752     16415904 :       if (commutative_tree_code (gimple_assign_rhs_code (stmt)))
     753      8539154 :         commutative_op = 0;
     754              :     }
     755              : 
     756     13720414 :   bool swapped = (swap != 0);
     757     13720414 :   bool backedge = false;
     758     13720414 :   enum vect_def_type *dts = XALLOCAVEC (enum vect_def_type, number_of_oprnds);
     759     37459204 :   for (i = 0; i < number_of_oprnds; i++)
     760              :     {
     761     23740153 :       oprnd_info = (*oprnds_info)[i];
     762     23740153 :       int opno = map ? map[i] : int (i);
     763     23740153 :       if (opno == GATHER_SCATTER_OFFSET)
     764              :         {
     765        23917 :           gcc_assert (STMT_VINFO_GATHER_SCATTER_P (stmt_info));
     766        23917 :           if (!is_a <loop_vec_info> (vinfo)
     767        23917 :               || !vect_check_gather_scatter (stmt_info, vectype,
     768              :                                              as_a <loop_vec_info> (vinfo),
     769              :                                              first ? &oprnd_info->first_gs_info
     770              :                                              : &gs_info))
     771         1363 :             return -1;
     772              : 
     773        23917 :           if (first)
     774              :             {
     775        23643 :               oprnd_info->first_gs_p = true;
     776        23643 :               oprnd = oprnd_info->first_gs_info.offset;
     777              :             }
     778              :           else
     779              :             {
     780          274 :               gs_op = i;
     781          274 :               oprnd = gs_info.offset;
     782              :             }
     783              :         }
     784     23716236 :       else if (opno < 0)
     785         3267 :         oprnd = TREE_OPERAND (gimple_arg (stmt_info->stmt, 0), -1 - opno);
     786              :       else
     787              :         {
     788     23712969 :           oprnd = gimple_arg (stmt_info->stmt, opno);
     789     23712969 :           if (gphi *stmt = dyn_cast <gphi *> (stmt_info->stmt))
     790              :             {
     791      1279705 :               edge e = gimple_phi_arg_edge (stmt, opno);
     792      2559410 :               backedge = (is_a <bb_vec_info> (vinfo)
     793      1982387 :                           ? e->flags & EDGE_DFS_BACK
     794       702682 :                           : dominated_by_p (CDI_DOMINATORS, e->src,
     795       702682 :                                             gimple_bb (stmt_info->stmt)));
     796              :             }
     797              :         }
     798              : 
     799     23740153 :       stmt_vec_info def_stmt_info;
     800     23740153 :       if (!vect_is_simple_use (oprnd, vinfo, &dts[i], &def_stmt_info))
     801              :         {
     802         1052 :           if (dump_enabled_p ())
     803            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     804              :                              "Build SLP failed: can't analyze def for %T\n",
     805              :                              oprnd);
     806              : 
     807              :           return -1;
     808              :         }
     809              : 
     810     23739101 :       if (skip_args[i])
     811              :         {
     812       565381 :           oprnd_info->def_stmts.quick_push (NULL);
     813       565381 :           oprnd_info->ops.quick_push (NULL_TREE);
     814       565381 :           oprnd_info->first_dt = vect_uninitialized_def;
     815       565381 :           continue;
     816              :         }
     817              : 
     818     23173720 :       oprnd_info->def_stmts.quick_push (def_stmt_info);
     819     23173720 :       oprnd_info->ops.quick_push (oprnd);
     820              : 
     821     23173720 :       if (def_stmt_info
     822     23173720 :           && is_pattern_stmt_p (def_stmt_info))
     823              :         {
     824       466552 :           if (STMT_VINFO_RELATED_STMT (vect_orig_stmt (def_stmt_info))
     825              :               != def_stmt_info)
     826       326451 :             oprnd_info->any_pattern = true;
     827              :           else
     828              :             /* If we promote this to external use the original stmt def.  */
     829       140101 :             oprnd_info->ops.last ()
     830       280202 :               = gimple_get_lhs (vect_orig_stmt (def_stmt_info)->stmt);
     831              :         }
     832              : 
     833              :       /* If there's a extern def on a backedge make sure we can
     834              :          code-generate at the region start.
     835              :          ???  This is another case that could be fixed by adjusting
     836              :          how we split the function but at the moment we'd have conflicting
     837              :          goals there.  */
     838     23173720 :       if (backedge
     839       175100 :           && dts[i] == vect_external_def
     840          332 :           && is_a <bb_vec_info> (vinfo)
     841          332 :           && TREE_CODE (oprnd) == SSA_NAME
     842          311 :           && !SSA_NAME_IS_DEFAULT_DEF (oprnd)
     843     23174031 :           && !dominated_by_p (CDI_DOMINATORS, vinfo->bbs[0],
     844          311 :                               gimple_bb (SSA_NAME_DEF_STMT (oprnd))))
     845              :         {
     846          311 :           if (dump_enabled_p ())
     847            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     848              :                              "Build SLP failed: extern def %T only defined "
     849              :                              "on backedge\n", oprnd);
     850              :           return -1;
     851              :         }
     852              : 
     853     23173409 :       if (first)
     854              :         {
     855      5299418 :           tree type = TREE_TYPE (oprnd);
     856      5299418 :           dt = dts[i];
     857              : 
     858              :           /* For the swapping logic below force vect_reduction_def
     859              :              for the reduction op in a SLP reduction group.  */
     860      5299418 :           if (!STMT_VINFO_DATA_REF (stmt_info)
     861      3983215 :               && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
     862         5312 :               && (int)i == STMT_VINFO_REDUC_IDX (stmt_info)
     863      5302031 :               && def_stmt_info)
     864         2613 :             dts[i] = dt = vect_reduction_def;
     865              : 
     866              :           /* Check the types of the definition.  */
     867      5299418 :           switch (dt)
     868              :             {
     869      5299418 :             case vect_external_def:
     870      5299418 :             case vect_constant_def:
     871      5299418 :             case vect_internal_def:
     872      5299418 :             case vect_reduction_def:
     873      5299418 :             case vect_double_reduction_def:
     874      5299418 :             case vect_induction_def:
     875      5299418 :             case vect_nested_cycle:
     876      5299418 :             case vect_first_order_recurrence:
     877      5299418 :               break;
     878              : 
     879            0 :             default:
     880              :               /* FORNOW: Not supported.  */
     881            0 :               if (dump_enabled_p ())
     882            0 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     883              :                                  "Build SLP failed: illegal type of def %T\n",
     884              :                                  oprnd);
     885              :               return -1;
     886              :             }
     887              : 
     888      5299418 :           oprnd_info->first_dt = dt;
     889      5299418 :           oprnd_info->first_op_type = type;
     890              :         }
     891              :     }
     892     13719051 :   if (first)
     893              :     return 0;
     894              : 
     895              :   /* Now match the operand definition types to that of the first stmt.  */
     896     27561682 :   for (i = 0; i < number_of_oprnds;)
     897              :     {
     898     17864043 :       if (skip_args[i])
     899              :         {
     900        44960 :           ++i;
     901        44960 :           continue;
     902              :         }
     903              : 
     904     17819083 :       oprnd_info = (*oprnds_info)[i];
     905     17819083 :       dt = dts[i];
     906     17819083 :       stmt_vec_info def_stmt_info = oprnd_info->def_stmts[stmt_num];
     907     17819083 :       oprnd = oprnd_info->ops[stmt_num];
     908     17819083 :       tree type = TREE_TYPE (oprnd);
     909              : 
     910     17819083 :       if (!types_compatible_p (oprnd_info->first_op_type, type))
     911              :         {
     912       119334 :           if (dump_enabled_p ())
     913           93 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     914              :                              "Build SLP failed: different operand types\n");
     915              :           return 1;
     916              :         }
     917              : 
     918     17699749 :       if ((gs_op == i) != oprnd_info->first_gs_p)
     919              :         {
     920            0 :           if (dump_enabled_p ())
     921            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     922              :                              "Build SLP failed: mixed gather and non-gather\n");
     923              :           return 1;
     924              :         }
     925     17699749 :       else if (gs_op == i)
     926              :         {
     927          242 :           if (!operand_equal_p (oprnd_info->first_gs_info.base,
     928          242 :                                 gs_info.base))
     929              :             {
     930           16 :               if (dump_enabled_p ())
     931            6 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     932              :                                  "Build SLP failed: different gather base\n");
     933              :               return 1;
     934              :             }
     935          226 :           if (oprnd_info->first_gs_info.scale != gs_info.scale)
     936              :             {
     937            8 :               if (dump_enabled_p ())
     938            2 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
     939              :                                  "Build SLP failed: different gather scale\n");
     940              :               return 1;
     941              :             }
     942              :         }
     943              : 
     944              :       /* Not first stmt of the group, check that the def-stmt/s match
     945              :          the def-stmt/s of the first stmt.  Allow different definition
     946              :          types for reduction chains: the first stmt must be a
     947              :          vect_reduction_def (a phi node), and the rest
     948              :          end in the reduction chain.  */
     949     17699725 :       if ((!vect_def_types_match (oprnd_info->first_dt, dt)
     950       334288 :            && !(oprnd_info->first_dt == vect_reduction_def
     951         5019 :                 && !STMT_VINFO_DATA_REF (stmt_info)
     952         5019 :                 && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
     953         4993 :                 && def_stmt_info
     954         4991 :                 && !STMT_VINFO_DATA_REF (def_stmt_info)
     955         4991 :                 && (REDUC_GROUP_FIRST_ELEMENT (def_stmt_info)
     956              :                     == REDUC_GROUP_FIRST_ELEMENT (stmt_info))))
     957     17370428 :           || (!STMT_VINFO_DATA_REF (stmt_info)
     958     15580856 :               && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
     959        10429 :               && ((!def_stmt_info
     960        10193 :                    || STMT_VINFO_DATA_REF (def_stmt_info)
     961        18668 :                    || (REDUC_GROUP_FIRST_ELEMENT (def_stmt_info)
     962              :                        != REDUC_GROUP_FIRST_ELEMENT (stmt_info)))
     963        10429 :                   != (oprnd_info->first_dt != vect_reduction_def))))
     964              :         {
     965              :           /* Try swapping operands if we got a mismatch.  For BB
     966              :              vectorization only in case it will clearly improve things.  */
     967       331932 :           if (i == commutative_op && !swapped
     968       329297 :               && (!is_a <bb_vec_info> (vinfo)
     969         5607 :                   || (!vect_def_types_match ((*oprnds_info)[i+1]->first_dt,
     970         5607 :                                              dts[i+1])
     971         1420 :                       && (vect_def_types_match (oprnd_info->first_dt, dts[i+1])
     972              :                           || vect_def_types_match
     973          233 :                                ((*oprnds_info)[i+1]->first_dt, dts[i])))))
     974              :             {
     975         2635 :               if (dump_enabled_p ())
     976          198 :                 dump_printf_loc (MSG_NOTE, vect_location,
     977              :                                  "trying swapped operands\n");
     978         2635 :               std::swap (dts[i], dts[i+1]);
     979         2635 :               std::swap ((*oprnds_info)[i]->def_stmts[stmt_num],
     980         2635 :                          (*oprnds_info)[i+1]->def_stmts[stmt_num]);
     981         2635 :               std::swap ((*oprnds_info)[i]->ops[stmt_num],
     982         2635 :                          (*oprnds_info)[i+1]->ops[stmt_num]);
     983              :               /* After swapping some operands we lost track whether an
     984              :                  operand has any pattern defs so be conservative here.  */
     985         2635 :               if ((*oprnds_info)[i]->any_pattern
     986         2635 :                   || (*oprnds_info)[i+1]->any_pattern)
     987           36 :                 (*oprnds_info)[i]->any_pattern
     988           18 :                   = (*oprnds_info)[i+1]->any_pattern = true;
     989         2635 :               swapped = true;
     990         2635 :               continue;
     991              :             }
     992              : 
     993       326662 :           if (is_a <bb_vec_info> (vinfo)
     994       309337 :               && !oprnd_info->any_pattern
     995       309069 :               && number_of_oprnds > 1
     996       635731 :               && !soft_fail)
     997              :             {
     998              :               /* Now for commutative ops we should see whether we can
     999              :                  make the other operand matching.  */
    1000       107223 :               if (dump_enabled_p ())
    1001          338 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1002              :                                  "treating operand as external\n");
    1003              :               oprnd_info->first_dt = dt = vect_external_def;
    1004              :             }
    1005              :           else
    1006              :             {
    1007       219439 :               if (dump_enabled_p ())
    1008          410 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1009              :                                  "Build SLP failed: different types\n");
    1010              :               return 1;
    1011              :             }
    1012              :         }
    1013              : 
    1014              :       /* Make sure to demote the overall operand to external.  */
    1015     17370428 :       if (dt == vect_external_def)
    1016       426444 :         oprnd_info->first_dt = vect_external_def;
    1017              :       /* For a SLP reduction chain we want to duplicate the reduction to
    1018              :          each of the chain members.  That gets us a sane SLP graph (still
    1019              :          the stmts are not 100% correct wrt the initial values).  */
    1020     17051207 :       else if ((dt == vect_internal_def
    1021     17051207 :                 || dt == vect_reduction_def)
    1022     15788112 :                && oprnd_info->first_dt == vect_reduction_def
    1023       101523 :                && !STMT_VINFO_DATA_REF (stmt_info)
    1024       101523 :                && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
    1025         4991 :                && !STMT_VINFO_DATA_REF (def_stmt_info)
    1026     17056198 :                && (REDUC_GROUP_FIRST_ELEMENT (def_stmt_info)
    1027              :                    == REDUC_GROUP_FIRST_ELEMENT (stmt_info)))
    1028              :         {
    1029         4991 :           oprnd_info->def_stmts[stmt_num] = oprnd_info->def_stmts[0];
    1030         4991 :           oprnd_info->ops[stmt_num] = oprnd_info->ops[0];
    1031              :         }
    1032              : 
    1033     17477651 :       ++i;
    1034              :     }
    1035              : 
    1036              :   /* Swap operands.  */
    1037      9697639 :   if (swapped)
    1038              :     {
    1039        41816 :       if (dump_enabled_p ())
    1040          502 :         dump_printf_loc (MSG_NOTE, vect_location,
    1041              :                          "swapped operands to match def types in %G",
    1042              :                          stmt_info->stmt);
    1043              :     }
    1044              : 
    1045              :   return 0;
    1046              : }
    1047              : 
    1048              : /* Return true if call statements CALL1 and CALL2 are similar enough
    1049              :    to be combined into the same SLP group.  */
    1050              : 
    1051              : bool
    1052        65587 : compatible_calls_p (gcall *call1, gcall *call2, bool allow_two_operators)
    1053              : {
    1054        65587 :   unsigned int nargs = gimple_call_num_args (call1);
    1055        65587 :   if (nargs != gimple_call_num_args (call2))
    1056              :     return false;
    1057              : 
    1058        48499 :   auto cfn1 = gimple_call_combined_fn (call1);
    1059        48499 :   auto cfn2 = gimple_call_combined_fn (call2);
    1060        48499 :   if (cfn1 != cfn2
    1061           39 :       && (!allow_two_operators
    1062           39 :           || !((cfn1 == CFN_FMA || cfn1 == CFN_FMS)
    1063            2 :                && (cfn2 == CFN_FMA || cfn2 == CFN_FMS))))
    1064              :     return false;
    1065              : 
    1066        48462 :   if (gimple_call_internal_p (call1))
    1067              :     {
    1068         7739 :       if (!types_compatible_p (TREE_TYPE (gimple_call_lhs (call1)),
    1069         7739 :                                TREE_TYPE (gimple_call_lhs (call2))))
    1070              :         return false;
    1071        16381 :       for (unsigned int i = 0; i < nargs; ++i)
    1072         8642 :         if (!types_compatible_p (TREE_TYPE (gimple_call_arg (call1, i)),
    1073         8642 :                                  TREE_TYPE (gimple_call_arg (call2, i))))
    1074              :           return false;
    1075              :     }
    1076              :   else
    1077              :     {
    1078        40723 :       if (!operand_equal_p (gimple_call_fn (call1),
    1079        40723 :                             gimple_call_fn (call2), 0))
    1080              :         return false;
    1081              : 
    1082        33930 :       if (gimple_call_fntype (call1) != gimple_call_fntype (call2))
    1083              :         return false;
    1084              :     }
    1085              : 
    1086              :   /* Check that any unvectorized arguments are equal.  */
    1087        19049 :   if (const int *map = vect_get_operand_map (call1, false, false))
    1088              :     {
    1089           15 :       unsigned int nkept = *map++;
    1090           15 :       unsigned int mapi = 0;
    1091           57 :       for (unsigned int i = 0; i < nargs; ++i)
    1092           42 :         if (mapi < nkept && map[mapi] == int (i))
    1093           27 :           mapi += 1;
    1094           15 :         else if (!operand_equal_p (gimple_call_arg (call1, i),
    1095           15 :                                    gimple_call_arg (call2, i)))
    1096              :           return false;
    1097              :     }
    1098              : 
    1099              :   return true;
    1100              : }
    1101              : 
    1102              : /* Verify if the scalar stmts STMTS are isomorphic, require data
    1103              :    permutation or are of unsupported types of operation.
    1104              :    Return false if at least one (or all in case of BB vectorization)
    1105              :    stmt is unvectorizable or the comparison could not be carried out.
    1106              :    Return true if they all (or at least one in case of BB vectorization)
    1107              :    are and indicate in MATCHES[] which stmts are not isomorphic to the
    1108              :    stmt at *START_I.
    1109              : 
    1110              :    This function is designed to be invoked repeatedly on the same
    1111              :    set of STMTS with increasing *START_I.
    1112              : 
    1113              :    When *START_I is zero and the function returns true MATCHES[] will be
    1114              :    initialized with, in case of BB vectorization, unvectorizable stmts
    1115              :    marked with -2, stmts isomorphic to *START_I as *START_I and
    1116              :    other vectorizable stmts with -1 (not isomorphic to *START_I).
    1117              :    *START_I, when initially zero, is updated to the first vectorizable
    1118              :    statement, so MATCHES[] can have a prefix with entries valued -2.
    1119              : 
    1120              :    When *START_I is not zero MATCHES[] is expected to be pre-initialized
    1121              :    by a former call with *START_I zero and MATCHES[*START_I] should be -1.
    1122              :    The function will return true and have the stmts isomorphic to
    1123              :    MATCHES[*START_I] marked with *START_I.
    1124              : 
    1125              :    *TWO_OPERATORS indicates whether the group of isomorphic statements
    1126              :    uses two related operations like PLUS_EXPR and MINUS_EXPR.  If
    1127              :    TWO_OPERATORS is NULL such case is not considered isomorphic.
    1128              : 
    1129              :    SWAP[] indicates whether for a stmt to be isomorphic to its group
    1130              :    leader, has to have its operands swapped (1) or its predicate inverted (2).
    1131              :    COND_EXPR is possibly isomorphic to another one after swapping its
    1132              :    operands.  Set SWAP[i] to 1 if stmt I is COND_EXPR and isomorphic to
    1133              :    the first stmt by swapping the two operands of comparison; set SWAP[i]
    1134              :    to 2 if stmt I is isormorphic to the first stmt by inverting the code
    1135              :    of comparison.  Take A1 >= B1 ? X1 : Y1 as an example, it can be swapped
    1136              :    to (B1 <= A1 ? X1 : Y1); or be inverted to (A1 < B1) ? Y1 : X1.  */
    1137              : 
    1138              : static bool
    1139      6319530 : vect_build_slp_tree_3 (vec_info *vinfo, vec<stmt_vec_info> stmts,
    1140              :                        match_elt_t *matches, unsigned char *swap,
    1141              :                        bool *two_operators, tree vectype, unsigned *start_i)
    1142              : {
    1143      6319530 :   stmt_vec_info first_stmt_info = NULL;
    1144      6319530 :   code_helper first_stmt_code = ERROR_MARK;
    1145      6319530 :   code_helper alt_stmt_code = ERROR_MARK;
    1146      6319530 :   code_helper first_cond_code = ERROR_MARK;
    1147      6319530 :   bool need_same_oprnds = false;
    1148      6319530 :   tree first_lhs = NULL_TREE;
    1149      6319530 :   tree first_op1 = NULL_TREE;
    1150      6319530 :   stmt_vec_info first_load = NULL, prev_first_load = NULL;
    1151      6319530 :   bool first_stmt_ldst_p = false, first_stmt_ldst_masklen_p = false;
    1152      6319530 :   bool first_stmt_phi_p = false;
    1153      6319530 :   int first_reduc_idx = -1;
    1154              : 
    1155      6319530 :   basic_block common_bb = NULL;
    1156      6319530 :   gimple *trapping_stmt = NULL;
    1157      6319530 :   int first_match = -1;
    1158              : 
    1159     26461482 :   for (unsigned i = *start_i; i < stmts.length (); ++i)
    1160              :     {
    1161     20142223 :       stmt_vec_info stmt_info = stmts[i];
    1162     20142223 :       bool ldst_p = false;
    1163     20142223 :       bool ldst_masklen_p = false;
    1164     20142223 :       bool phi_p = false;
    1165     20142223 :       code_helper rhs_code = ERROR_MARK;
    1166              : 
    1167     20142223 :       if (*start_i == 0)
    1168              :         {
    1169     18088950 :           swap[i] = 0;
    1170     18088950 :           matches[i] = -1;
    1171              :         }
    1172      2053273 :       else if (matches[i] != -1)
    1173     20141952 :         continue;
    1174              : 
    1175     20051649 :       if (!stmt_info)
    1176              :         {
    1177              :           /* ???  We shouldn't run into this.  */
    1178        40987 :           gcc_assert (first_match != -1);
    1179        40987 :           matches[i] = first_match;
    1180        40987 :           continue;
    1181              :         }
    1182              : 
    1183     20010662 :       gimple *stmt = stmt_info->stmt;
    1184     20010662 :       if (dump_enabled_p ())
    1185       241147 :         dump_printf_loc (MSG_NOTE, vect_location, "Build SLP for %G", stmt);
    1186              : 
    1187              :       /* Fail to vectorize statements marked as unvectorizable, throw
    1188              :          or are volatile.  */
    1189     20010662 :       if (!STMT_VINFO_VECTORIZABLE (stmt_info)
    1190     19623788 :           || stmt_can_throw_internal (cfun, stmt)
    1191     38621973 :           || gimple_has_volatile_ops (stmt))
    1192              :         {
    1193       404167 :           if (dump_enabled_p ())
    1194          466 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1195              :                              "Build SLP failed: unvectorizable statement %G",
    1196              :                              stmt);
    1197       404167 :           if (is_a <bb_vec_info> (vinfo))
    1198              :             {
    1199       404167 :               matches[i] = -2;
    1200       404167 :               continue;
    1201              :             }
    1202      6319530 :           return false;
    1203              :         }
    1204              : 
    1205     19606495 :       gcall *call_stmt = dyn_cast <gcall *> (stmt);
    1206     19606495 :       tree lhs = gimple_get_lhs (stmt);
    1207     19606495 :       if (lhs == NULL_TREE && !call_stmt)
    1208              :         {
    1209           34 :           if (dump_enabled_p ())
    1210            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1211              :                              "Build SLP failed: not GIMPLE_ASSIGN nor "
    1212              :                              "GIMPLE_CALL %G", stmt);
    1213           34 :           if (is_a <bb_vec_info> (vinfo))
    1214              :             {
    1215           34 :               matches[i] = -2;
    1216           34 :               continue;
    1217              :             }
    1218              :           return false;
    1219              :         }
    1220              : 
    1221     19606461 :       if (call_stmt)
    1222              :         {
    1223       205825 :           combined_fn cfn = gimple_call_combined_fn (call_stmt);
    1224       205825 :           if (cfn != CFN_LAST && cfn != CFN_MASK_CALL)
    1225        63799 :             rhs_code = cfn;
    1226              :           else
    1227              :             rhs_code = CALL_EXPR;
    1228              : 
    1229       205825 :           if (cfn == CFN_GATHER_LOAD
    1230       205825 :               || cfn == CFN_SCATTER_STORE)
    1231              :             ldst_p = true;
    1232              :           else if (cfn == CFN_MASK_LOAD
    1233              :                    || cfn == CFN_MASK_GATHER_LOAD
    1234              :                    || cfn == CFN_MASK_LEN_GATHER_LOAD
    1235              :                    || cfn == CFN_MASK_SCATTER_STORE
    1236              :                    || cfn == CFN_MASK_LEN_SCATTER_STORE)
    1237              :             {
    1238              :               ldst_p = true;
    1239              :               ldst_masklen_p = true;
    1240              :             }
    1241              :           else if (cfn == CFN_MASK_STORE)
    1242              :             {
    1243              :               ldst_p = true;
    1244              :               ldst_masklen_p = true;
    1245              :               rhs_code = CFN_MASK_STORE;
    1246              :             }
    1247              :           else if (cfn == CFN_GOMP_SIMD_LANE)
    1248              :             ;
    1249       194721 :           else if ((cfn != CFN_LAST
    1250              :                     && cfn != CFN_MASK_CALL
    1251        52695 :                     && internal_fn_p (cfn)
    1252        39990 :                     && !vectorizable_internal_fn_p (as_internal_fn (cfn)))
    1253       194610 :                    || gimple_call_tail_p (call_stmt)
    1254       194610 :                    || gimple_call_noreturn_p (call_stmt)
    1255       389331 :                    || gimple_call_chain (call_stmt))
    1256              :             {
    1257         1394 :               if (dump_enabled_p ())
    1258            8 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1259              :                                  "Build SLP failed: unsupported call type %G",
    1260              :                                  (gimple *) call_stmt);
    1261         1394 :               if (is_a <bb_vec_info> (vinfo))
    1262              :                 {
    1263         1394 :                   matches[i] = -2;
    1264         1394 :                   continue;
    1265              :                 }
    1266              :               return false;
    1267              :             }
    1268              :         }
    1269     19400636 :       else if (gimple_code (stmt) == GIMPLE_PHI)
    1270              :         {
    1271     19556992 :           rhs_code = ERROR_MARK;
    1272              :           phi_p = true;
    1273              :         }
    1274              :       else
    1275              :         {
    1276     18388159 :           rhs_code = gimple_assign_rhs_code (stmt);
    1277     18388159 :           ldst_p = STMT_VINFO_DATA_REF (stmt_info) != nullptr;
    1278              :         }
    1279              : 
    1280     18388159 :       if (!ldst_p
    1281              :           && !phi_p
    1282     13284899 :           && rhs_code.is_tree_code ()
    1283     13228661 :           && TREE_CODE_CLASS (tree_code (rhs_code)) != tcc_binary
    1284              :           && TREE_CODE_CLASS (tree_code (rhs_code)) != tcc_unary
    1285              :           && TREE_CODE_CLASS (tree_code (rhs_code)) != tcc_expression
    1286              :           && TREE_CODE_CLASS (tree_code (rhs_code)) != tcc_comparison
    1287       240296 :           && rhs_code != VIEW_CONVERT_EXPR
    1288              :           && rhs_code != CALL_EXPR
    1289              :           && rhs_code != BIT_FIELD_REF
    1290     18388159 :           && rhs_code != SSA_NAME)
    1291              :         {
    1292        48075 :           if (dump_enabled_p ())
    1293           98 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1294              :                              "Build SLP failed: operation unsupported %G",
    1295              :                              stmt);
    1296        48075 :           if (is_a <bb_vec_info> (vinfo))
    1297              :             {
    1298        47930 :               matches[i] = -2;
    1299        47930 :               continue;
    1300              :             }
    1301              :           return false;
    1302              :         }
    1303              : 
    1304              :       /* Non-grouped store or load.  */
    1305     19556992 :       if (ldst_p
    1306      5307691 :           && !STMT_VINFO_GROUPED_ACCESS (stmt_info)
    1307      1134127 :           && DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info))
    1308       856179 :           && rhs_code != CFN_GATHER_LOAD
    1309       856179 :           && rhs_code != CFN_MASK_GATHER_LOAD
    1310       856179 :           && rhs_code != CFN_MASK_LEN_GATHER_LOAD
    1311       856179 :           && rhs_code != CFN_SCATTER_STORE
    1312       856179 :           && rhs_code != CFN_MASK_SCATTER_STORE
    1313       856179 :           && rhs_code != CFN_MASK_LEN_SCATTER_STORE
    1314       856179 :           && !STMT_VINFO_GATHER_SCATTER_P (stmt_info)
    1315              :           /* Not grouped loads are handled as externals for BB
    1316              :              vectorization.  Treat them as not vectorizable.  */
    1317     20393441 :           && is_a <bb_vec_info> (vinfo))
    1318              :         {
    1319              :           /* Not grouped load.  */
    1320            0 :           if (dump_enabled_p ())
    1321            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1322              :                              "Build SLP failed: not grouped load %G", stmt);
    1323            0 :           matches[i] = -2;
    1324            0 :           continue;
    1325              :         }
    1326              : 
    1327     19556992 :       if (!ldst_p && rhs_code == BIT_FIELD_REF)
    1328              :         {
    1329        44767 :           tree vec = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
    1330        44767 :           if (!is_a <bb_vec_info> (vinfo)
    1331        44641 :               || TREE_CODE (vec) != SSA_NAME
    1332              :               /* When the element types are not compatible we pun the
    1333              :                  source to the target vectype which requires equal size.  */
    1334        89384 :               || ((!VECTOR_TYPE_P (TREE_TYPE (vec))
    1335        41883 :                    || !types_compatible_p (TREE_TYPE (vectype),
    1336        41883 :                                            TREE_TYPE (TREE_TYPE (vec))))
    1337         3997 :                   && !operand_equal_p (TYPE_SIZE (vectype),
    1338         3997 :                                        TYPE_SIZE (TREE_TYPE (vec)))))
    1339              :             {
    1340         2288 :               if (dump_enabled_p ())
    1341            0 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1342              :                                  "Build SLP failed: "
    1343              :                                  "BIT_FIELD_REF not supported\n");
    1344         2288 :               if (is_a <bb_vec_info> (vinfo))
    1345              :                 {
    1346         2162 :                   matches[i] = -2;
    1347         2162 :                   continue;
    1348              :                 }
    1349              :               return false;
    1350              :             }
    1351              :         }
    1352              : 
    1353              :       /* Check the operation.  */
    1354     19554704 :       if (first_match == -1)
    1355              :         {
    1356      6217878 :           first_match = i;
    1357      6217878 :           first_stmt_info = stmt_info;
    1358      6217878 :           common_bb = gimple_bb (stmt_info->stmt);
    1359      6217878 :           first_lhs = lhs;
    1360      6217878 :           first_stmt_code = rhs_code;
    1361      6217878 :           first_stmt_ldst_p = ldst_p;
    1362      6217878 :           first_stmt_ldst_masklen_p = ldst_masklen_p;
    1363      6217878 :           first_stmt_phi_p = phi_p;
    1364      6217878 :           first_reduc_idx = STMT_VINFO_REDUC_IDX (stmt_info);
    1365              : 
    1366              :           /* Shift arguments should be equal in all the packed stmts for a
    1367              :              vector shift with scalar shift operand.  */
    1368      6217878 :           if (rhs_code == LSHIFT_EXPR
    1369      6118623 :               || rhs_code == RSHIFT_EXPR
    1370      6025049 :               || rhs_code == LROTATE_EXPR
    1371     12242813 :               || rhs_code == RROTATE_EXPR)
    1372              :             {
    1373              :               /* First see if we have a vector/vector shift.  */
    1374       193428 :               if (!directly_supported_p (rhs_code, vectype, optab_vector))
    1375              :                 {
    1376              :                   /* No vector/vector shift, arrange for a vector/scalar
    1377              :                      SLP layout.  */
    1378       180035 :                   need_same_oprnds = true;
    1379       180035 :                   first_op1 = gimple_assign_rhs2 (stmt);
    1380              :                 }
    1381              :             }
    1382      6024450 :           else if (rhs_code == WIDEN_LSHIFT_EXPR)
    1383              :             {
    1384            0 :               need_same_oprnds = true;
    1385            0 :               first_op1 = gimple_assign_rhs2 (stmt);
    1386              :             }
    1387      6024450 :           else if (rhs_code == CFN_DIV_POW2)
    1388              :             {
    1389            0 :               need_same_oprnds = true;
    1390            0 :               first_op1 = gimple_call_arg (call_stmt, 1);
    1391              :             }
    1392      6024450 :           else if (rhs_code == CFN_GOMP_SIMD_LANE)
    1393              :             {
    1394         3654 :               need_same_oprnds = true;
    1395         3654 :               first_op1 = gimple_call_arg (call_stmt, 1);
    1396              :             }
    1397              :         }
    1398              :       else
    1399              :         {
    1400     13336826 :           int comm_arg;
    1401     13337265 :           if (first_reduc_idx != STMT_VINFO_REDUC_IDX (stmt_info)
    1402              :               /* For SLP reduction groups the index isn't necessarily
    1403              :                  uniform but only that of the first stmt matters.  */
    1404         2525 :               && !(first_reduc_idx != -1
    1405         2525 :                    && STMT_VINFO_REDUC_IDX (stmt_info) != -1
    1406         2525 :                    && REDUC_GROUP_FIRST_ELEMENT (stmt_info))
    1407     13336826 :               && !(first_reduc_idx != -1
    1408         1187 :                    && STMT_VINFO_REDUC_IDX (stmt_info) != -1
    1409         1187 :                    && (comm_arg = first_commutative_argument
    1410         1187 :                                     (rhs_code, TREE_TYPE (lhs))) >= 0
    1411              :                    && (first_reduc_idx
    1412          932 :                        == 2 * comm_arg + 1 - STMT_VINFO_REDUC_IDX (stmt_info))))
    1413              :             {
    1414          439 :               if (dump_enabled_p ())
    1415              :                 {
    1416           12 :                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1417              :                                    "Build SLP failed: different reduc_idx "
    1418              :                                    "%d instead of %d in %G",
    1419              :                                    STMT_VINFO_REDUC_IDX (stmt_info),
    1420              :                                    first_reduc_idx, stmt);
    1421              :                 }
    1422              :               /* Mismatch.  */
    1423          439 :               continue;
    1424              :             }
    1425     13336387 :           if (!ldst_p
    1426     13336387 :               && two_operators
    1427     10487017 :               && first_stmt_code != rhs_code
    1428     14857580 :               && alt_stmt_code == ERROR_MARK)
    1429              :             alt_stmt_code = rhs_code;
    1430     14838692 :           if ((!ldst_p
    1431     10487017 :                && first_stmt_code != rhs_code
    1432      1521193 :                && (first_stmt_code != IMAGPART_EXPR
    1433          202 :                    || rhs_code != REALPART_EXPR)
    1434      1521193 :                && (first_stmt_code != REALPART_EXPR
    1435          735 :                    || rhs_code != IMAGPART_EXPR)
    1436              :                /* Handle mismatches in plus/minus by computing both
    1437              :                   and merging the results.  */
    1438      1521193 :                && !((((first_stmt_code == PLUS_EXPR
    1439      1414053 :                        || first_stmt_code == MINUS_EXPR)
    1440       131429 :                       && (alt_stmt_code == PLUS_EXPR
    1441       121488 :                           || alt_stmt_code == MINUS_EXPR))
    1442      1489260 :                      || ((first_stmt_code == CFN_FMA
    1443      1489258 :                           || first_stmt_code == CFN_FMS)
    1444            2 :                          && (alt_stmt_code == CFN_FMA
    1445            2 :                              || alt_stmt_code == CFN_FMS)))
    1446        31935 :                     && rhs_code == alt_stmt_code)
    1447      1531116 :                && !(first_stmt_code.is_tree_code ()
    1448      1400068 :                     && rhs_code.is_tree_code ()
    1449      1285949 :                     && (TREE_CODE_CLASS (tree_code (first_stmt_code))
    1450              :                         == tcc_comparison)
    1451       140791 :                     && (swap_tree_comparison (tree_code (first_stmt_code))
    1452       140791 :                         == tree_code (rhs_code))
    1453              :                     && (first_reduc_idx == -1
    1454            0 :                         || REDUC_GROUP_FIRST_ELEMENT (stmt_info))))
    1455              :               || (ldst_p
    1456      5698740 :                   && (STMT_VINFO_GROUPED_ACCESS (stmt_info)
    1457      2849370 :                       != STMT_VINFO_GROUPED_ACCESS (first_stmt_info)))
    1458              :               || (ldst_p
    1459      2795692 :                   && (STMT_VINFO_GATHER_SCATTER_P (stmt_info)
    1460      2795692 :                       != STMT_VINFO_GATHER_SCATTER_P (first_stmt_info)))
    1461     11834220 :               || first_stmt_ldst_p != ldst_p
    1462     11834090 :               || (ldst_p && first_stmt_ldst_masklen_p != ldst_masklen_p)
    1463     25170469 :               || first_stmt_phi_p != phi_p)
    1464              :             {
    1465      1502305 :               if (dump_enabled_p ())
    1466              :                 {
    1467         3636 :                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1468              :                                    "Build SLP failed: different operation "
    1469              :                                    "in stmt %G", stmt);
    1470         3636 :                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1471              :                                    "original stmt %G", first_stmt_info->stmt);
    1472              :                 }
    1473              :               /* Mismatch.  */
    1474      1502305 :               continue;
    1475              :             }
    1476              : 
    1477     11853269 :           if (!ldst_p
    1478      9038543 :               && first_stmt_code == BIT_FIELD_REF
    1479     11863963 :               && (TREE_OPERAND (gimple_assign_rhs1 (first_stmt_info->stmt), 0)
    1480        29881 :                   != TREE_OPERAND (gimple_assign_rhs1 (stmt_info->stmt), 0)))
    1481              :             {
    1482        19187 :               if (dump_enabled_p ())
    1483          116 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1484              :                                  "Build SLP failed: different BIT_FIELD_REF "
    1485              :                                  "arguments in %G", stmt);
    1486              :               /* Mismatch.  */
    1487        19187 :               continue;
    1488              :             }
    1489              : 
    1490     11814895 :           if (call_stmt
    1491        88949 :               && first_stmt_code != CFN_MASK_LOAD
    1492     11903442 :               && first_stmt_code != CFN_MASK_STORE)
    1493              :             {
    1494        88236 :               if (!is_a <gcall *> (stmts[0]->stmt)
    1495        88236 :                   || !compatible_calls_p (as_a <gcall *> (stmts[0]->stmt),
    1496              :                                           call_stmt, true))
    1497              :                 {
    1498        69187 :                   if (dump_enabled_p ())
    1499           13 :                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1500              :                                      "Build SLP failed: different calls in %G",
    1501              :                                      stmt);
    1502              :                   /* Mismatch.  */
    1503        69187 :                   continue;
    1504              :                 }
    1505              :             }
    1506              : 
    1507     11788318 :           if (phi_p
    1508     11745708 :               && (gimple_bb (first_stmt_info->stmt)
    1509       213325 :                   != gimple_bb (stmt_info->stmt)))
    1510              :             {
    1511        42610 :               if (dump_enabled_p ())
    1512            8 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1513              :                                  "Build SLP failed: different BB for PHI %G",
    1514              :                                  stmt);
    1515              :               /* Mismatch.  */
    1516        42610 :               continue;
    1517              :             }
    1518              : 
    1519     11703098 :           if (need_same_oprnds)
    1520              :             {
    1521        64024 :               tree other_op1 = gimple_arg (stmt, 1);
    1522        64024 :               if (!operand_equal_p (first_op1, other_op1, 0))
    1523              :                 {
    1524        11397 :                   if (dump_enabled_p ())
    1525          195 :                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1526              :                                      "Build SLP failed: different shift "
    1527              :                                      "arguments in %G", stmt);
    1528              :                   /* Mismatch.  */
    1529        11397 :                   continue;
    1530              :                 }
    1531              :             }
    1532              : 
    1533     11692542 :           if (first_lhs
    1534     11691701 :               && lhs
    1535     11691701 :               && !types_compatible_p (TREE_TYPE (lhs), TREE_TYPE (first_lhs)))
    1536              :             {
    1537          841 :               if (dump_enabled_p ())
    1538            6 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1539              :                                  "Build SLP failed: different vector type "
    1540              :                                  "in %G", stmt);
    1541              :               /* Mismatch.  */
    1542          841 :               continue;
    1543              :             }
    1544              : 
    1545              :           /* We need to ensure all stmts are in the same BB when one stmt could
    1546              :              trap.  */
    1547     11690860 :           if (trapping_stmt || gimple_could_trap_p (stmt))
    1548              :             {
    1549      1175223 :               gcc_assert (!trapping_stmt || common_bb);
    1550      1175223 :               if (gimple_bb (stmt) != common_bb)
    1551              :                 {
    1552         6077 :                   if (dump_enabled_p ())
    1553           13 :                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1554              :                                      "Build SLP failed: not all stmts in same "
    1555              :                                      "BB but possibly trapping operation in %G",
    1556              :                                      trapping_stmt ? trapping_stmt : stmt);
    1557         6077 :                   continue;
    1558              :                 }
    1559              :             }
    1560              :         }
    1561              : 
    1562              :       /* Grouped store or load.  */
    1563     17902661 :       if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
    1564              :         {
    1565      4114447 :           gcc_assert (ldst_p);
    1566      4114447 :           if (DR_IS_WRITE (STMT_VINFO_DATA_REF (stmt_info)))
    1567              :             {
    1568              :               /* Store.  */
    1569      3031913 :               gcc_assert (rhs_code == CFN_MASK_STORE
    1570              :                           || REFERENCE_CLASS_P (lhs)
    1571              :                           || DECL_P (lhs));
    1572              :             }
    1573              :           else
    1574              :             {
    1575              :               /* Load.  */
    1576      1082534 :               first_load = DR_GROUP_FIRST_ELEMENT (stmt_info);
    1577      1082534 :               if (prev_first_load)
    1578              :                 {
    1579              :                   /* Check that there are no loads from different interleaving
    1580              :                      chains in the same node.  */
    1581       508141 :                   if (prev_first_load != first_load)
    1582              :                     {
    1583       106457 :                       if (dump_enabled_p ())
    1584         2296 :                         dump_printf_loc (MSG_MISSED_OPTIMIZATION,
    1585              :                                          vect_location,
    1586              :                                          "Build SLP failed: different "
    1587              :                                          "interleaving chains in one node %G",
    1588              :                                          stmt);
    1589              :                       /* Mismatch.  */
    1590       106457 :                       continue;
    1591              :                     }
    1592              :                 }
    1593              :               else
    1594              :                 prev_first_load = first_load;
    1595              :            }
    1596              :         }
    1597              :       /* Non-grouped store or load.  */
    1598     13788214 :       else if (ldst_p)
    1599              :         {
    1600      1133816 :           if (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info))
    1601       855868 :               && rhs_code != CFN_GATHER_LOAD
    1602              :               && rhs_code != CFN_MASK_GATHER_LOAD
    1603              :               && rhs_code != CFN_MASK_LEN_GATHER_LOAD
    1604              :               && rhs_code != CFN_SCATTER_STORE
    1605              :               && rhs_code != CFN_MASK_SCATTER_STORE
    1606              :               && rhs_code != CFN_MASK_LEN_SCATTER_STORE
    1607      1989684 :               && !STMT_VINFO_GATHER_SCATTER_P (stmt_info))
    1608              :             {
    1609       836157 :               gcc_assert (!is_a <bb_vec_info> (vinfo));
    1610              :               /* For loop vectorization we can handle splats the same we
    1611              :                  handle single element interleaving.  Likewise we can handle
    1612              :                  a collection of invariant refs.  */
    1613      1040356 :               if (stmt_info != first_stmt_info
    1614       836419 :                   && !(integer_zerop (DR_STEP (STMT_VINFO_DATA_REF (stmt_info)))
    1615          262 :                        && integer_zerop (DR_STEP (STMT_VINFO_DATA_REF
    1616              :                                                         (first_stmt_info)))))
    1617              :                 {
    1618              :                   /* Not grouped load.  */
    1619       204199 :                   if (dump_enabled_p ())
    1620          179 :                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1621              :                                      "Build SLP failed: not grouped load %G",
    1622              :                                      stmt);
    1623       204199 :                   continue;
    1624              :                 }
    1625              :             }
    1626              :         }
    1627              :       /* Not memory operation.  */
    1628              :       else
    1629              :         {
    1630     12654398 :           if (rhs_code == COND_EXPR)
    1631              :             {
    1632        71641 :               tree cond_expr = gimple_assign_rhs1 (stmt);
    1633        71641 :               enum tree_code cond_code = TREE_CODE (cond_expr);
    1634        71641 :               enum tree_code swap_code = ERROR_MARK;
    1635        71641 :               enum tree_code invert_code = ERROR_MARK;
    1636              : 
    1637        71641 :               if (i == (unsigned)first_match)
    1638        59406 :                 first_cond_code = TREE_CODE (cond_expr);
    1639        12235 :               else if (TREE_CODE_CLASS (cond_code) == tcc_comparison)
    1640              :                 {
    1641            0 :                   bool honor_nans = HONOR_NANS (TREE_OPERAND (cond_expr, 0));
    1642            0 :                   swap_code = swap_tree_comparison (cond_code);
    1643            0 :                   invert_code = invert_tree_comparison (cond_code, honor_nans);
    1644              :                 }
    1645              : 
    1646        71641 :               if (first_cond_code == cond_code)
    1647              :                 ;
    1648              :               /* Isomorphic can be achieved by swapping.  */
    1649            0 :               else if (first_cond_code == swap_code)
    1650            0 :                 swap[i] = 1;
    1651              :               /* Isomorphic can be achieved by inverting.  */
    1652            0 :               else if (first_cond_code == invert_code)
    1653            0 :                 swap[i] = 2;
    1654              :               else
    1655              :                 {
    1656            0 :                   if (dump_enabled_p ())
    1657            0 :                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1658              :                                      "Build SLP failed: different"
    1659              :                                      " operation %G", stmt);
    1660              :                   /* Mismatch.  */
    1661            0 :                   continue;
    1662              :                 }
    1663              :             }
    1664              : 
    1665     12654398 :           if (i != (unsigned) first_match
    1666      8894841 :               && first_stmt_code != rhs_code
    1667        72717 :               && first_stmt_code.is_tree_code ()
    1668        72715 :               && rhs_code.is_tree_code ()
    1669        72715 :               && TREE_CODE_CLASS ((tree_code)first_stmt_code) == tcc_comparison
    1670     12695721 :               && (swap_tree_comparison ((tree_code)first_stmt_code)
    1671        41323 :                   == (tree_code)rhs_code))
    1672        41323 :             swap[i] = 1;
    1673              : 
    1674     12654398 :           if (i != (unsigned) first_match
    1675      8894841 :               && first_reduc_idx != STMT_VINFO_REDUC_IDX (stmt_info)
    1676         1786 :               && first_reduc_idx != -1
    1677         1786 :               && STMT_VINFO_REDUC_IDX (stmt_info) != -1
    1678         1786 :               && rhs_code.is_tree_code ()
    1679         1778 :               && commutative_tree_code (tree_code (rhs_code))
    1680     12656174 :               && first_reduc_idx == 1 - STMT_VINFO_REDUC_IDX (stmt_info))
    1681         1776 :             swap[i] = 1;
    1682              :         }
    1683              : 
    1684              :       /* We need to ensure all stmts are in the same BB when one stmt could
    1685              :          trap.  Not matching stmts are not relevant, so exclude those.  */
    1686     17592005 :       if (!trapping_stmt && gimple_could_trap_p (stmt))
    1687              :         trapping_stmt = stmt;
    1688     17592005 :       if (common_bb != gimple_bb (stmt))
    1689              :         {
    1690        62701 :           common_bb = NULL;
    1691        62701 :           gcc_assert (!trapping_stmt);
    1692              :         }
    1693              : 
    1694     17592005 :       matches[i] = first_match;
    1695              :     }
    1696              : 
    1697              :   /* Record if we allowed two distinct operations for the SLP node.  */
    1698      6319259 :   if (((first_stmt_code == PLUS_EXPR
    1699      5798146 :         || first_stmt_code == MINUS_EXPR)
    1700       631591 :        && (alt_stmt_code == PLUS_EXPR
    1701       624293 :            || alt_stmt_code == MINUS_EXPR))
    1702     12621475 :       || ((first_stmt_code == CFN_FMA
    1703      6302167 :            || first_stmt_code == CFN_FMS)
    1704           49 :           && (alt_stmt_code == CFN_FMA
    1705           49 :               || alt_stmt_code == CFN_FMS)))
    1706        17045 :     *two_operators = true;
    1707              : 
    1708      6319259 :   if (first_match == -1)
    1709              :     {
    1710              :       /* If there was no useful stmt, fail.  Can only happen during
    1711              :          the first sweep.  */
    1712       101381 :       gcc_assert (*start_i == 0);
    1713       101381 :       *start_i = stmts.length () - 1;
    1714       101381 :       return false;
    1715              :     }
    1716              : 
    1717      6217878 :   *start_i = first_match;
    1718      6217878 :   return true;
    1719              : }
    1720              : 
    1721              : /* Verify if the scalar stmts STMTS are isomorphic, require data
    1722              :    permutation or are of unsupported types of operation.  Return
    1723              :    true if they are, otherwise return false and indicate in *MATCHES
    1724              :    the groups of isomorphic stmts.  See vect_build_slp_tree_3 for
    1725              :    details.  *TWO_OPERATORS is for the first isomorphic group,
    1726              :    knowledge whether following isomorphic groups have one or two operators
    1727              :    is not retained.  */
    1728              : 
    1729              : static bool
    1730      6191176 : vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
    1731              :                        vec<stmt_vec_info> stmts, match_elt_t *matches,
    1732              :                        bool *two_operators, tree *node_vectype)
    1733              : {
    1734      6191176 :   stmt_vec_info first_stmt_info = stmts[0];
    1735      6191176 :   unsigned int group_size = stmts.length ();
    1736      6191176 :   tree vectype;
    1737      6191176 :   if (!vect_get_vector_types_for_stmt (vinfo, first_stmt_info, &vectype,
    1738              :                                        group_size))
    1739              :     {
    1740              :       /* Fatal mismatch.  */
    1741       254985 :       matches[0] = -1;
    1742       254985 :       return false;
    1743              :     }
    1744      5936191 :   if (is_a <bb_vec_info> (vinfo)
    1745      5936191 :       && known_le (TYPE_VECTOR_SUBPARTS (vectype), 1U))
    1746              :     {
    1747       374827 :       if (dump_enabled_p ())
    1748          308 :         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1749              :                          "Build SLP failed: not using single lane "
    1750              :                          "vector type %T\n", vectype);
    1751       374827 :       matches[0] = -1;
    1752       374827 :       return false;
    1753              :     }
    1754              :   /* Check nunits required but continue analysis, producing matches[]
    1755              :      as if nunits was not an issue.  This allows splitting of groups
    1756              :      to happen.  */
    1757      5561364 :   unsigned HOST_WIDE_INT const_nunits = 0;
    1758      5561364 :   if (vectype
    1759      5561344 :       && is_a <bb_vec_info> (vinfo)
    1760     11122708 :       && !multiple_p (group_size, TYPE_VECTOR_SUBPARTS (vectype)))
    1761              :     {
    1762       211055 :       if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant (&const_nunits)
    1763       211055 :           || const_nunits > group_size)
    1764              :         {
    1765            0 :           if (dump_enabled_p ())
    1766            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    1767              :                              "Build SLP failed: unrolling required "
    1768              :                              "in basic block SLP\n");
    1769              :           /* Fatal mismatch.  */
    1770            0 :           matches[0] = -1;
    1771            0 :           return false;
    1772              :         }
    1773              :     }
    1774              : 
    1775      5561364 :   gcc_assert (vectype || !gimple_get_lhs (first_stmt_info->stmt));
    1776      5561364 :   *node_vectype = vectype;
    1777              : 
    1778      5561364 :   unsigned start_i = 0;
    1779      5561364 :   if (!vect_build_slp_tree_3 (vinfo, stmts, matches, swap, two_operators,
    1780              :                               vectype, &start_i))
    1781              :     {
    1782              :       /* Fatal mismatch.  */
    1783       101652 :       matches[0] = -1;
    1784       101652 :       return false;
    1785              :     }
    1786      5459712 :   gcc_assert (matches[start_i] == (int)start_i);
    1787              :   /* Discover further isomorphic groups.  */
    1788     17744535 :   for (start_i = start_i + 1; start_i < group_size; ++start_i)
    1789     12284823 :     if (matches[start_i] == -1)
    1790              :       {
    1791       758166 :         unsigned prev_start_i = start_i;
    1792       758166 :         bool tem_two_operators;
    1793       758166 :         bool res = vect_build_slp_tree_3 (vinfo, stmts, matches, swap,
    1794              :                                           &tem_two_operators,
    1795              :                                           vectype, &start_i);
    1796       758166 :         gcc_assert (res && matches[start_i] == (int)prev_start_i);
    1797              :       }
    1798              : 
    1799              :   bool res = true;
    1800     23280635 :   for (unsigned i = 0; i < group_size; ++i)
    1801     17820923 :     if (matches[i] != 0)
    1802      1898971 :       res = false;
    1803              :   if (!res)
    1804              :     return false;
    1805              : 
    1806              :   return true;
    1807              : }
    1808              : 
    1809              : /* Traits for the hash_set to record failed SLP builds for a stmt set.
    1810              :    Note we never remove apart from at destruction time so we do not
    1811              :    need a special value for deleted that differs from empty.  */
    1812              : struct bst_traits
    1813              : {
    1814              :   typedef vec <stmt_vec_info> value_type;
    1815              :   typedef vec <stmt_vec_info> compare_type;
    1816              :   static inline hashval_t hash (value_type);
    1817              :   static inline bool equal (value_type existing, value_type candidate);
    1818    512172108 :   static inline bool is_empty (value_type x) { return !x.exists (); }
    1819    114750460 :   static inline bool is_deleted (value_type x) { return !x.exists (); }
    1820              :   static const bool empty_zero_p = true;
    1821            0 :   static inline void mark_empty (value_type &x) { x.release (); }
    1822              :   static inline void mark_deleted (value_type &x) { x.release (); }
    1823      9857772 :   static inline void remove (value_type &x) { x.release (); }
    1824              : };
    1825              : inline hashval_t
    1826     99870420 : bst_traits::hash (value_type x)
    1827              : {
    1828     99870420 :   inchash::hash h;
    1829    440896781 :   for (unsigned i = 0; i < x.length (); ++i)
    1830    341026361 :     h.add_int (x[i] ? gimple_uid (x[i]->stmt) : -1);
    1831     99870420 :   return h.end ();
    1832              : }
    1833              : inline bool
    1834     87458235 : bst_traits::equal (value_type existing, value_type candidate)
    1835              : {
    1836    262374705 :   if (existing.length () != candidate.length ())
    1837              :     return false;
    1838     87900187 :   for (unsigned i = 0; i < existing.length (); ++i)
    1839     83307672 :     if (existing[i] != candidate[i])
    1840              :       return false;
    1841              :   return true;
    1842              : }
    1843              : 
    1844              : typedef hash_map <vec <stmt_vec_info>, slp_tree,
    1845              :                   simple_hashmap_traits <bst_traits, slp_tree> >
    1846              :   scalar_stmts_to_slp_tree_map_t;
    1847              : 
    1848              : /* Release BST_MAP.  */
    1849              : 
    1850              : static void
    1851      1924607 : release_scalar_stmts_to_slp_tree_map (scalar_stmts_to_slp_tree_map_t *bst_map)
    1852              : {
    1853              :   /* The map keeps a reference on SLP nodes built, release that.  */
    1854     11782379 :   for (scalar_stmts_to_slp_tree_map_t::iterator it = bst_map->begin ();
    1855     11782379 :        it != bst_map->end (); ++it)
    1856      9857772 :     if ((*it).second)
    1857      9857772 :       vect_free_slp_tree ((*it).second);
    1858      3849214 :   delete bst_map;
    1859      1924607 : }
    1860              : 
    1861              : /* ???  This was std::pair<std::pair<tree_code, vect_def_type>, tree>
    1862              :    but then vec::insert does memmove and that's not compatible with
    1863              :    std::pair.  */
    1864              : struct chain_op_t
    1865              : {
    1866      4389257 :   chain_op_t (tree_code code_, vect_def_type dt_, tree op_)
    1867      4389257 :       : code (code_), dt (dt_), op (op_) {}
    1868              :   tree_code code;
    1869              :   vect_def_type dt;
    1870              :   tree op;
    1871              : };
    1872              : 
    1873              : /* Comparator for sorting associatable chains.  */
    1874              : 
    1875              : static int
    1876     12876843 : dt_sort_cmp (const void *op1_, const void *op2_, void *)
    1877              : {
    1878     12876843 :   auto *op1 = (const chain_op_t *) op1_;
    1879     12876843 :   auto *op2 = (const chain_op_t *) op2_;
    1880     12876843 :   if (op1->dt != op2->dt)
    1881      2028559 :     return (int)op1->dt - (int)op2->dt;
    1882     10848284 :   return (int)op1->code - (int)op2->code;
    1883              : }
    1884              : 
    1885              : /* Linearize the associatable expression chain at START with the
    1886              :    associatable operation CODE (where PLUS_EXPR also allows MINUS_EXPR),
    1887              :    filling CHAIN with the result and using WORKLIST as intermediate storage.
    1888              :    CODE_STMT and ALT_CODE_STMT are filled with the first stmt using CODE
    1889              :    or MINUS_EXPR.  *CHAIN_STMTS if not NULL is filled with all computation
    1890              :    stmts, starting with START.  When ALLOW_ALT_CODE is false, do not
    1891              :    follow into MINUS_EXPR when building a PLUS chain (treat MINUS as leaf).  */
    1892              : 
    1893              : static void
    1894      1890517 : vect_slp_linearize_chain (vec_info *vinfo,
    1895              :                           vec<std::pair<tree_code, gimple *> > &worklist,
    1896              :                           vec<chain_op_t> &chain,
    1897              :                           enum tree_code code, gimple *start,
    1898              :                           gimple *&code_stmt, gimple *&alt_code_stmt,
    1899              :                           vec<gimple *> *chain_stmts,
    1900              :                           bool allow_alt_code = true)
    1901              : {
    1902              :   /* For each lane linearize the addition/subtraction (or other
    1903              :      uniform associatable operation) expression tree.  */
    1904      1890517 :   worklist.safe_push (std::make_pair (code, start));
    1905      4389257 :   while (!worklist.is_empty ())
    1906              :     {
    1907      2498740 :       auto entry = worklist.pop ();
    1908      2498740 :       gassign *stmt = as_a <gassign *> (entry.second);
    1909      2498740 :       enum tree_code in_code = entry.first;
    1910      4997480 :       enum tree_code this_code = gimple_assign_rhs_code (stmt);
    1911              :       /* Pick some stmts suitable for SLP_TREE_REPRESENTATIVE.  */
    1912      2498740 :       if (!code_stmt
    1913      2498740 :           && gimple_assign_rhs_code (stmt) == code)
    1914      1576853 :         code_stmt = stmt;
    1915       921887 :       else if (!alt_code_stmt
    1916       921887 :                && gimple_assign_rhs_code (stmt) == MINUS_EXPR)
    1917       370243 :         alt_code_stmt = stmt;
    1918      2498740 :       if (chain_stmts)
    1919      2417541 :         chain_stmts->safe_push (stmt);
    1920      7496220 :       for (unsigned opnum = 1; opnum <= 2; ++opnum)
    1921              :         {
    1922      4997480 :           tree op = gimple_op (stmt, opnum);
    1923      4997480 :           vect_def_type dt;
    1924      4997480 :           stmt_vec_info def_stmt_info;
    1925      4997480 :           bool res = vect_is_simple_use (op, vinfo, &dt, &def_stmt_info);
    1926      4997480 :           gcc_assert (res);
    1927      4997480 :           if (dt == vect_internal_def
    1928      4997480 :               && is_pattern_stmt_p (def_stmt_info))
    1929         9250 :             op = gimple_get_lhs (def_stmt_info->stmt);
    1930      4997480 :           gimple *use_stmt;
    1931      4997480 :           use_operand_p use_p;
    1932      4997480 :           if (dt == vect_internal_def
    1933      4545464 :               && single_imm_use (op, &use_p, &use_stmt)
    1934      2903967 :               && is_gimple_assign (def_stmt_info->stmt)
    1935      7706486 :               && (gimple_assign_rhs_code (def_stmt_info->stmt) == code
    1936      2101100 :                   || (allow_alt_code
    1937        57504 :                       && code == PLUS_EXPR
    1938        36441 :                       && (gimple_assign_rhs_code (def_stmt_info->stmt)
    1939              :                           == MINUS_EXPR))))
    1940              :             {
    1941       608223 :               tree_code op_def_code = this_code;
    1942       608223 :               if (op_def_code == MINUS_EXPR && opnum == 1)
    1943        54816 :                 op_def_code = PLUS_EXPR;
    1944       608223 :               if (in_code == MINUS_EXPR)
    1945          222 :                 op_def_code = op_def_code == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR;
    1946       608223 :               worklist.safe_push (std::make_pair (op_def_code,
    1947       608223 :                                                   def_stmt_info->stmt));
    1948              :             }
    1949              :           else
    1950              :             {
    1951      4389257 :               tree_code op_def_code = this_code;
    1952      4389257 :               if (op_def_code == MINUS_EXPR && opnum == 1)
    1953       315546 :                 op_def_code = PLUS_EXPR;
    1954      4389257 :               if (in_code == MINUS_EXPR)
    1955         4230 :                 op_def_code = op_def_code == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR;
    1956      4389257 :               chain.safe_push (chain_op_t (op_def_code, dt, op));
    1957              :             }
    1958              :         }
    1959              :     }
    1960      1890517 : }
    1961              : 
    1962              : /* Distance from the node currently being discovered to the closest upthread
    1963              :    commutative operation whose operand-zero discovery may still be fixed by
    1964              :    retrying with swapped operands, or -1U if there is none.  */
    1965              : 
    1966              : static unsigned least_upthread_swappable_op_distance = -1U;
    1967              : 
    1968              : static slp_tree
    1969              : vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
    1970              :                        vec<stmt_vec_info> stmts,
    1971              :                        match_elt_t *matches, unsigned *limit,
    1972              :                        unsigned *tree_size,
    1973              :                        scalar_stmts_to_slp_tree_map_t *bst_map);
    1974              : 
    1975              : static slp_tree
    1976      6701522 : vect_build_slp_tree (vec_info *vinfo,
    1977              :                      vec<stmt_vec_info> stmts,
    1978              :                      match_elt_t *matches, unsigned *limit, unsigned *tree_size,
    1979              :                      scalar_stmts_to_slp_tree_map_t *bst_map)
    1980              : {
    1981      6701522 :   unsigned int group_size = stmts.length ();
    1982      6701522 :   if (slp_tree *leader = bst_map->get (stmts))
    1983              :     {
    1984       504497 :       if (dump_enabled_p ())
    1985        18347 :         dump_printf_loc (MSG_NOTE, vect_location, "re-using %sSLP tree %p\n",
    1986        18347 :                          !(*leader)->failed ? "" : "failed ",
    1987              :                          (void *) *leader);
    1988       504497 :       if (!(*leader)->failed)
    1989              :         {
    1990       455835 :           SLP_TREE_REF_COUNT (*leader)++;
    1991       455835 :           stmts.release ();
    1992       455835 :           return *leader;
    1993              :         }
    1994        48662 :       memcpy (matches, (*leader)->failed, sizeof (match_elt_t) * group_size);
    1995        48662 :       return NULL;
    1996              :     }
    1997              : 
    1998              :   /* Single-lane SLP doesn't have the chance of run-away, do not account
    1999              :      it to the limit.  */
    2000      6197025 :   if (stmts.length () > 1)
    2001              :     {
    2002      3469363 :       if (*limit == 0)
    2003              :         {
    2004         1355 :           if (dump_enabled_p ())
    2005           15 :             dump_printf_loc (MSG_NOTE, vect_location,
    2006              :                              "SLP discovery limit exceeded\n");
    2007         1355 :           memset (matches, -1, sizeof (match_elt_t) * group_size);
    2008         1355 :           return NULL;
    2009              :         }
    2010      3468008 :       --*limit;
    2011              :     }
    2012              : 
    2013              :   /* Seed the bst_map with a stub node to be filled by vect_build_slp_tree_2
    2014              :      so we can pick up backedge destinations during discovery.  */
    2015      6195670 :   slp_tree res = new _slp_tree;
    2016      6195670 :   SLP_TREE_DEF_TYPE (res) = vect_internal_def;
    2017      6195670 :   SLP_TREE_SCALAR_STMTS (res) = stmts;
    2018      6195670 :   bst_map->put (stmts.copy (), res);
    2019              : 
    2020      6195670 :   if (dump_enabled_p ())
    2021       157017 :     dump_printf_loc (MSG_NOTE, vect_location,
    2022              :                      "starting SLP discovery for node %p\n", (void *) res);
    2023              : 
    2024      6195670 :   slp_tree res_ = vect_build_slp_tree_2 (vinfo, res, stmts,
    2025              :                                         matches, limit, tree_size, bst_map);
    2026      6195670 :   if (!res_)
    2027              :     {
    2028      2199736 :       if (dump_enabled_p ())
    2029         8217 :         dump_printf_loc (MSG_NOTE, vect_location,
    2030              :                          "SLP discovery for node %p failed\n", (void *) res);
    2031              :       /* Mark the node invalid so we can detect those when still in use
    2032              :          as backedge destinations.  */
    2033      2199736 :       SLP_TREE_SCALAR_STMTS (res) = vNULL;
    2034      2199736 :       SLP_TREE_DEF_TYPE (res) = vect_uninitialized_def;
    2035      2199736 :       res->failed = XNEWVEC (match_elt_t, group_size);
    2036      2199736 :       if (flag_checking)
    2037              :         {
    2038              :           unsigned i;
    2039      3871379 :           for (i = 0; i < group_size; ++i)
    2040      3871379 :             if (matches[i] != 0)
    2041              :               break;
    2042      2199736 :           gcc_assert (i < group_size);
    2043              :         }
    2044      2199736 :       memcpy (res->failed, matches, sizeof (match_elt_t) * group_size);
    2045              :     }
    2046              :   else
    2047              :     {
    2048      3995934 :       if (dump_enabled_p ())
    2049       148800 :         dump_printf_loc (MSG_NOTE, vect_location,
    2050              :                          "SLP discovery for node %p succeeded\n",
    2051              :                          (void *) res);
    2052      3995934 :       gcc_assert (res_ == res);
    2053              :       /* Keep a reference for the bst_map use.  */
    2054      3995934 :       SLP_TREE_REF_COUNT (res)++;
    2055              :       /* For BB vectorization nodes that need splitting should be failed.  */
    2056      3995934 :       gcc_assert (!is_a <bb_vec_info> (vinfo)
    2057              :                   || multiple_p (group_size,
    2058              :                                  TYPE_VECTOR_SUBPARTS (res->vectype)));
    2059              :     }
    2060              :   return res_;
    2061              : }
    2062              : 
    2063              : /* Helper for building an associated SLP node chain.  */
    2064              : 
    2065              : static void
    2066          162 : vect_slp_build_two_operator_nodes (slp_tree perm, tree vectype,
    2067              :                                    slp_tree op0, slp_tree op1,
    2068              :                                    stmt_vec_info oper1, stmt_vec_info oper2,
    2069              :                                    vec<std::pair<unsigned, unsigned> > lperm)
    2070              : {
    2071          162 :   unsigned group_size = SLP_TREE_LANES (op1);
    2072              : 
    2073          162 :   slp_tree child1 = new _slp_tree;
    2074          162 :   SLP_TREE_DEF_TYPE (child1) = vect_internal_def;
    2075          162 :   SLP_TREE_VECTYPE (child1) = vectype;
    2076          162 :   SLP_TREE_LANES (child1) = group_size;
    2077          162 :   SLP_TREE_CHILDREN (child1).create (2);
    2078          162 :   SLP_TREE_CHILDREN (child1).quick_push (op0);
    2079          162 :   SLP_TREE_CHILDREN (child1).quick_push (op1);
    2080          162 :   SLP_TREE_REPRESENTATIVE (child1) = oper1;
    2081              : 
    2082          162 :   slp_tree child2 = new _slp_tree;
    2083          162 :   SLP_TREE_DEF_TYPE (child2) = vect_internal_def;
    2084          162 :   SLP_TREE_VECTYPE (child2) = vectype;
    2085          162 :   SLP_TREE_LANES (child2) = group_size;
    2086          162 :   SLP_TREE_CHILDREN (child2).create (2);
    2087          162 :   SLP_TREE_CHILDREN (child2).quick_push (op0);
    2088          162 :   SLP_TREE_REF_COUNT (op0)++;
    2089          162 :   SLP_TREE_CHILDREN (child2).quick_push (op1);
    2090          162 :   SLP_TREE_REF_COUNT (op1)++;
    2091          162 :   SLP_TREE_REPRESENTATIVE (child2) = oper2;
    2092              : 
    2093          162 :   SLP_TREE_DEF_TYPE (perm) = vect_internal_def;
    2094          162 :   SLP_TREE_CODE (perm) = VEC_PERM_EXPR;
    2095          162 :   SLP_TREE_VECTYPE (perm) = vectype;
    2096          162 :   SLP_TREE_LANES (perm) = group_size;
    2097          162 :   SLP_TREE_REPRESENTATIVE (perm) = NULL;
    2098          162 :   SLP_TREE_LANE_PERMUTATION (perm) = lperm;
    2099          162 :   SLP_TREE_CHILDREN (perm).quick_push (child1);
    2100          162 :   SLP_TREE_CHILDREN (perm).quick_push (child2);
    2101          162 : }
    2102              : 
    2103              : /* For isomorphic matches[], indicate a splitting point according to
    2104              :    CONST_NUNITS.  */
    2105              : 
    2106              : static void
    2107       124417 : force_split_matches (match_elt_t *matches, unsigned group_size,
    2108              :                      unsigned const_nunits)
    2109              : {
    2110       124417 :   if (dump_enabled_p ())
    2111           54 :     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    2112              :                      "Build SLP failed: unrolling required "
    2113              :                      "in basic block SLP\n");
    2114              : 
    2115              :   /* With constant vector elements simulate a mismatch at the
    2116              :      point we need to split.  But indicate the tail is isomorphic.  */
    2117       124417 :   unsigned tail = group_size & (const_nunits - 1);
    2118       273790 :   for (unsigned i = group_size - tail; i < group_size; ++i)
    2119       149373 :     matches[i] = (int)(group_size - tail);
    2120       124417 : }
    2121              : 
    2122              : /* Recursively build an SLP tree starting from NODE.
    2123              :    Fail (and return a value not equal to zero) if def-stmts are not
    2124              :    isomorphic, require data permutation or are of unsupported types of
    2125              :    operation.  Otherwise, return 0.
    2126              :    The value returned is the depth in the SLP tree where a mismatch
    2127              :    was found.  */
    2128              : 
    2129              : static slp_tree
    2130      6195670 : vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
    2131              :                        vec<stmt_vec_info> stmts,
    2132              :                        match_elt_t *matches, unsigned *limit,
    2133              :                        unsigned *tree_size,
    2134              :                        scalar_stmts_to_slp_tree_map_t *bst_map)
    2135              : {
    2136      6195670 :   unsigned int group_size = stmts.length ();
    2137      6195670 :   unsigned nops, i, this_tree_size = 0;
    2138              : 
    2139      6195670 :   matches[0] = -1;
    2140              : 
    2141      6195670 :   stmt_vec_info stmt_info = stmts[0];
    2142      6195670 :   if (!is_a<gcall *> (stmt_info->stmt)
    2143              :       && !is_a<gassign *> (stmt_info->stmt)
    2144              :       && !is_a<gphi *> (stmt_info->stmt))
    2145              :     return NULL;
    2146              : 
    2147      6195500 :   nops = gimple_num_args (stmt_info->stmt);
    2148      6195500 :   if (const int *map = vect_get_operand_map (stmt_info))
    2149        36818 :     nops = map[0];
    2150              : 
    2151              :   /* If the SLP node is a PHI (induction or reduction), terminate
    2152              :      the recursion.  */
    2153      6195500 :   bool *skip_args = XALLOCAVEC (bool, nops);
    2154      6195500 :   memset (skip_args, 0, sizeof (bool) * nops);
    2155      6195500 :   if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
    2156      2926874 :     if (gphi *stmt = dyn_cast <gphi *> (stmt_info->stmt))
    2157              :       {
    2158       320375 :         tree scalar_type = TREE_TYPE (PHI_RESULT (stmt));
    2159       320375 :         tree vectype = get_vectype_for_scalar_type (vinfo, scalar_type,
    2160              :                                                     group_size);
    2161       320375 :         if (!vectype)
    2162              :           {
    2163         4318 :             if (dump_enabled_p ())
    2164            7 :               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    2165              :                                "Build SLP failed: unsupported data-type in %G\n",
    2166              :                                stmt_info->stmt);
    2167              :             return NULL;
    2168              :           }
    2169              : 
    2170       316057 :         vect_def_type def_type = STMT_VINFO_DEF_TYPE (stmt_info);
    2171       316057 :         if (def_type == vect_induction_def)
    2172              :           {
    2173              :             /* Induction PHIs are not cycles but walk the initial
    2174              :                value.  Only for inner loops through, for outer loops
    2175              :                we need to pick up the value from the actual PHIs
    2176              :                to more easily support peeling and epilogue vectorization.  */
    2177       207246 :             class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
    2178       207246 :             if (!nested_in_vect_loop_p (loop, stmt_info))
    2179       206414 :               skip_args[loop_preheader_edge (loop)->dest_idx] = true;
    2180              :             else
    2181              :               loop = loop->inner;
    2182       207246 :             skip_args[loop_latch_edge (loop)->dest_idx] = true;
    2183              :           }
    2184       108811 :         else if (def_type == vect_reduction_def
    2185              :                  || def_type == vect_double_reduction_def
    2186              :                  || def_type == vect_nested_cycle
    2187       108811 :                  || def_type == vect_first_order_recurrence)
    2188              :           {
    2189              :             /* Else def types have to match.  */
    2190              :             stmt_vec_info other_info;
    2191              :             bool all_same = true;
    2192       246175 :             FOR_EACH_VEC_ELT (stmts, i, other_info)
    2193              :               {
    2194       138652 :                 if (STMT_VINFO_DEF_TYPE (other_info) != def_type)
    2195      6195670 :                   return NULL;
    2196       138646 :                 if (other_info != stmt_info)
    2197        26269 :                   all_same = false;
    2198              :               }
    2199       107523 :             class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
    2200              :             /* Reduction initial values are not explicitly represented.  */
    2201       107523 :             if (def_type != vect_first_order_recurrence
    2202       107523 :                 && gimple_bb (stmt_info->stmt) == loop->header)
    2203       104345 :               skip_args[loop_preheader_edge (loop)->dest_idx] = true;
    2204              :             /* Reduction chain backedge defs are filled manually.
    2205              :                ???  Need a better way to identify a SLP reduction chain PHI.
    2206              :                Or a better overall way to SLP match those.  */
    2207       107523 :             if (stmts.length () > 1
    2208       107523 :                 && all_same && def_type == vect_reduction_def)
    2209         2416 :               skip_args[loop_latch_edge (loop)->dest_idx] = true;
    2210              :           }
    2211         1282 :         else if (def_type != vect_internal_def)
    2212              :           return NULL;
    2213              :       }
    2214              : 
    2215              : 
    2216      6191176 :   bool two_operators = false;
    2217      6191176 :   unsigned char *swap = XALLOCAVEC (unsigned char, group_size);
    2218      6191176 :   tree vectype = NULL_TREE;
    2219      6191176 :   if (!vect_build_slp_tree_1 (vinfo, swap, stmts, matches, &two_operators,
    2220              :                               &vectype))
    2221              :     return NULL;
    2222              : 
    2223      4623152 :   bool soft_fail
    2224      4623152 :     = (is_a <bb_vec_info> (vinfo)
    2225      4623152 :        && !multiple_p (group_size, TYPE_VECTOR_SUBPARTS (vectype)));
    2226              : 
    2227              :   /* If the SLP node is a load, terminate the recursion unless masked.  */
    2228      4623152 :   if (STMT_VINFO_DATA_REF (stmt_info)
    2229      2240165 :       && DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)))
    2230              :     {
    2231       958150 :       if (soft_fail)
    2232              :         {
    2233          962 :           force_split_matches (matches, group_size,
    2234          962 :                                TYPE_VECTOR_SUBPARTS (vectype).to_constant ());
    2235          962 :           return NULL;
    2236              :         }
    2237       957188 :       if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
    2238              :         gcc_assert (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)));
    2239              :       else
    2240              :         {
    2241       937770 :           (*tree_size)++;
    2242       937770 :           node = vect_create_new_slp_node (node, stmts, 0);
    2243       937770 :           SLP_TREE_VECTYPE (node) = vectype;
    2244              :           /* And compute the load permutation.  Whether it is actually
    2245              :              a permutation depends on the unrolling factor which is
    2246              :              decided later.  */
    2247       937770 :           vec<unsigned> load_permutation;
    2248       937770 :           int j;
    2249       937770 :           stmt_vec_info load_info;
    2250       937770 :           load_permutation.create (group_size);
    2251       937770 :           stmt_vec_info first_stmt_info
    2252       937770 :             = STMT_VINFO_GROUPED_ACCESS (stmt_info)
    2253       937770 :               ? DR_GROUP_FIRST_ELEMENT (stmt_info) : stmt_info;
    2254       937770 :           bool any_permute = false;
    2255      2269075 :           FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), j, load_info)
    2256              :             {
    2257      1331305 :               int load_place;
    2258      1331305 :               if (! load_info)
    2259              :                 {
    2260        40747 :                   if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
    2261              :                     load_place = j;
    2262              :                   else
    2263              :                     load_place = 0;
    2264              :                 }
    2265      1290558 :               else if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
    2266       754663 :                 load_place = vect_get_place_in_interleaving_chain
    2267       754663 :                     (load_info, first_stmt_info);
    2268              :               else
    2269              :                 /* Recognize the splat case as { 0, 0, ... } but make
    2270              :                    sure to use the appropriate refs for collections
    2271              :                    of invariant refs.  */
    2272       535895 :                 load_place = (load_info == stmt_info) ? 0 : j;
    2273       795663 :               gcc_assert (load_place != -1);
    2274      1331305 :               any_permute |= load_place != j;
    2275      1331305 :               load_permutation.quick_push (load_place);
    2276              :             }
    2277              : 
    2278       937770 :           if (gcall *stmt = dyn_cast <gcall *> (stmt_info->stmt))
    2279              :             {
    2280         3353 :               gcc_assert (gimple_call_internal_p (stmt, IFN_MASK_LOAD));
    2281         3353 :               bool has_gaps = false;
    2282         3353 :               if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
    2283          189 :                 for (stmt_vec_info si = DR_GROUP_NEXT_ELEMENT (first_stmt_info);
    2284          846 :                      si; si = DR_GROUP_NEXT_ELEMENT (si))
    2285          657 :                   if (DR_GROUP_GAP (si) != 1)
    2286           80 :                     has_gaps = true;
    2287              :               /* We cannot handle permuted masked loads directly, see
    2288              :                  PR114375.  We cannot handle strided masked loads or masked
    2289              :                  loads with gaps unless the mask is uniform.  */
    2290         3353 :               if ((STMT_VINFO_GROUPED_ACCESS (stmt_info)
    2291          189 :                    && (DR_GROUP_GAP (first_stmt_info) != 0
    2292          129 :                        || (has_gaps
    2293           35 :                            && STMT_VINFO_SLP_VECT_ONLY (first_stmt_info))))
    2294         6626 :                   || STMT_VINFO_STRIDED_P (stmt_info))
    2295              :                 {
    2296          108 :                   load_permutation.release ();
    2297          108 :                   matches[0] = -1;
    2298       934564 :                   return NULL;
    2299              :                 }
    2300              : 
    2301              :               /* For permuted masked loads do an unpermuted masked load of
    2302              :                  the whole group followed by a SLP permute node.  */
    2303         3245 :               if (any_permute
    2304         3245 :                   || (STMT_VINFO_GROUPED_ACCESS (stmt_info)
    2305           83 :                       && DR_GROUP_SIZE (first_stmt_info) != group_size))
    2306              :                 {
    2307              :                   /* Discover the whole unpermuted load.  */
    2308           39 :                   vec<stmt_vec_info> stmts2;
    2309           39 :                   unsigned dr_group_size = STMT_VINFO_GROUPED_ACCESS (stmt_info)
    2310           68 :                       ? DR_GROUP_SIZE (first_stmt_info) : 1;
    2311           39 :                   stmts2.create (dr_group_size);
    2312           39 :                   stmts2.quick_grow_cleared (dr_group_size);
    2313           39 :                   unsigned i = 0;
    2314           39 :                   for (stmt_vec_info si = first_stmt_info;
    2315          464 :                        si; si = DR_GROUP_NEXT_ELEMENT (si))
    2316              :                     {
    2317          425 :                       if (si != first_stmt_info)
    2318         1586 :                         for (unsigned k = 1; k < DR_GROUP_GAP (si); ++k)
    2319         1200 :                           stmts2[i++] = NULL;
    2320          425 :                       stmts2[i++] = si;
    2321              :                     }
    2322           39 :                   match_elt_t *matches2
    2323           39 :                     = XALLOCAVEC (match_elt_t, dr_group_size);
    2324           39 :                   slp_tree unperm_load
    2325           39 :                     = vect_build_slp_tree (vinfo, stmts2, matches2, limit,
    2326           39 :                                            &this_tree_size, bst_map);
    2327              :                   /* When we are able to do the full masked load emit that
    2328              :                      followed by 'node' being the desired final permutation.  */
    2329           39 :                   if (unperm_load)
    2330              :                     {
    2331           16 :                       gcc_assert
    2332              :                         (!SLP_TREE_LOAD_PERMUTATION (unperm_load).exists ());
    2333           16 :                       lane_permutation_t lperm;
    2334           16 :                       lperm.create (group_size);
    2335           72 :                       for (unsigned j = 0; j < load_permutation.length (); ++j)
    2336           40 :                         lperm.quick_push
    2337           40 :                           (std::make_pair (0, load_permutation[j]));
    2338           16 :                       SLP_TREE_CODE (node) = VEC_PERM_EXPR;
    2339           16 :                       SLP_TREE_CHILDREN (node).safe_push (unperm_load);
    2340           16 :                       SLP_TREE_LANE_PERMUTATION (node) = lperm;
    2341           16 :                       SLP_TREE_REPRESENTATIVE (node) = NULL;
    2342           16 :                       load_permutation.release ();
    2343           16 :                       return node;
    2344              :                     }
    2345           23 :                   stmts2.release ();
    2346           23 :                   load_permutation.release ();
    2347           23 :                   matches[0] = -1;
    2348           23 :                   return NULL;
    2349              :                 }
    2350         3206 :               load_permutation.release ();
    2351              :             }
    2352              :           else
    2353              :             {
    2354       934417 :               if (!any_permute
    2355       803803 :                   && STMT_VINFO_GROUPED_ACCESS (stmt_info)
    2356      1228526 :                   && group_size == DR_GROUP_SIZE (first_stmt_info))
    2357       129443 :                 load_permutation.release ();
    2358       934417 :               SLP_TREE_LOAD_PERMUTATION (node) = load_permutation;
    2359       934417 :               return node;
    2360              :             }
    2361              :         }
    2362              :     }
    2363      3665002 :   else if (gimple_assign_single_p (stmt_info->stmt)
    2364      2570978 :            && !gimple_vuse (stmt_info->stmt)
    2365      3674004 :            && gimple_assign_rhs_code (stmt_info->stmt) == BIT_FIELD_REF)
    2366              :     {
    2367         3335 :       if (soft_fail)
    2368              :         {
    2369           16 :           force_split_matches (matches, group_size,
    2370           16 :                                TYPE_VECTOR_SUBPARTS (vectype).to_constant ());
    2371           16 :           return NULL;
    2372              :         }
    2373              :       /* vect_build_slp_tree_2 determined all BIT_FIELD_REFs reference
    2374              :          the same SSA name vector of a compatible type to vectype.  */
    2375         3319 :       vec<std::pair<unsigned, unsigned> > lperm = vNULL;
    2376         3319 :       tree vec = TREE_OPERAND (gimple_assign_rhs1 (stmt_info->stmt), 0);
    2377         3319 :       stmt_vec_info estmt_info;
    2378        11547 :       FOR_EACH_VEC_ELT (stmts, i, estmt_info)
    2379              :         {
    2380         8375 :           gassign *estmt = as_a <gassign *> (estmt_info->stmt);
    2381         8375 :           tree bfref = gimple_assign_rhs1 (estmt);
    2382         8375 :           HOST_WIDE_INT lane;
    2383         8375 :           if (!known_eq (bit_field_size (bfref),
    2384              :                          tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (vectype))))
    2385        16603 :               || !constant_multiple_p (bit_field_offset (bfref),
    2386         8375 :                                        bit_field_size (bfref), &lane))
    2387              :             {
    2388          147 :               lperm.release ();
    2389          147 :               matches[0] = -1;
    2390          147 :               return NULL;
    2391              :             }
    2392         8228 :           lperm.safe_push (std::make_pair (0, (unsigned)lane));
    2393              :         }
    2394         3172 :       slp_tree vnode = vect_create_new_slp_node (vNULL);
    2395         3172 :       if (operand_equal_p (TYPE_SIZE (vectype), TYPE_SIZE (TREE_TYPE (vec))))
    2396              :         /* ???  We record vectype here but we hide eventually necessary
    2397              :            punning and instead rely on code generation to materialize
    2398              :            VIEW_CONVERT_EXPRs as necessary.  We instead should make
    2399              :            this explicit somehow.  */
    2400         1409 :         SLP_TREE_VECTYPE (vnode) = vectype;
    2401              :       else
    2402              :         {
    2403              :           /* For different size but compatible elements we can still
    2404              :              use VEC_PERM_EXPR without punning.  */
    2405         1763 :           gcc_assert (VECTOR_TYPE_P (TREE_TYPE (vec))
    2406              :                       && types_compatible_p (TREE_TYPE (vectype),
    2407              :                                              TREE_TYPE (TREE_TYPE (vec))));
    2408         1763 :           SLP_TREE_VECTYPE (vnode) = TREE_TYPE (vec);
    2409              :         }
    2410         3172 :       auto nunits = TYPE_VECTOR_SUBPARTS (SLP_TREE_VECTYPE (vnode));
    2411         3172 :       unsigned HOST_WIDE_INT const_nunits;
    2412         3172 :       if (nunits.is_constant (&const_nunits))
    2413         3172 :         SLP_TREE_LANES (vnode) = const_nunits;
    2414         3172 :       SLP_TREE_VEC_DEFS (vnode).safe_push (vec);
    2415              :       /* We are always building a permutation node even if it is an identity
    2416              :          permute to shield the rest of the vectorizer from the odd node
    2417              :          representing an actual vector without any scalar ops.
    2418              :          ???  We could hide it completely with making the permute node
    2419              :          external?  */
    2420         3172 :       node = vect_create_new_slp_node (node, stmts, 1);
    2421         3172 :       SLP_TREE_CODE (node) = VEC_PERM_EXPR;
    2422         3172 :       SLP_TREE_LANE_PERMUTATION (node) = lperm;
    2423         3172 :       SLP_TREE_VECTYPE (node) = vectype;
    2424         3172 :       SLP_TREE_CHILDREN (node).quick_push (vnode);
    2425         3172 :       SLP_TREE_REPRESENTATIVE (node) = NULL;
    2426         3172 :       return node;
    2427              :     }
    2428              :   /* When discovery reaches an associatable operation see whether we can
    2429              :      improve that to match up lanes in a way superior to the operand
    2430              :      swapping code which at most looks at two defs.
    2431              :      ???  For BB vectorization we cannot do the brute-force search
    2432              :      for matching as we can succeed by means of builds from scalars
    2433              :      and have no good way to "cost" one build against another.  */
    2434      3661667 :   else if (is_a <loop_vec_info> (vinfo)
    2435              :            /* Do not bother for single-lane SLP.  */
    2436      2080229 :            && group_size > 1
    2437              :            /* ???  We don't handle !vect_internal_def defs below.  */
    2438       114429 :            && STMT_VINFO_DEF_TYPE (stmt_info) == vect_internal_def
    2439              :            /* ???  Do not associate a reduction, this will wreck REDUC_IDX
    2440              :               mapping as long as that exists on the stmt_info level.  */
    2441        88745 :            && STMT_VINFO_REDUC_IDX (stmt_info) == -1
    2442        80118 :            && is_gimple_assign (stmt_info->stmt)
    2443        79793 :            && (associative_tree_code (gimple_assign_rhs_code (stmt_info->stmt))
    2444        52821 :                || gimple_assign_rhs_code (stmt_info->stmt) == MINUS_EXPR)
    2445      3690596 :            && ((FLOAT_TYPE_P (vectype) && flag_associative_math)
    2446        16662 :                || (INTEGRAL_TYPE_P (TREE_TYPE (vectype))
    2447        14123 :                    && TYPE_OVERFLOW_WRAPS (TREE_TYPE (vectype)))))
    2448              :     {
    2449              :       /* See if we have a chain of (mixed) adds or subtracts or other
    2450              :          associatable ops.  */
    2451        21756 :       enum tree_code code = gimple_assign_rhs_code (stmt_info->stmt);
    2452        21756 :       if (code == MINUS_EXPR)
    2453          842 :         code = PLUS_EXPR;
    2454        21756 :       stmt_vec_info other_op_stmt_info = NULL;
    2455        21756 :       stmt_vec_info op_stmt_info = NULL;
    2456        21756 :       unsigned chain_len = 0;
    2457        21756 :       auto_vec<chain_op_t> chain;
    2458        21756 :       auto_vec<std::pair<tree_code, gimple *> > worklist;
    2459        21756 :       auto_vec<vec<chain_op_t> > chains (group_size);
    2460        21756 :       auto_vec<slp_tree, 4> children;
    2461        21756 :       bool hard_fail = true;
    2462        22739 :       for (unsigned lane = 0; lane < group_size; ++lane)
    2463              :         {
    2464        22413 :           if (!stmts[lane])
    2465              :             {
    2466              :               /* ???  Below we require lane zero is present.  */
    2467            0 :               if (lane == 0)
    2468              :                 {
    2469              :                   hard_fail = false;
    2470        21430 :                   break;
    2471              :                 }
    2472            0 :               chains.quick_push (vNULL);
    2473            0 :               continue;
    2474              :             }
    2475              :           /* For each lane linearize the addition/subtraction (or other
    2476              :              uniform associatable operation) expression tree.  */
    2477        22413 :           gimple *op_stmt = NULL, *other_op_stmt = NULL;
    2478        22413 :           vect_slp_linearize_chain (vinfo, worklist, chain, code,
    2479        22413 :                                     stmts[lane]->stmt, op_stmt, other_op_stmt,
    2480              :                                     NULL);
    2481        22413 :           if (!op_stmt_info && op_stmt)
    2482        21105 :             op_stmt_info = vinfo->lookup_stmt (op_stmt);
    2483        22413 :           if (!other_op_stmt_info && other_op_stmt)
    2484          878 :             other_op_stmt_info = vinfo->lookup_stmt (other_op_stmt);
    2485        22413 :           if (chain.length () == 2)
    2486              :             {
    2487              :               /* In a chain of just two elements resort to the regular
    2488              :                  operand swapping scheme.  Likewise if we run into a
    2489              :                  length mismatch process regularly as well as we did not
    2490              :                  process the other lanes we cannot report a good hint what
    2491              :                  lanes to try swapping in the parent.  */
    2492              :               hard_fail = false;
    2493              :               break;
    2494              :             }
    2495          986 :           else if (chain_len == 0)
    2496          366 :             chain_len = chain.length ();
    2497         1240 :           else if (chain.length () != chain_len)
    2498              :             {
    2499              :               /* ???  Here we could slip in magic to compensate with
    2500              :                  neutral operands.  */
    2501            3 :               matches[lane] = -1;
    2502            3 :               if (lane != group_size - 1)
    2503            3 :                 matches[0] = -1;
    2504              :               break;
    2505              :             }
    2506          983 :           chains.quick_push (chain.copy ());
    2507          983 :           chain.truncate (0);
    2508              :         }
    2509        43512 :       if (chains.length () == group_size)
    2510              :         {
    2511              :           /* We cannot yet use SLP_TREE_CODE to communicate the operation.  */
    2512          326 :           if (!op_stmt_info)
    2513              :             {
    2514            3 :               hard_fail = false;
    2515            3 :               goto out;
    2516              :             }
    2517              :           /* Now we have a set of chains with the same length.  */
    2518              :           /* 1. pre-sort according to def_type and operation.  */
    2519         1194 :           for (unsigned lane = 0; lane < group_size; ++lane)
    2520         1742 :             chains[lane].stablesort (dt_sort_cmp, vinfo);
    2521          323 :           if (dump_enabled_p ())
    2522              :             {
    2523          155 :               dump_printf_loc (MSG_NOTE, vect_location,
    2524              :                                "pre-sorted chains of %s\n",
    2525              :                                get_tree_code_name (code));
    2526          655 :               for (unsigned lane = 0; lane < group_size; ++lane)
    2527              :                 {
    2528          500 :                   if (!stmts[lane])
    2529            0 :                     dump_printf (MSG_NOTE, "--");
    2530              :                   else
    2531         2250 :                     for (unsigned opnum = 0; opnum < chain_len; ++opnum)
    2532         3500 :                       dump_printf (MSG_NOTE, "%s %T ",
    2533         1750 :                                    get_tree_code_name (chains[lane][opnum].code),
    2534         1750 :                                    chains[lane][opnum].op);
    2535          500 :                   dump_printf (MSG_NOTE, "\n");
    2536              :                 }
    2537              :             }
    2538              :           /* 2. try to build children nodes, associating as necessary.  */
    2539              :           /* 2a. prepare and perform early checks to avoid eating into
    2540              :              discovery limit unnecessarily.  */
    2541          323 :           vect_def_type *dts = XALLOCAVEC (vect_def_type, chain_len);
    2542         1361 :           for (unsigned n = 0; n < chain_len; ++n)
    2543              :             {
    2544         1038 :               vect_def_type dt = chains[0][n].dt;
    2545         1038 :               unsigned lane;
    2546         3949 :               for (lane = 0; lane < group_size; ++lane)
    2547         5822 :                 if (stmts[lane] && chains[lane][n].dt != dt)
    2548              :                   {
    2549            0 :                     if (dt == vect_constant_def
    2550            0 :                         && chains[lane][n].dt == vect_external_def)
    2551              :                       dt = vect_external_def;
    2552            0 :                     else if (dt == vect_external_def
    2553            0 :                              && chains[lane][n].dt == vect_constant_def)
    2554              :                       ;
    2555              :                     else
    2556              :                       break;
    2557              :                   }
    2558         1038 :               if (lane != group_size)
    2559              :                 {
    2560            0 :                   if (dump_enabled_p ())
    2561            0 :                     dump_printf_loc (MSG_NOTE, vect_location,
    2562              :                                      "giving up on chain due to mismatched "
    2563              :                                      "def types\n");
    2564            0 :                   matches[lane] = -1;
    2565            0 :                   if (lane != group_size - 1)
    2566            0 :                     matches[0] = -1;
    2567            0 :                   goto out;
    2568              :                 }
    2569         1038 :               dts[n] = dt;
    2570         1038 :               if (dt == vect_constant_def
    2571         1038 :                   || dt == vect_external_def)
    2572              :                 {
    2573              :                   /* Check whether we can build the invariant.  If we can't
    2574              :                      we never will be able to.  */
    2575           77 :                   tree type = TREE_TYPE (chains[0][n].op);
    2576         1038 :                   if (!GET_MODE_SIZE (vinfo->vector_mode).is_constant ()
    2577              :                       && (TREE_CODE (type) == BOOLEAN_TYPE
    2578              :                           || !can_duplicate_and_interleave_p (vinfo, group_size,
    2579              :                                                               type)))
    2580              :                     {
    2581              :                       matches[0] = -1;
    2582              :                       goto out;
    2583              :                     }
    2584              :                 }
    2585          961 :               else if (dt != vect_internal_def)
    2586              :                 {
    2587              :                   /* Not sure, we might need sth special.
    2588              :                      gcc.dg/vect/pr96854.c,
    2589              :                      gfortran.dg/vect/fast-math-pr37021.f90
    2590              :                      and gfortran.dg/vect/pr61171.f trigger.  */
    2591              :                   /* Soft-fail for now.  */
    2592            0 :                   hard_fail = false;
    2593            0 :                   goto out;
    2594              :                 }
    2595              :             }
    2596              :           /* 2b. do the actual build.  */
    2597         1307 :           for (unsigned n = 0; n < chain_len; ++n)
    2598              :             {
    2599         1003 :               vect_def_type dt = dts[n];
    2600         1003 :               unsigned lane;
    2601         1003 :               if (dt == vect_constant_def
    2602         1003 :                   || dt == vect_external_def)
    2603              :                 {
    2604           77 :                   vec<tree> ops;
    2605           77 :                   ops.create (group_size);
    2606          397 :                   for (lane = 0; lane < group_size; ++lane)
    2607          243 :                     if (stmts[lane])
    2608          243 :                       ops.quick_push (chains[lane][n].op);
    2609              :                     else
    2610            0 :                       ops.quick_push (NULL_TREE);
    2611           77 :                   slp_tree child = vect_create_new_slp_node (ops);
    2612           77 :                   SLP_TREE_DEF_TYPE (child) = dt;
    2613           77 :                   children.safe_push (child);
    2614              :                 }
    2615              :               else
    2616              :                 {
    2617          926 :                   vec<stmt_vec_info> op_stmts;
    2618          926 :                   op_stmts.create (group_size);
    2619          926 :                   slp_tree child = NULL;
    2620              :                   /* Brute-force our way.  We have to consider a lane
    2621              :                      failing after fixing an earlier fail up in the
    2622              :                      SLP discovery recursion.  So track the current
    2623              :                      permute per lane.  */
    2624          926 :                   unsigned *perms = XALLOCAVEC (unsigned, group_size);
    2625          926 :                   memset (perms, 0, sizeof (unsigned) * group_size);
    2626         1022 :                   do
    2627              :                     {
    2628         1022 :                       op_stmts.truncate (0);
    2629         4900 :                       for (lane = 0; lane < group_size; ++lane)
    2630         2856 :                         if (stmts[lane])
    2631         2856 :                           op_stmts.quick_push
    2632         2856 :                             (vinfo->lookup_def (chains[lane][n].op));
    2633              :                         else
    2634            0 :                           op_stmts.quick_push (NULL);
    2635         1022 :                       child = vect_build_slp_tree (vinfo, op_stmts,
    2636              :                                                    matches, limit,
    2637              :                                                    &this_tree_size, bst_map);
    2638              :                       /* ???  We're likely getting too many fatal mismatches
    2639              :                          here so maybe we want to ignore them (but then we
    2640              :                          have no idea which lanes fatally mismatched).  */
    2641              :                       /* ???  Revisit this with matches[] improvements.  */
    2642         1022 :                       if (child || matches[0] != 0)
    2643              :                         break;
    2644              :                       /* Swap another lane we have not yet matched up into
    2645              :                          lanes that did not match.  If we run out of
    2646              :                          permute possibilities for a lane terminate the
    2647              :                          search.  */
    2648          291 :                       bool term = false;
    2649          291 :                       for (lane = 1; lane < group_size; ++lane)
    2650          195 :                         if (matches[lane] != 0)
    2651              :                           {
    2652          167 :                             if (n + perms[lane] + 1 == chain_len)
    2653              :                               {
    2654              :                                 term = true;
    2655              :                                 break;
    2656              :                               }
    2657          148 :                             if (dump_enabled_p ())
    2658          115 :                               dump_printf_loc (MSG_NOTE, vect_location,
    2659              :                                                "swapping operand %d and %d "
    2660              :                                                "of lane %d\n",
    2661              :                                                n, n + perms[lane] + 1, lane);
    2662          296 :                             std::swap (chains[lane][n],
    2663          148 :                                        chains[lane][n + perms[lane] + 1]);
    2664          148 :                             perms[lane]++;
    2665              :                           }
    2666          115 :                       if (term)
    2667              :                         break;
    2668              :                     }
    2669              :                   while (1);
    2670          926 :                   if (!child)
    2671              :                     {
    2672           19 :                       if (dump_enabled_p ())
    2673           18 :                         dump_printf_loc (MSG_NOTE, vect_location,
    2674              :                                          "failed to match up op %d\n", n);
    2675           19 :                       op_stmts.release ();
    2676           19 :                       if (lane != group_size - 1)
    2677            9 :                         matches[0] = -1;
    2678              :                       else
    2679           10 :                         matches[lane] = -1;
    2680           19 :                       goto out;
    2681              :                     }
    2682          907 :                   if (dump_enabled_p ())
    2683              :                     {
    2684          409 :                       dump_printf_loc (MSG_NOTE, vect_location,
    2685              :                                        "matched up op %d to\n", n);
    2686          409 :                       vect_print_slp_tree (MSG_NOTE, vect_location, child);
    2687              :                     }
    2688          907 :                   children.safe_push (child);
    2689              :                 }
    2690              :             }
    2691              :           /* 3. build SLP nodes to combine the chain.  */
    2692         1102 :           for (unsigned lane = 0; lane < group_size; ++lane)
    2693         1608 :             if (stmts[lane] && chains[lane][0].code != code)
    2694              :               {
    2695              :                 /* See if there's any alternate all-PLUS entry.  */
    2696              :                 unsigned n;
    2697            6 :                 for (n = 1; n < chain_len; ++n)
    2698              :                   {
    2699           30 :                     for (lane = 0; lane < group_size; ++lane)
    2700           48 :                       if (stmts[lane] && chains[lane][n].code != code)
    2701              :                         break;
    2702            6 :                     if (lane == group_size)
    2703              :                       break;
    2704              :                   }
    2705            6 :                 if (n != chain_len)
    2706              :                   {
    2707              :                     /* Swap that in at first position.  */
    2708            6 :                     std::swap (children[0], children[n]);
    2709           30 :                     for (lane = 0; lane < group_size; ++lane)
    2710           24 :                       if (stmts[lane])
    2711           24 :                         std::swap (chains[lane][0], chains[lane][n]);
    2712              :                   }
    2713              :                 else
    2714              :                   {
    2715              :                     /* ???  When this triggers and we end up with two
    2716              :                        vect_constant/external_def up-front things break (ICE)
    2717              :                        spectacularly finding an insertion place for the
    2718              :                        all-constant op.  We should have a fully
    2719              :                        vect_internal_def operand though(?) so we can swap
    2720              :                        that into first place and then prepend the all-zero
    2721              :                        constant.  */
    2722            0 :                     if (dump_enabled_p ())
    2723            0 :                       dump_printf_loc (MSG_NOTE, vect_location,
    2724              :                                        "inserting constant zero to compensate "
    2725              :                                        "for (partially) negated first "
    2726              :                                        "operand\n");
    2727            0 :                     chain_len++;
    2728            0 :                     for (lane = 0; lane < group_size; ++lane)
    2729            0 :                       if (stmts[lane])
    2730            0 :                         chains[lane].safe_insert
    2731            0 :                           (0, chain_op_t (code, vect_constant_def, NULL_TREE));
    2732            0 :                     vec<tree> zero_ops;
    2733            0 :                     zero_ops.create (group_size);
    2734            0 :                     zero_ops.quick_push (build_zero_cst (TREE_TYPE (vectype)));
    2735            0 :                     for (lane = 1; lane < group_size; ++lane)
    2736            0 :                       if (stmts[lane])
    2737            0 :                         zero_ops.quick_push (zero_ops[0]);
    2738              :                       else
    2739            0 :                         zero_ops.quick_push (NULL_TREE);
    2740            0 :                     slp_tree zero = vect_create_new_slp_node (zero_ops);
    2741            0 :                     SLP_TREE_DEF_TYPE (zero) = vect_constant_def;
    2742            0 :                     children.safe_insert (0, zero);
    2743              :                   }
    2744              :                 break;
    2745              :               }
    2746          979 :           for (unsigned i = 1; i < children.length (); ++i)
    2747              :             {
    2748          675 :               slp_tree op0 = children[i - 1];
    2749          675 :               slp_tree op1 = children[i];
    2750          675 :               bool this_two_op = false;
    2751         2391 :               for (unsigned lane = 0; lane < group_size; ++lane)
    2752         3756 :                 if (stmts[lane] && chains[lane][i].code != chains[0][i].code)
    2753              :                   {
    2754              :                     this_two_op = true;
    2755              :                     break;
    2756              :                   }
    2757          675 :               slp_tree child;
    2758          675 :               if (i == children.length () - 1)
    2759          304 :                 child = vect_create_new_slp_node (node, stmts, 2);
    2760              :               else
    2761          371 :                 child = vect_create_new_slp_node (2, ERROR_MARK);
    2762          675 :               if (this_two_op)
    2763              :                 {
    2764          162 :                   vec<std::pair<unsigned, unsigned> > lperm;
    2765          162 :                   lperm.create (group_size);
    2766          744 :                   for (unsigned lane = 0; lane < group_size; ++lane)
    2767          840 :                     lperm.quick_push (std::make_pair
    2768          420 :                       (chains[lane][i].code != chains[0][i].code, lane));
    2769          324 :                   vect_slp_build_two_operator_nodes (child, vectype, op0, op1,
    2770          162 :                                                      (chains[0][i].code == code
    2771              :                                                       ? op_stmt_info
    2772              :                                                       : other_op_stmt_info),
    2773          162 :                                                      (chains[0][i].code == code
    2774              :                                                       ? other_op_stmt_info
    2775              :                                                       : op_stmt_info),
    2776              :                                                      lperm);
    2777              :                 }
    2778              :               else
    2779              :                 {
    2780          513 :                   SLP_TREE_DEF_TYPE (child) = vect_internal_def;
    2781          513 :                   SLP_TREE_VECTYPE (child) = vectype;
    2782          513 :                   SLP_TREE_LANES (child) = group_size;
    2783          513 :                   SLP_TREE_CHILDREN (child).quick_push (op0);
    2784          513 :                   SLP_TREE_CHILDREN (child).quick_push (op1);
    2785          513 :                   SLP_TREE_REPRESENTATIVE (child)
    2786         1026 :                     = (chains[0][i].code == code
    2787          513 :                        ? op_stmt_info : other_op_stmt_info);
    2788              :                 }
    2789          675 :               children[i] = child;
    2790              :             }
    2791          304 :           *tree_size += this_tree_size + 1;
    2792         1452 :           while (!chains.is_empty ())
    2793          822 :             chains.pop ().release ();
    2794              :           return node;
    2795              :         }
    2796        21430 : out:
    2797        21452 :       if (dump_enabled_p ())
    2798         2825 :         dump_printf_loc (MSG_NOTE, vect_location,
    2799              :                          "failed to line up SLP graph by re-associating "
    2800              :                          "operations in lanes%s\n",
    2801              :                          !hard_fail ? " trying regular discovery" : "");
    2802        21457 :       while (!children.is_empty ())
    2803            5 :         vect_free_slp_tree (children.pop ());
    2804        21613 :       while (!chains.is_empty ())
    2805          161 :         chains.pop ().release ();
    2806              :       /* Hard-fail, otherwise we might run into quadratic processing of the
    2807              :          chains starting one stmt into the chain again.  */
    2808        21452 :       if (hard_fail)
    2809              :         return NULL;
    2810              :       /* Fall thru to normal processing.  */
    2811        21756 :     }
    2812              : 
    2813              :   /* Get at the operands, verifying they are compatible.  */
    2814      3683965 :   vec<slp_oprnd_info> oprnds_info = vect_create_oprnd_info (nops, group_size);
    2815      3683965 :   slp_oprnd_info oprnd_info;
    2816     21086981 :   FOR_EACH_VEC_ELT (stmts, i, stmt_info)
    2817              :     {
    2818     27440828 :       int res = vect_get_and_check_slp_defs (vinfo, vectype,
    2819     13720414 :                                              swap[i], skip_args,
    2820              :                                              stmts, i, &oprnds_info,
    2821              :                                              soft_fail);
    2822     13720414 :       if (res != 0)
    2823              :         /* ???  This puts -1 back into matches[] and the cache.  */
    2824       340160 :         matches[(res == -1) ? 0 : i] = -1;
    2825     13720414 :       if (matches[0] == -1)
    2826              :         break;
    2827              :     }
    2828     17010640 :   for (i = 0; i < group_size; ++i)
    2829     13576716 :     if (matches[i] != 0)
    2830              :       {
    2831       250041 :         vect_free_oprnd_info (oprnds_info);
    2832       250041 :         return NULL;
    2833              :       }
    2834      3433924 :   swap = NULL;
    2835              : 
    2836              :   /* Perform delayed soft-failing only here so we can factor in mismatches
    2837              :      determined by vect_get_and_check_slp_defs.  */
    2838      3433924 :   if (soft_fail)
    2839              :     {
    2840       123439 :       force_split_matches (matches, group_size,
    2841       123439 :                            TYPE_VECTOR_SUBPARTS (vectype).to_constant ());
    2842       123439 :       return NULL;
    2843              :     }
    2844              : 
    2845      3310485 :   bool has_two_operators_perm = false;
    2846     16552425 :   auto_vec<unsigned> two_op_perm_indices[2];
    2847      3310485 :   vec<stmt_vec_info> two_op_scalar_stmts[2] = {vNULL, vNULL};
    2848              : 
    2849      3326715 :   if (two_operators && oprnds_info.length () == 2 && group_size > 2)
    2850              :     {
    2851         4020 :       unsigned idx = 0;
    2852         4020 :       hash_map<gimple *, unsigned> seen;
    2853         4020 :       vec<slp_oprnd_info> new_oprnds_info
    2854         4020 :         = vect_create_oprnd_info (1, group_size);
    2855         4020 :       bool success = true;
    2856              : 
    2857         4020 :       enum tree_code code = ERROR_MARK;
    2858         4020 :       if (oprnds_info[0]->def_stmts[0]
    2859         4020 :           && is_a<gassign *> (oprnds_info[0]->def_stmts[0]->stmt))
    2860         3960 :         code = gimple_assign_rhs_code (oprnds_info[0]->def_stmts[0]->stmt);
    2861         4020 :       basic_block bb = nullptr;
    2862              : 
    2863         7722 :       for (unsigned j = 0; j < group_size; ++j)
    2864              :         {
    2865        18008 :           FOR_EACH_VEC_ELT (oprnds_info, i, oprnd_info)
    2866              :             {
    2867        14306 :               stmt_vec_info stmt_info = oprnd_info->def_stmts[j];
    2868        14306 :               if (!stmt_info
    2869        14139 :                   || !is_a<gassign *> (stmt_info->stmt)
    2870        14139 :                   || gimple_assign_rhs_code (stmt_info->stmt) != code
    2871        25075 :                   || skip_args[i])
    2872              :                 {
    2873              :                   success = false;
    2874         3541 :                   break;
    2875              :                 }
    2876              :               /* Avoid mixing lanes with defs in different basic-blocks.  */
    2877        10769 :               if (!bb)
    2878         4180 :                 bb = gimple_bb (vect_orig_stmt (stmt_info)->stmt);
    2879         8547 :               else if (gimple_bb (vect_orig_stmt (stmt_info)->stmt) != bb)
    2880              :                 {
    2881              :                   success = false;
    2882              :                   break;
    2883              :                 }
    2884              : 
    2885        10765 :               bool exists;
    2886        10765 :               unsigned &stmt_idx
    2887        10765 :                 = seen.get_or_insert (stmt_info->stmt, &exists);
    2888              : 
    2889        10765 :               if (!exists)
    2890              :                 {
    2891         9384 :                   new_oprnds_info[0]->def_stmts.safe_push (stmt_info);
    2892         9384 :                   new_oprnds_info[0]->ops.safe_push (oprnd_info->ops[j]);
    2893         9384 :                   stmt_idx = idx;
    2894         9384 :                   idx++;
    2895              :                 }
    2896              : 
    2897        10765 :               two_op_perm_indices[i].safe_push (stmt_idx);
    2898              :             }
    2899              : 
    2900         7243 :           if (!success)
    2901              :             break;
    2902              :         }
    2903              : 
    2904         4020 :       if (success && idx == group_size)
    2905              :         {
    2906           98 :           if (dump_enabled_p ())
    2907              :             {
    2908            0 :               dump_printf_loc (MSG_NOTE, vect_location,
    2909              :                                "Replace two_operators operands:\n");
    2910              : 
    2911            0 :               FOR_EACH_VEC_ELT (oprnds_info, i, oprnd_info)
    2912              :                 {
    2913            0 :                   dump_printf_loc (MSG_NOTE, vect_location,
    2914              :                                    "Operand %u:\n", i);
    2915            0 :                   for (unsigned j = 0; j < group_size; j++)
    2916            0 :                     dump_printf_loc (MSG_NOTE, vect_location, "\tstmt %u %G",
    2917            0 :                                      j, oprnd_info->def_stmts[j]->stmt);
    2918              :                 }
    2919              : 
    2920            0 :               dump_printf_loc (MSG_NOTE, vect_location,
    2921              :                                "With a single operand:\n");
    2922            0 :               for (unsigned j = 0; j < group_size; j++)
    2923            0 :                 dump_printf_loc (MSG_NOTE, vect_location, "\tstmt %u %G",
    2924            0 :                                  j, new_oprnds_info[0]->def_stmts[j]->stmt);
    2925              :             }
    2926              : 
    2927           98 :           two_op_scalar_stmts[0].safe_splice (oprnds_info[0]->def_stmts);
    2928           98 :           two_op_scalar_stmts[1].safe_splice (oprnds_info[1]->def_stmts);
    2929              : 
    2930           98 :           new_oprnds_info[0]->first_op_type = oprnds_info[0]->first_op_type;
    2931           98 :           new_oprnds_info[0]->first_dt = oprnds_info[0]->first_dt;
    2932           98 :           new_oprnds_info[0]->any_pattern = oprnds_info[0]->any_pattern;
    2933           98 :           new_oprnds_info[0]->first_gs_p = oprnds_info[0]->first_gs_p;
    2934           98 :           new_oprnds_info[0]->first_gs_info = oprnds_info[0]->first_gs_info;
    2935              : 
    2936           98 :           vect_free_oprnd_info (oprnds_info);
    2937           98 :           oprnds_info = new_oprnds_info;
    2938           98 :           nops = 1;
    2939           98 :           has_two_operators_perm = true;
    2940              :         }
    2941              :       else
    2942         3922 :         vect_free_oprnd_info (new_oprnds_info);
    2943         4020 :     }
    2944              : 
    2945      6620970 :   auto_vec<slp_tree, 4> children;
    2946              : 
    2947      3310485 :   stmt_info = stmts[0];
    2948              : 
    2949      3310485 :   int reduc_idx = -1;
    2950      3310485 :   int gs_scale = 0;
    2951      3310485 :   tree gs_base = NULL_TREE;
    2952              : 
    2953              :   /* Create SLP_TREE nodes for the definition node/s.  */
    2954      8519652 :   FOR_EACH_VEC_ELT (oprnds_info, i, oprnd_info)
    2955              :     {
    2956      5321669 :       slp_tree child = nullptr;
    2957      5321669 :       unsigned int j;
    2958      5321669 :       unsigned old_swap_distance;
    2959      5321669 :       bool can_swap;
    2960      5321669 :       bool can_swap_nonmatching;
    2961      5321669 :       bool *stmt_can_swap;
    2962              : 
    2963              :       /* We're skipping certain operands from processing, for example
    2964              :          outer loop reduction initial defs.  */
    2965      5321669 :       if (skip_args[i])
    2966              :         {
    2967       520421 :           children.safe_push (NULL);
    2968      5209167 :           continue;
    2969              :         }
    2970              : 
    2971      4801248 :       if (oprnd_info->first_dt == vect_uninitialized_def)
    2972              :         {
    2973              :           /* COND_EXPR have one too many eventually if the condition
    2974              :              is a SSA name.  */
    2975            0 :           gcc_assert (i == 3 && nops == 4);
    2976            0 :           continue;
    2977              :         }
    2978              : 
    2979      4801248 :       if (oprnd_info->first_gs_p)
    2980              :         {
    2981        23593 :           gs_scale = oprnd_info->first_gs_info.scale;
    2982        23593 :           gs_base = oprnd_info->first_gs_info.base;
    2983              :         }
    2984              : 
    2985      4801248 :       if (is_a <bb_vec_info> (vinfo)
    2986      1703515 :           && oprnd_info->first_dt == vect_internal_def
    2987      5711093 :           && !oprnd_info->any_pattern)
    2988              :         {
    2989              :           /* For BB vectorization, if all defs are the same do not
    2990              :              bother to continue the build along the single-lane
    2991              :              graph but use a splat of the scalar value.  */
    2992       857345 :           stmt_vec_info first_def = oprnd_info->def_stmts[0];
    2993       923914 :           for (j = 1; j < group_size; ++j)
    2994       873220 :             if (oprnd_info->def_stmts[j] != first_def)
    2995              :               break;
    2996       857345 :           if (j == group_size
    2997              :               /* But avoid doing this for loads where we may be
    2998              :                  able to CSE things, unless the stmt is not
    2999              :                  vectorizable.  */
    3000       857345 :               && (!STMT_VINFO_VECTORIZABLE (first_def)
    3001        60924 :                   || !gimple_vuse (first_def->stmt)))
    3002              :             {
    3003        40899 :               if (dump_enabled_p ())
    3004          125 :                 dump_printf_loc (MSG_NOTE, vect_location,
    3005              :                                  "Using a splat of the uniform operand %G",
    3006              :                                  first_def->stmt);
    3007        40899 :               oprnd_info->first_dt = vect_external_def;
    3008              :             }
    3009              :         }
    3010              : 
    3011      4801248 :       if (oprnd_info->first_dt == vect_external_def
    3012      4801248 :           || oprnd_info->first_dt == vect_constant_def)
    3013              :         {
    3014      1584509 :           if (!GET_MODE_SIZE (vinfo->vector_mode).is_constant ())
    3015              :             {
    3016              :               tree op0;
    3017              :               tree uniform_val = op0 = oprnd_info->ops[0];
    3018              :               for (j = 1; j < oprnd_info->ops.length (); ++j)
    3019              :                 if (oprnd_info->ops[j]
    3020              :                     && !operand_equal_p (uniform_val, oprnd_info->ops[j]))
    3021              :                   {
    3022              :                     uniform_val = NULL_TREE;
    3023              :                     break;
    3024              :                   }
    3025              :               if (!uniform_val
    3026              :                   && !can_duplicate_and_interleave_p (vinfo,
    3027              :                                                       oprnd_info->ops.length (),
    3028              :                                                       TREE_TYPE (op0)))
    3029              :                 {
    3030              :                   matches[j] = -1;
    3031              :                   if (dump_enabled_p ())
    3032              :                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    3033              :                                      "Build SLP failed: invalid type of def "
    3034              :                                      "for variable-length SLP %T\n", op0);
    3035              :                   goto fail;
    3036              :                 }
    3037              :             }
    3038      1584509 :           slp_tree invnode = vect_create_new_slp_node (oprnd_info->ops);
    3039      1584509 :           SLP_TREE_DEF_TYPE (invnode) = oprnd_info->first_dt;
    3040      1584509 :           oprnd_info->ops = vNULL;
    3041      1584509 :           children.safe_push (invnode);
    3042      1584509 :           continue;
    3043      1584509 :         }
    3044              : 
    3045              :       /* See which SLP operand a reduction chain continues on.  We want
    3046              :          to chain even PHIs but not backedges.  */
    3047      3216739 :       if (STMT_VINFO_REDUC_DEF (oprnd_info->def_stmts[0])
    3048      3216739 :           || STMT_VINFO_REDUC_IDX (oprnd_info->def_stmts[0]) != -1)
    3049              :         {
    3050       239027 :           if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle)
    3051              :             {
    3052          776 :               if (oprnd_info->first_dt == vect_double_reduction_def)
    3053          388 :                 reduc_idx = i;
    3054              :             }
    3055       238251 :           else if (is_a <gphi *> (stmt_info->stmt)
    3056       238251 :                    && gimple_phi_num_args
    3057       102322 :                         (as_a <gphi *> (stmt_info->stmt)) != 1)
    3058              :             ;
    3059       136322 :           else if (STMT_VINFO_REDUC_IDX (stmt_info) == -1
    3060          393 :                    && STMT_VINFO_DEF_TYPE (stmt_info) != vect_double_reduction_def)
    3061              :             ;
    3062       136322 :           else if (reduc_idx == -1)
    3063       127830 :             reduc_idx = i;
    3064              :           else
    3065              :             /* For .COND_* reduction operations the else value can be the
    3066              :                same as one of the operation operands.  The other def
    3067              :                stmts have been moved, so we can't check easily.  Check
    3068              :                it's a call at least.  */
    3069         8492 :             gcc_assert (is_a <gcall *> (stmt_info->stmt));
    3070              :         }
    3071              : 
    3072              :       /* When we have a masked load with uniform mask discover this
    3073              :          as a single-lane mask with a splat permute.  This way we can
    3074              :          recognize this as a masked load-lane by stripping the splat.  */
    3075      3216739 :       if (is_a <gcall *> (STMT_VINFO_STMT (stmt_info))
    3076        58084 :           && gimple_call_internal_p (STMT_VINFO_STMT (stmt_info),
    3077              :                                      IFN_MASK_LOAD)
    3078         4751 :           && STMT_VINFO_GROUPED_ACCESS (stmt_info)
    3079      3216816 :           && ! STMT_VINFO_SLP_VECT_ONLY (DR_GROUP_FIRST_ELEMENT (stmt_info)))
    3080              :         {
    3081           35 :           vec<stmt_vec_info> def_stmts2;
    3082           35 :           def_stmts2.create (1);
    3083           35 :           def_stmts2.quick_push (oprnd_info->def_stmts[0]);
    3084           35 :           child = vect_build_slp_tree (vinfo, def_stmts2,
    3085              :                                        matches, limit,
    3086              :                                        &this_tree_size, bst_map);
    3087           35 :           if (child)
    3088              :             {
    3089           35 :               slp_tree pnode = vect_create_new_slp_node (1, VEC_PERM_EXPR);
    3090           35 :               SLP_TREE_VECTYPE (pnode) = SLP_TREE_VECTYPE (child);
    3091           35 :               SLP_TREE_LANES (pnode) = group_size;
    3092           35 :               SLP_TREE_SCALAR_STMTS (pnode).create (group_size);
    3093           35 :               SLP_TREE_LANE_PERMUTATION (pnode).create (group_size);
    3094          245 :               for (unsigned k = 0; k < group_size; ++k)
    3095              :                 {
    3096          175 :                   SLP_TREE_SCALAR_STMTS (pnode)
    3097          175 :                     .quick_push (oprnd_info->def_stmts[0]);
    3098          175 :                   SLP_TREE_LANE_PERMUTATION (pnode)
    3099          175 :                     .quick_push (std::make_pair (0u, 0u));
    3100              :                 }
    3101           35 :               SLP_TREE_CHILDREN (pnode).quick_push (child);
    3102           35 :               children.safe_push (pnode);
    3103           35 :               oprnd_info->def_stmts = vNULL;
    3104           35 :               continue;
    3105           35 :             }
    3106              :           else
    3107            0 :             def_stmts2.release ();
    3108              :         }
    3109              : 
    3110      6433408 :       can_swap = (i == 0
    3111      2377761 :                   && (nops == 2 || nops == 3)
    3112      1542320 :                   && oprnds_info.length () > 1
    3113      1542320 :                   && oprnds_info[1]->first_dt == vect_internal_def
    3114       626627 :                   && (is_gimple_assign (stmt_info->stmt)
    3115        51556 :                       || is_gimple_call (stmt_info->stmt))
    3116              :                   /* Swapping operands for reductions breaks assumptions
    3117              :                      later on.  */
    3118      3796969 :                   && STMT_VINFO_REDUC_IDX (stmt_info) == -1);
    3119      3216704 :       can_swap_nonmatching = can_swap;
    3120      3216704 :       stmt_can_swap = NULL;
    3121      3216704 :       if (can_swap)
    3122              :         {
    3123       524401 :           stmt_can_swap = XALLOCAVEC (bool, group_size);
    3124      8186759 :           for (j = 0; j < group_size; ++j)
    3125              :             {
    3126      7662358 :               stmt_can_swap[j] = false;
    3127      7662358 :               if (!stmts[j])
    3128              :                 /* NULL lanes are gaps and have no stmt to swap.  */
    3129            0 :                 stmt_can_swap[j] = true;
    3130      7662358 :               else if (gassign *stmt = dyn_cast <gassign *> (stmts[j]->stmt))
    3131              :                 {
    3132      7656309 :                   tree_code code = gimple_assign_rhs_code (stmt);
    3133     15312618 :                   stmt_can_swap[j] = (commutative_tree_code (code)
    3134      7656309 :                                       || commutative_ternary_tree_code (code));
    3135              :                 }
    3136         6049 :               else if (gcall *call = dyn_cast <gcall *> (stmts[j]->stmt))
    3137              :                 {
    3138         6049 :                   internal_fn fn = (gimple_call_internal_p (call)
    3139         6049 :                                     ? gimple_call_internal_fn (call) : IFN_LAST);
    3140        12098 :                   stmt_can_swap[j] = ((commutative_binary_fn_p (fn)
    3141         4794 :                                        || commutative_ternary_fn_p (fn))
    3142         6085 :                                       && first_commutative_argument (fn) == 0);
    3143              :                 }
    3144              : 
    3145      7662358 :               if (j != 0 && !stmt_can_swap[j])
    3146      7662358 :                 can_swap_nonmatching = false;
    3147              :             }
    3148              :         }
    3149              : 
    3150      3216704 :       old_swap_distance = least_upthread_swappable_op_distance;
    3151      3216704 :       if (can_swap_nonmatching)
    3152       482727 :         least_upthread_swappable_op_distance = 1;
    3153      2733977 :       else if (least_upthread_swappable_op_distance != -1U)
    3154       353153 :         least_upthread_swappable_op_distance++;
    3155      3216704 :       child = vect_build_slp_tree (vinfo, oprnd_info->def_stmts,
    3156              :                                    matches, limit,
    3157              :                                    &this_tree_size, bst_map);
    3158      3216704 :       least_upthread_swappable_op_distance = old_swap_distance;
    3159      3216704 :       if (child != NULL)
    3160              :         {
    3161      2707738 :           oprnd_info->def_stmts = vNULL;
    3162      2707738 :           children.safe_push (child);
    3163      2707738 :           continue;
    3164              :         }
    3165              : 
    3166              :       /* If the SLP build for operand zero failed and operand zero
    3167              :          and one can be commuted try that for the scalar stmts
    3168              :          that failed the match.  */
    3169       508966 :       if (/* A first scalar stmt mismatch signals a fatal mismatch.  */
    3170       508966 :           matches[0] == 0
    3171       508966 :           && can_swap)
    3172              :         {
    3173              :           /* See whether we can swap the matching or the non-matching
    3174              :              stmt operands.  */
    3175              :           bool swap_not_matching = true;
    3176        74666 :           do
    3177              :             {
    3178      7115569 :               for (j = 0; j < group_size; ++j)
    3179              :                 {
    3180      7059057 :                   if ((matches[j] == 0) != !swap_not_matching)
    3181        89105 :                     continue;
    3182              :                   /* Verify if we can swap operands of this stmt.  */
    3183      6969952 :                   if (!stmt_can_swap[j])
    3184              :                     {
    3185        18154 :                       if (!swap_not_matching)
    3186         7993 :                         goto fail;
    3187              :                       swap_not_matching = false;
    3188              :                       break;
    3189              :                     }
    3190              :                 }
    3191              :             }
    3192        66673 :           while (j != group_size);
    3193              : 
    3194              :           /* Swap mismatched definition stmts.  */
    3195        56512 :           if (dump_enabled_p ())
    3196          432 :             dump_printf_loc (MSG_NOTE, vect_location,
    3197              :                              "Re-trying with swapped operands of stmts ");
    3198      7086197 :           for (j = 0; j < group_size; ++j)
    3199      7029685 :             if ((matches[j] == 0) == !swap_not_matching)
    3200              :               {
    3201     13903188 :                 std::swap (oprnds_info[0]->def_stmts[j],
    3202      6951594 :                            oprnds_info[1]->def_stmts[j]);
    3203     13903188 :                 std::swap (oprnds_info[0]->ops[j],
    3204      6951594 :                            oprnds_info[1]->ops[j]);
    3205      6951594 :                 if (dump_enabled_p ())
    3206         1101 :                   dump_printf (MSG_NOTE, "%d ", j);
    3207              :               }
    3208        56512 :           if (dump_enabled_p ())
    3209          432 :             dump_printf (MSG_NOTE, "\n");
    3210              :           /* After swapping some operands we lost track whether an
    3211              :              operand has any pattern defs so be conservative here.  */
    3212       109875 :           if (oprnds_info[0]->any_pattern || oprnds_info[1]->any_pattern)
    3213         4226 :             oprnds_info[0]->any_pattern = oprnds_info[1]->any_pattern = true;
    3214              :           /* And try again with scratch 'matches' ... */
    3215        56512 :           match_elt_t *tem = XALLOCAVEC (match_elt_t, group_size);
    3216        56512 :           if ((child = vect_build_slp_tree (vinfo, oprnd_info->def_stmts,
    3217              :                                             tem, limit,
    3218              :                                             &this_tree_size, bst_map)) != NULL)
    3219              :             {
    3220         7762 :               oprnd_info->def_stmts = vNULL;
    3221         7762 :               children.safe_push (child);
    3222         7762 :               continue;
    3223              :             }
    3224              :         }
    3225       501204 : fail:
    3226              : 
    3227              :       /* If the SLP build failed and we analyze a basic-block
    3228              :          simply treat nodes we fail to build as externally defined
    3229              :          (and thus build vectors from the scalar defs).
    3230              :          The cost model will reject outright expensive cases.
    3231              :          ???  This doesn't treat cases where permutation ultimatively
    3232              :          fails (or we don't try permutation below).  Ideally we'd
    3233              :          even compute a permutation that will end up with the maximum
    3234              :          SLP tree size...  */
    3235       501204 :       if (is_a <bb_vec_info> (vinfo)
    3236              :           /* ???  Rejecting patterns this way doesn't work.  We'd have to
    3237              :              do extra work to cancel the pattern so the uses see the
    3238              :              scalar version.  */
    3239              :           /* Skip building vector operands from scalars while operand
    3240              :              discovery may still be fixed by retrying with swapped operands.  */
    3241       441994 :           && (least_upthread_swappable_op_distance != 1
    3242              :               /* A first scalar stmt mismatch signals a fatal mismatch
    3243              :                  that the parent commutative retry cannot recover.
    3244              :                  ???  Possibly revisit this with the matches[] improvements
    3245              :                  as we can have matches[0] == -2 here.  */
    3246        27871 :               || matches[0] != 0)
    3247       422872 :           && !is_pattern_stmt_p (stmt_info)
    3248       896756 :           && !oprnd_info->any_pattern)
    3249              :         {
    3250              :           /* But if there's a leading vector sized set of matching stmts
    3251              :              fail here so we can split the group.  This matches the condition
    3252              :              vect_analyze_slp_instance uses.  */
    3253              :           /* ???  We might want to split here and combine the results to support
    3254              :              multiple vector sizes better.  */
    3255       613644 :           for (j = 0; j < group_size; ++j)
    3256       613644 :             if (matches[j] != 0)
    3257              :               break;
    3258       395187 :           if (!known_ge (j, TYPE_VECTOR_SUBPARTS (vectype))
    3259       395153 :               && vect_slp_can_convert_to_external (oprnd_info->def_stmts))
    3260              :             {
    3261       388702 :               if (dump_enabled_p ())
    3262          797 :                 dump_printf_loc (MSG_NOTE, vect_location,
    3263              :                                  "Building vector operands from scalars\n");
    3264       388702 :               this_tree_size++;
    3265       388702 :               child = vect_create_new_slp_node (oprnd_info->ops);
    3266       388702 :               children.safe_push (child);
    3267       388702 :               oprnd_info->ops = vNULL;
    3268       388702 :               continue;
    3269              :             }
    3270              :         }
    3271              : 
    3272       112502 :       gcc_assert (child == NULL);
    3273       245333 :       FOR_EACH_VEC_ELT (children, j, child)
    3274        20329 :         if (child)
    3275        20329 :           vect_free_slp_tree (child);
    3276       112502 :       vect_free_oprnd_info (oprnds_info);
    3277       112502 :       return NULL;
    3278              :     }
    3279              : 
    3280      3197983 :   vect_free_oprnd_info (oprnds_info);
    3281              : 
    3282              :   /* If we have all children of a child built up from uniform scalars
    3283              :      or does more than one possibly expensive vector construction then
    3284              :      just throw that away, causing it built up from scalars.
    3285              :      The exception is the SLP node for the vector store.  */
    3286      3197983 :   if (is_a <bb_vec_info> (vinfo)
    3287      1160816 :       && !STMT_VINFO_GROUPED_ACCESS (stmt_info)
    3288              :       /* ???  Rejecting patterns this way doesn't work.  We'd have to
    3289              :          do extra work to cancel the pattern so the uses see the
    3290              :          scalar version.  */
    3291      3681173 :       && !is_pattern_stmt_p (stmt_info))
    3292              :     {
    3293              :       slp_tree child;
    3294              :       unsigned j;
    3295              :       bool all_uniform_p = true;
    3296              :       unsigned n_vector_builds = 0;
    3297      1347237 :       FOR_EACH_VEC_ELT (children, j, child)
    3298              :         {
    3299       898257 :           if (!child)
    3300              :             ;
    3301       898257 :           else if (SLP_TREE_DEF_TYPE (child) == vect_internal_def)
    3302              :             all_uniform_p = false;
    3303       641457 :           else if (!vect_slp_tree_uniform_p (child))
    3304              :             {
    3305       485385 :               all_uniform_p = false;
    3306       485385 :               if (SLP_TREE_DEF_TYPE (child) == vect_external_def)
    3307       444873 :                 n_vector_builds++;
    3308              :             }
    3309              :         }
    3310       448980 :       if (all_uniform_p
    3311       448980 :           || n_vector_builds > 1
    3312       762390 :           || (n_vector_builds == children.length ()
    3313        35229 :               && is_a <gphi *> (stmt_info->stmt)))
    3314              :         {
    3315              :           /* Roll back.  */
    3316       139958 :           matches[0] = -1;
    3317       443907 :           FOR_EACH_VEC_ELT (children, j, child)
    3318       303949 :             if (child)
    3319       303949 :               vect_free_slp_tree (child);
    3320              : 
    3321       139958 :           if (dump_enabled_p ())
    3322          262 :             dump_printf_loc (MSG_NOTE, vect_location,
    3323              :                              "Building parent vector operands from "
    3324              :                              "scalars instead\n");
    3325      3310485 :           return NULL;
    3326              :         }
    3327              :     }
    3328              : 
    3329      3058025 :   *tree_size += this_tree_size + 1;
    3330              : 
    3331      3058025 :   if (two_operators)
    3332              :     {
    3333              :       /* ???  We'd likely want to either cache in bst_map sth like
    3334              :          { a+b, NULL, a+b, NULL } and { NULL, a-b, NULL, a-b } or
    3335              :          the true { a+b, a+b, a+b, a+b } ... but there we don't have
    3336              :          explicit stmts to put in so the keying on 'stmts' doesn't
    3337              :          work (but we have the same issue with nodes that use 'ops').  */
    3338              : 
    3339         7570 :       if (has_two_operators_perm)
    3340              :         {
    3341           46 :           slp_tree child = children[0];
    3342           46 :           children.truncate (0);
    3343          184 :           for (i = 0; i < 2; i++)
    3344              :             {
    3345           92 :               slp_tree pnode
    3346           92 :                 = vect_create_new_slp_node (two_op_scalar_stmts[i], 2);
    3347           92 :               SLP_TREE_CODE (pnode) = VEC_PERM_EXPR;
    3348           92 :               SLP_TREE_VECTYPE (pnode) = vectype;
    3349           92 :               SLP_TREE_CHILDREN (pnode).quick_push (child);
    3350           92 :               SLP_TREE_CHILDREN (pnode).quick_push (child);
    3351           92 :               SLP_TREE_REPRESENTATIVE (pnode) = NULL;
    3352           92 :               lane_permutation_t& perm = SLP_TREE_LANE_PERMUTATION (pnode);
    3353           92 :               children.safe_push (pnode);
    3354              : 
    3355          808 :               for (unsigned j = 0; j < stmts.length (); j++)
    3356          624 :                 perm.safe_push (std::make_pair (0, two_op_perm_indices[i][j]));
    3357              :             }
    3358              : 
    3359           46 :           SLP_TREE_REF_COUNT (child) += 4;
    3360              :         }
    3361              : 
    3362         7570 :       slp_tree one = new _slp_tree;
    3363         7570 :       slp_tree two = new _slp_tree;
    3364         7570 :       SLP_TREE_DEF_TYPE (one) = vect_internal_def;
    3365         7570 :       SLP_TREE_DEF_TYPE (two) = vect_internal_def;
    3366         7570 :       SLP_TREE_VECTYPE (one) = vectype;
    3367         7570 :       SLP_TREE_VECTYPE (two) = vectype;
    3368         7570 :       SLP_TREE_CHILDREN (one).safe_splice (children);
    3369         7570 :       SLP_TREE_CHILDREN (two).safe_splice (children);
    3370         7570 :       slp_tree child;
    3371        30282 :       FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (two), i, child)
    3372        15142 :         SLP_TREE_REF_COUNT (child)++;
    3373              : 
    3374              :       /* Here we record the original defs since this
    3375              :          node represents the final lane configuration.  */
    3376         7570 :       node = vect_create_new_slp_node (node, stmts, 2);
    3377         7570 :       SLP_TREE_VECTYPE (node) = vectype;
    3378         7570 :       SLP_TREE_CODE (node) = VEC_PERM_EXPR;
    3379         7570 :       SLP_TREE_CHILDREN (node).quick_push (one);
    3380         7570 :       SLP_TREE_CHILDREN (node).quick_push (two);
    3381         7570 :       SLP_TREE_REPRESENTATIVE (node) = NULL;
    3382         7570 :       enum tree_code code0 = ERROR_MARK;
    3383         7570 :       if (gassign *stmt = dyn_cast <gassign *> (stmts[0]->stmt))
    3384         7568 :         code0 = gimple_assign_rhs_code (stmt);
    3385         7570 :       stmt_vec_info ostmt_info;
    3386         7570 :       unsigned j = 0;
    3387        27105 :       FOR_EACH_VEC_ELT (stmts, i, ostmt_info)
    3388              :         {
    3389        19535 :           int op = 0;
    3390        19535 :           gassign *ostmt = dyn_cast<gassign *> (ostmt_info->stmt);
    3391        19531 :           if ((ostmt && gimple_assign_rhs_code (ostmt) != code0)
    3392              :               || (!ostmt
    3393            8 :                   && gimple_call_combined_fn (stmts[0]->stmt)
    3394            4 :                      != gimple_call_combined_fn (ostmt_info->stmt)))
    3395              :             {
    3396              :               op = 1;
    3397              :               j = i;
    3398              :             }
    3399        19535 :           SLP_TREE_LANE_PERMUTATION (node).safe_push (std::make_pair (op, i));
    3400              :         }
    3401         7570 :       SLP_TREE_LANES (one) = stmts.length ();
    3402         7570 :       SLP_TREE_LANES (two) = stmts.length ();
    3403         7570 :       SLP_TREE_REPRESENTATIVE (one) = stmts[0];
    3404         7570 :       SLP_TREE_REPRESENTATIVE (two) = stmts[j];
    3405              : 
    3406         7570 :       return node;
    3407              :     }
    3408              : 
    3409      3050455 :   node = vect_create_new_slp_node (node, stmts, nops);
    3410      3050455 :   SLP_TREE_VECTYPE (node) = vectype;
    3411      3050455 :   SLP_TREE_CHILDREN (node).splice (children);
    3412      3050455 :   SLP_TREE_GS_SCALE (node) = gs_scale;
    3413      3050455 :   SLP_TREE_GS_BASE (node) = gs_base;
    3414      3050455 :   if (reduc_idx != -1)
    3415              :     {
    3416       119689 :       gcc_assert (STMT_VINFO_REDUC_IDX (stmt_info) != -1
    3417              :                   || STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle
    3418              :                   || STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def);
    3419       119689 :       SLP_TREE_REDUC_IDX (node) = reduc_idx;
    3420       119689 :       node->cycle_info.id = SLP_TREE_CHILDREN (node)[reduc_idx]->cycle_info.id;
    3421              :     }
    3422              :   /* When reaching the reduction PHI, create a vect_reduc_info.  */
    3423      2930766 :   else if ((STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def
    3424      2930766 :             || STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def)
    3425      2930766 :            && is_a <gphi *> (STMT_VINFO_STMT (stmt_info)))
    3426              :     {
    3427       104345 :       loop_vec_info loop_vinfo = as_a <loop_vec_info> (vinfo);
    3428       104345 :       gcc_assert (STMT_VINFO_REDUC_IDX (stmt_info) == -1);
    3429       104345 :       node->cycle_info.id = loop_vinfo->reduc_infos.length ();
    3430       104345 :       vect_reduc_info reduc_info = new vect_reduc_info_s ();
    3431       104345 :       loop_vinfo->reduc_infos.safe_push (reduc_info);
    3432       104345 :       stmt_vec_info reduc_phi = stmt_info;
    3433              :       /* ???  For double reductions vect_is_simple_reduction stores the
    3434              :          reduction type and code on the inner loop header PHI.  */
    3435       104345 :       if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def)
    3436              :         {
    3437          388 :           use_operand_p use_p;
    3438          388 :           gimple *use_stmt;
    3439          388 :           bool res = single_imm_use (gimple_phi_result (stmt_info->stmt),
    3440              :                                      &use_p, &use_stmt);
    3441          388 :           gcc_assert (res);
    3442          388 :           reduc_phi = loop_vinfo->lookup_stmt (use_stmt);
    3443              :         }
    3444       104345 :       VECT_REDUC_INFO_DEF_TYPE (reduc_info) = STMT_VINFO_DEF_TYPE (stmt_info);
    3445       104345 :       VECT_REDUC_INFO_TYPE (reduc_info) = STMT_VINFO_REDUC_TYPE (reduc_phi);
    3446       104345 :       VECT_REDUC_INFO_CODE (reduc_info) = STMT_VINFO_REDUC_CODE (reduc_phi);
    3447       104345 :       VECT_REDUC_INFO_FN (reduc_info) = IFN_LAST;
    3448              :     }
    3449              :   return node;
    3450      9931455 : }
    3451              : 
    3452              : /* Dump a single SLP tree NODE.  */
    3453              : 
    3454              : static void
    3455       482302 : vect_print_slp_tree (dump_flags_t dump_kind, dump_location_t loc,
    3456              :                      slp_tree node)
    3457              : {
    3458       482302 :   unsigned i, j;
    3459       482302 :   slp_tree child;
    3460       482302 :   stmt_vec_info stmt_info;
    3461       482302 :   tree op;
    3462              : 
    3463       482302 :   dump_metadata_t metadata (dump_kind, loc.get_impl_location ());
    3464       482302 :   dump_user_location_t user_loc = loc.get_user_location ();
    3465       482302 :   dump_printf_loc (metadata, user_loc,
    3466              :                    "node%s %p (refcnt=%u)",
    3467       482302 :                    SLP_TREE_DEF_TYPE (node) == vect_external_def
    3468              :                    ? " (external)"
    3469              :                    : (SLP_TREE_DEF_TYPE (node) == vect_constant_def
    3470       465517 :                       ? " (constant)"
    3471              :                       : ""), (void *) node,
    3472              :                    SLP_TREE_REF_COUNT (node));
    3473       482302 :   if (SLP_TREE_VECTYPE (node))
    3474       406982 :     dump_printf (metadata, " %T", SLP_TREE_VECTYPE (node));
    3475       482302 :   dump_printf (metadata, "%s",
    3476       482302 :                node->avoid_stlf_fail ? " (avoid-stlf-fail)" : "");
    3477       482302 :   if (node->cycle_info.id != -1 || node->cycle_info.reduc_idx != -1)
    3478        24625 :     dump_printf (metadata, " cycle %d, link %d", node->cycle_info.id,
    3479              :                  node->cycle_info.reduc_idx);
    3480       482302 :   if (node->si)
    3481         5382 :     dump_printf (metadata, " @%G", node->si);
    3482              :   else
    3483       476920 :     dump_printf (metadata, "\n");
    3484       482302 :   if (SLP_TREE_DEF_TYPE (node) == vect_internal_def)
    3485              :     {
    3486       390973 :       if (SLP_TREE_PERMUTE_P (node))
    3487        17320 :         dump_printf_loc (metadata, user_loc, "op: VEC_PERM_EXPR\n");
    3488              :       else
    3489       373653 :         dump_printf_loc (metadata, user_loc, "op template: %G",
    3490       373653 :                          SLP_TREE_REPRESENTATIVE (node)->stmt);
    3491              :     }
    3492       482302 :   if (SLP_TREE_SCALAR_STMTS (node).exists ())
    3493       935318 :     FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
    3494       553381 :       if (stmt_info)
    3495       547229 :         dump_printf_loc (metadata, user_loc, "\t%sstmt %u %G",
    3496       547229 :                          SLP_TREE_LIVE_LANES (node).contains (i)
    3497       543455 :                          ? "[l*]" : (STMT_VINFO_LIVE_P (stmt_info)
    3498       543455 :                                      ? "[l] " : ""),
    3499              :                          i, stmt_info->stmt);
    3500              :       else
    3501         6152 :         dump_printf_loc (metadata, user_loc, "\tstmt %u ---\n", i);
    3502              :   else
    3503              :     {
    3504       100365 :       dump_printf_loc (metadata, user_loc, "\t{ ");
    3505       221590 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
    3506       121225 :         dump_printf (metadata, "%T%s ", op,
    3507       121225 :                      i < SLP_TREE_SCALAR_OPS (node).length () - 1 ? "," : "");
    3508       100365 :       dump_printf (metadata, "}\n");
    3509              :     }
    3510       482302 :   if (SLP_TREE_LOAD_PERMUTATION (node).exists ())
    3511              :     {
    3512        68738 :       dump_printf_loc (metadata, user_loc, "\tload permutation {");
    3513       156656 :       FOR_EACH_VEC_ELT (SLP_TREE_LOAD_PERMUTATION (node), i, j)
    3514        87918 :         dump_printf (dump_kind, " %u", j);
    3515        68738 :       dump_printf (dump_kind, " }\n");
    3516              :     }
    3517       482302 :   if (SLP_TREE_LANE_PERMUTATION (node).exists ())
    3518              :     {
    3519        17328 :       dump_printf_loc (metadata, user_loc, "\tlane permutation {");
    3520        64872 :       for (i = 0; i < SLP_TREE_LANE_PERMUTATION (node).length (); ++i)
    3521        47544 :         dump_printf (dump_kind, " %u[%u]",
    3522        47544 :                      SLP_TREE_LANE_PERMUTATION (node)[i].first,
    3523        47544 :                      SLP_TREE_LANE_PERMUTATION (node)[i].second);
    3524        17328 :       dump_printf (dump_kind, " }%s\n",
    3525        17328 :                    node->ldst_lanes ? " (load-lanes)" : "");
    3526              :     }
    3527       482302 :   if (SLP_TREE_CHILDREN (node).is_empty ())
    3528       182774 :     return;
    3529       299528 :   dump_printf_loc (metadata, user_loc, "\tchildren");
    3530       790057 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    3531       490529 :     dump_printf (dump_kind, " %p", (void *)child);
    3532       299528 :   dump_printf (dump_kind, "%s\n",
    3533       299528 :                node->ldst_lanes && !SLP_TREE_LANE_PERMUTATION (node).exists ()
    3534              :                ? " (store-lanes)" : "");
    3535              : }
    3536              : 
    3537              : DEBUG_FUNCTION void
    3538            0 : debug (slp_tree node)
    3539              : {
    3540            0 :   debug_dump_context ctx;
    3541            0 :   vect_print_slp_tree (MSG_NOTE,
    3542            0 :                        dump_location_t::from_location_t (UNKNOWN_LOCATION),
    3543              :                        node);
    3544            0 : }
    3545              : 
    3546              : /* Recursive helper for the dot producer below.  */
    3547              : 
    3548              : static void
    3549            0 : dot_slp_tree (FILE *f, slp_tree node, hash_set<slp_tree> &visited)
    3550              : {
    3551            0 :   if (visited.add (node))
    3552              :     return;
    3553              : 
    3554            0 :   fprintf (f, "\"%p\" [label=\"", (void *)node);
    3555            0 :   vect_print_slp_tree (MSG_NOTE,
    3556            0 :                        dump_location_t::from_location_t (UNKNOWN_LOCATION),
    3557              :                        node);
    3558            0 :   fprintf (f, "\"];\n");
    3559              : 
    3560              : 
    3561            0 :   for (slp_tree child : SLP_TREE_CHILDREN (node))
    3562            0 :     fprintf (f, "\"%p\" -> \"%p\";", (void *)node, (void *)child);
    3563              : 
    3564            0 :   for (slp_tree child : SLP_TREE_CHILDREN (node))
    3565            0 :     if (child)
    3566            0 :       dot_slp_tree (f, child, visited);
    3567              : }
    3568              : 
    3569              : DEBUG_FUNCTION void
    3570            0 : dot_slp_tree (const char *fname, slp_tree node)
    3571              : {
    3572            0 :   FILE *f = fopen (fname, "w");
    3573            0 :   fprintf (f, "digraph {\n");
    3574            0 :   fflush (f);
    3575            0 :     {
    3576            0 :       debug_dump_context ctx (f);
    3577            0 :       hash_set<slp_tree> visited;
    3578            0 :       dot_slp_tree (f, node, visited);
    3579            0 :     }
    3580            0 :   fflush (f);
    3581            0 :   fprintf (f, "}\n");
    3582            0 :   fclose (f);
    3583            0 : }
    3584              : 
    3585              : DEBUG_FUNCTION void
    3586            0 : dot_slp_tree (const char *fname, const vec<slp_instance> &slp_instances)
    3587              : {
    3588            0 :   FILE *f = fopen (fname, "w");
    3589            0 :   fprintf (f, "digraph {\n");
    3590            0 :   fflush (f);
    3591            0 :     {
    3592            0 :       debug_dump_context ctx (f);
    3593            0 :       hash_set<slp_tree> visited;
    3594            0 :       for (auto inst : slp_instances)
    3595            0 :         dot_slp_tree (f, SLP_INSTANCE_TREE (inst), visited);
    3596            0 :     }
    3597            0 :   fflush (f);
    3598            0 :   fprintf (f, "}\n");
    3599            0 :   fclose (f);
    3600            0 : }
    3601              : 
    3602              : /* Dump a slp tree NODE using flags specified in DUMP_KIND.  */
    3603              : 
    3604              : static void
    3605       520735 : vect_print_slp_graph (dump_flags_t dump_kind, dump_location_t loc,
    3606              :                       slp_tree node, hash_set<slp_tree> &visited)
    3607              : {
    3608       520735 :   unsigned i;
    3609       520735 :   slp_tree child;
    3610              : 
    3611       520735 :   if (visited.add (node))
    3612       520735 :     return;
    3613              : 
    3614       478471 :   vect_print_slp_tree (dump_kind, loc, node);
    3615              : 
    3616      1442342 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    3617       485400 :     if (child)
    3618       440451 :       vect_print_slp_graph (dump_kind, loc, child, visited);
    3619              : }
    3620              : 
    3621              : static void
    3622        49125 : vect_print_slp_graph (dump_flags_t dump_kind, dump_location_t loc,
    3623              :                       slp_tree entry)
    3624              : {
    3625        49125 :   hash_set<slp_tree> visited;
    3626        49125 :   vect_print_slp_graph (dump_kind, loc, entry, visited);
    3627        49125 : }
    3628              : 
    3629              : DEBUG_FUNCTION void
    3630            0 : debug (slp_instance instance)
    3631              : {
    3632            0 :   debug_dump_context ctx;
    3633            0 :   vect_print_slp_graph (MSG_NOTE,
    3634            0 :                         dump_location_t::from_location_t (UNKNOWN_LOCATION),
    3635              :                         SLP_INSTANCE_TREE (instance));
    3636            0 : }
    3637              : 
    3638              : 
    3639              : /* Compute the set of scalar stmts participating in external nodes.  */
    3640              : 
    3641              : static void
    3642      1706611 : vect_slp_gather_extern_scalar_stmts (vec_info *vinfo, slp_tree node,
    3643              :                                      hash_set<slp_tree> &visited,
    3644              :                                      hash_set<stmt_vec_info> &estmts)
    3645              : {
    3646      1706611 :   if (visited.add (node))
    3647              :     return;
    3648              : 
    3649      1645472 :   if (SLP_TREE_DEF_TYPE (node) == vect_internal_def)
    3650              :     {
    3651              :       slp_tree child;
    3652              :       int i;
    3653      1930087 :       FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    3654       985879 :         if (child)
    3655       985879 :           vect_slp_gather_extern_scalar_stmts (vinfo, child, visited, estmts);
    3656              :     }
    3657              :   else
    3658      3926576 :     for (tree def : SLP_TREE_SCALAR_OPS (node))
    3659              :       {
    3660      1824956 :         stmt_vec_info def_stmt = vinfo->lookup_def (def);
    3661      1824956 :         if (def_stmt)
    3662       390897 :           estmts.add (def_stmt);
    3663              :       }
    3664              : }
    3665              : 
    3666              : /* Mark the original scalar stmt coverage of the vector SLP graph of VINFO
    3667              :    with STMT_SLP_TYPE == pure_slp.  */
    3668              : 
    3669              : static void
    3670       248621 : vect_bb_slp_mark_stmts_vectorized (bb_vec_info vinfo)
    3671              : {
    3672              :   /* Gather the scalar stmt leafs of the SLP graph to stop the below DFS
    3673              :      walk on.  */
    3674       248621 :   hash_set<stmt_vec_info> scalar_stmts_in_externs;
    3675       248621 :   hash_set<slp_tree> visited;
    3676      1466595 :   for (auto instance : BB_VINFO_SLP_INSTANCES (vinfo))
    3677       720732 :     vect_slp_gather_extern_scalar_stmts (vinfo, SLP_INSTANCE_TREE (instance),
    3678              :                                          visited, scalar_stmts_in_externs);
    3679              : 
    3680              :   /* DFS walk scalar stmts to compute the vectorized coverage indicated
    3681              :      by STMT_SLP_TYPE (stmt) == pure_slp on the original scalar (non-pattern)
    3682              :      stmts.  */
    3683      1466595 :   for (auto instance : BB_VINFO_SLP_INSTANCES (vinfo))
    3684              :     {
    3685       917069 :       for (auto stmt : SLP_INSTANCE_ROOT_STMTS (instance))
    3686        90967 :         if (!scalar_stmts_in_externs.contains (stmt))
    3687        89722 :           STMT_SLP_TYPE (stmt) = pure_slp;
    3688       720732 :       auto_vec<stmt_vec_info> worklist;
    3689      4062422 :       for (auto stmt : SLP_TREE_SCALAR_STMTS (SLP_INSTANCE_TREE (instance)))
    3690              :         {
    3691      1900226 :           stmt = vect_orig_stmt (stmt);
    3692      1900226 :           if (!scalar_stmts_in_externs.contains (stmt)
    3693      1900226 :               && STMT_SLP_TYPE (stmt) != pure_slp)
    3694              :             {
    3695      1883261 :               STMT_SLP_TYPE (stmt) = pure_slp;
    3696      1883261 :               worklist.safe_push (stmt);
    3697              :             }
    3698              :         }
    3699      3791975 :       while (!worklist.is_empty ())
    3700              :         {
    3701      2355384 :           stmt_vec_info stmt = worklist.pop ();
    3702              : 
    3703              :           /* Now walk relevant parts of the SSA use-def graph.  */
    3704      2355384 :           slp_oprnds child_ops (stmt);
    3705      7346269 :           for (unsigned i = 0; i < child_ops.num_slp_children; ++i)
    3706              :             {
    3707      2635501 :               tree op = child_ops.get_op_for_slp_child (stmt, i);
    3708      2635501 :               stmt_vec_info def = vinfo->lookup_def (op);
    3709      2635501 :               if (def
    3710       947416 :                   && !scalar_stmts_in_externs.contains (def)
    3711      3203370 :                   && STMT_SLP_TYPE (def) != pure_slp)
    3712              :                 {
    3713       472123 :                   STMT_SLP_TYPE (def) = pure_slp;
    3714       472123 :                   worklist.safe_push (def);
    3715              :                 }
    3716              :             }
    3717              :         }
    3718       720732 :     }
    3719       248621 : }
    3720              : 
    3721              : /* Mark the statements of the tree rooted at NODE as relevant (vect_used).  */
    3722              : 
    3723              : static void
    3724      2614921 : vect_mark_slp_stmts_relevant (slp_tree node, hash_set<slp_tree> &visited)
    3725              : {
    3726      2614921 :   if (SLP_TREE_DEF_TYPE (node) != vect_internal_def)
    3727              :     return;
    3728              : 
    3729      1572888 :   if (visited.add (node))
    3730              :     return;
    3731              : 
    3732      7341408 :   for (auto stmt_info : SLP_TREE_SCALAR_STMTS (node))
    3733      3279218 :     if (stmt_info)
    3734              :       {
    3735      3279218 :         gcc_assert (!STMT_VINFO_RELEVANT (stmt_info)
    3736              :                     || STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_scope);
    3737      3279218 :         STMT_VINFO_RELEVANT (stmt_info) = vect_used_in_scope;
    3738              :       }
    3739              : 
    3740      5690125 :   for (auto child: SLP_TREE_CHILDREN (node))
    3741      1789485 :     if (child)
    3742      1789485 :       vect_mark_slp_stmts_relevant (child, visited);
    3743              : }
    3744              : 
    3745              : static void
    3746       825436 : vect_mark_slp_stmts_relevant (slp_tree node)
    3747              : {
    3748       825436 :   hash_set<slp_tree> visited;
    3749       825436 :   vect_mark_slp_stmts_relevant (node, visited);
    3750       825436 : }
    3751              : 
    3752              : 
    3753              : /* Gather loads in the SLP graph NODE and populate the INST loads array.  */
    3754              : 
    3755              : static void
    3756     11253104 : vect_gather_slp_loads (vec<slp_tree> &loads, slp_tree node,
    3757              :                        hash_set<slp_tree> &visited)
    3758              : {
    3759     11253104 :   if (!node || visited.add (node))
    3760              :     return;
    3761              : 
    3762      9404240 :   if (SLP_TREE_DEF_TYPE (node) != vect_internal_def)
    3763              :     return;
    3764              : 
    3765      6951961 :   if (!SLP_TREE_PERMUTE_P (node))
    3766              :     {
    3767      6737581 :       stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node);
    3768      6737581 :       if (STMT_VINFO_DATA_REF (stmt_info)
    3769      2885551 :           && DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)))
    3770      1647439 :         loads.safe_push (node);
    3771              :     }
    3772              : 
    3773      6951961 :   unsigned i;
    3774      6951961 :   slp_tree child;
    3775     15851320 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    3776      8899359 :     vect_gather_slp_loads (loads, child, visited);
    3777              : }
    3778              : 
    3779              : 
    3780              : /* Find the last store in SLP INSTANCE.  */
    3781              : 
    3782              : stmt_vec_info
    3783      2565852 : vect_find_last_scalar_stmt_in_slp (slp_tree node)
    3784              : {
    3785      2565852 :   stmt_vec_info last = NULL;
    3786     14517977 :   for (auto stmt_vinfo : SLP_TREE_SCALAR_STMTS (node))
    3787      6820421 :     if (stmt_vinfo)
    3788              :       {
    3789      6820421 :         stmt_vinfo = vect_orig_stmt (stmt_vinfo);
    3790      6820421 :         last = last ? get_later_stmt (stmt_vinfo, last) : stmt_vinfo;
    3791              :       }
    3792              : 
    3793      2565852 :   return last;
    3794              : }
    3795              : 
    3796              : /* Find the first stmt in NODE.  */
    3797              : 
    3798              : stmt_vec_info
    3799       657874 : vect_find_first_scalar_stmt_in_slp (slp_tree node)
    3800              : {
    3801       657874 :   stmt_vec_info first = NULL;
    3802              : 
    3803      3559741 :   for (auto stmt_vinfo : SLP_TREE_SCALAR_STMTS (node))
    3804      1586119 :     if (stmt_vinfo)
    3805              :       {
    3806      1583330 :         stmt_vinfo = vect_orig_stmt (stmt_vinfo);
    3807      1583330 :         if (!first
    3808      1583330 :             || get_later_stmt (stmt_vinfo, first) == first)
    3809              :           first = stmt_vinfo;
    3810              :       }
    3811              : 
    3812       657874 :   return first;
    3813              : }
    3814              : 
    3815              : /* Splits a group of stores, currently beginning at FIRST_VINFO, into
    3816              :    two groups: one (still beginning at FIRST_VINFO) of size GROUP1_SIZE
    3817              :    (also containing the first GROUP1_SIZE stmts, since stores are
    3818              :    consecutive), the second containing the remainder.
    3819              :    Return the first stmt in the second group.  */
    3820              : 
    3821              : static stmt_vec_info
    3822       138107 : vect_split_slp_store_group (stmt_vec_info first_vinfo, unsigned group1_size)
    3823              : {
    3824       138107 :   gcc_assert (DR_GROUP_FIRST_ELEMENT (first_vinfo) == first_vinfo);
    3825       138107 :   gcc_assert (group1_size > 0);
    3826       138107 :   int group2_size = DR_GROUP_SIZE (first_vinfo) - group1_size;
    3827       138107 :   gcc_assert (group2_size > 0);
    3828       138107 :   DR_GROUP_SIZE (first_vinfo) = group1_size;
    3829              : 
    3830       138107 :   stmt_vec_info stmt_info = first_vinfo;
    3831       462443 :   for (unsigned i = group1_size; i > 1; i--)
    3832              :     {
    3833       324336 :       stmt_info = DR_GROUP_NEXT_ELEMENT (stmt_info);
    3834       324336 :       gcc_assert (DR_GROUP_GAP (stmt_info) == 1);
    3835              :     }
    3836              :   /* STMT is now the last element of the first group.  */
    3837       138107 :   stmt_vec_info group2 = DR_GROUP_NEXT_ELEMENT (stmt_info);
    3838       138107 :   DR_GROUP_NEXT_ELEMENT (stmt_info) = 0;
    3839              : 
    3840       138107 :   DR_GROUP_SIZE (group2) = group2_size;
    3841       409464 :   for (stmt_info = group2; stmt_info;
    3842       271357 :        stmt_info = DR_GROUP_NEXT_ELEMENT (stmt_info))
    3843              :     {
    3844       271357 :       DR_GROUP_FIRST_ELEMENT (stmt_info) = group2;
    3845       271357 :       gcc_assert (DR_GROUP_GAP (stmt_info) == 1);
    3846              :     }
    3847              : 
    3848              :   /* For the second group, the DR_GROUP_GAP is that before the original group,
    3849              :      plus skipping over the first vector.  */
    3850       138107 :   DR_GROUP_GAP (group2) = DR_GROUP_GAP (first_vinfo) + group1_size;
    3851              : 
    3852              :   /* DR_GROUP_GAP of the first group now has to skip over the second group too.  */
    3853       138107 :   DR_GROUP_GAP (first_vinfo) += group2_size;
    3854              : 
    3855       138107 :   if (dump_enabled_p ())
    3856           88 :     dump_printf_loc (MSG_NOTE, vect_location, "Split group into %d and %d\n",
    3857              :                      group1_size, group2_size);
    3858              : 
    3859       138107 :   return group2;
    3860              : }
    3861              : 
    3862              : /* Calculate the unrolling factor for an SLP instance with GROUP_SIZE
    3863              :    statements and a vector of NUNITS elements.  */
    3864              : 
    3865              : static poly_uint64
    3866      2888739 : calculate_unrolling_factor (poly_uint64 nunits, unsigned int group_size)
    3867              : {
    3868      2888739 :   return exact_div (common_multiple (nunits, group_size), group_size);
    3869              : }
    3870              : 
    3871              : /* Helper that checks to see if a node is a load node.  */
    3872              : 
    3873              : static inline bool
    3874          103 : vect_is_slp_load_node  (slp_tree root)
    3875              : {
    3876          103 :   return (!SLP_TREE_PERMUTE_P (root)
    3877          103 :           && SLP_TREE_DEF_TYPE (root) == vect_internal_def
    3878           97 :           && STMT_VINFO_GROUPED_ACCESS (SLP_TREE_REPRESENTATIVE (root))
    3879          167 :           && DR_IS_READ (STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (root))));
    3880              : }
    3881              : 
    3882              : 
    3883              : /* Helper function of optimize_load_redistribution that performs the operation
    3884              :    recursively.  */
    3885              : 
    3886              : static slp_tree
    3887        21801 : optimize_load_redistribution_1 (scalar_stmts_to_slp_tree_map_t *bst_map,
    3888              :                                 vec_info *vinfo, unsigned int group_size,
    3889              :                                 hash_map<slp_tree, slp_tree> *load_map,
    3890              :                                 slp_tree root)
    3891              : {
    3892        21801 :   if (slp_tree *leader = load_map->get (root))
    3893         4549 :     return *leader;
    3894              : 
    3895        17252 :   slp_tree node;
    3896        17252 :   unsigned i;
    3897              : 
    3898              :   /* For now, we don't know anything about externals so do not do anything.  */
    3899        17252 :   if (!root || SLP_TREE_DEF_TYPE (root) != vect_internal_def)
    3900              :     return NULL;
    3901        12116 :   else if (SLP_TREE_PERMUTE_P (root))
    3902              :     {
    3903              :       /* First convert this node into a load node and add it to the leaves
    3904              :          list and flatten the permute from a lane to a load one.  If it's
    3905              :          unneeded it will be elided later.  */
    3906           71 :       vec<stmt_vec_info> stmts;
    3907           71 :       stmts.create (SLP_TREE_LANES (root));
    3908           71 :       lane_permutation_t lane_perm = SLP_TREE_LANE_PERMUTATION (root);
    3909          135 :       for (unsigned j = 0; j < lane_perm.length (); j++)
    3910              :         {
    3911          103 :           std::pair<unsigned, unsigned> perm = lane_perm[j];
    3912          103 :           node = SLP_TREE_CHILDREN (root)[perm.first];
    3913              : 
    3914          103 :           if (!vect_is_slp_load_node (node)
    3915          103 :               || SLP_TREE_CHILDREN (node).exists ())
    3916              :             {
    3917           39 :               stmts.release ();
    3918           39 :               goto next;
    3919              :             }
    3920              : 
    3921           64 :           stmts.quick_push (SLP_TREE_SCALAR_STMTS (node)[perm.second]);
    3922              :         }
    3923              : 
    3924           32 :       if (dump_enabled_p ())
    3925            0 :         dump_printf_loc (MSG_NOTE, vect_location,
    3926              :                          "converting stmts on permute node %p\n",
    3927              :                          (void *) root);
    3928              : 
    3929           32 :       match_elt_t *matches = XALLOCAVEC (match_elt_t, group_size);
    3930           32 :       unsigned tree_size = 0, limit = 1;
    3931           32 :       node = vect_build_slp_tree (vinfo, stmts,
    3932              :                                   matches, &limit, &tree_size, bst_map);
    3933           32 :       if (!node)
    3934            0 :         stmts.release ();
    3935              : 
    3936           32 :       load_map->put (root, node);
    3937           32 :       return node;
    3938              :     }
    3939              : 
    3940        12045 : next:
    3941        12084 :   load_map->put (root, NULL);
    3942              : 
    3943        27523 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (root), i , node)
    3944              :     {
    3945        15439 :       slp_tree value
    3946        15439 :         = optimize_load_redistribution_1 (bst_map, vinfo, group_size, load_map,
    3947              :                                           node);
    3948        15439 :       if (value)
    3949              :         {
    3950           32 :           SLP_TREE_REF_COUNT (value)++;
    3951           32 :           SLP_TREE_CHILDREN (root)[i] = value;
    3952              :           /* ???  We know the original leafs of the replaced nodes will
    3953              :              be referenced by bst_map, only the permutes created by
    3954              :              pattern matching are not.  */
    3955           32 :           if (SLP_TREE_REF_COUNT (node) == 1)
    3956           32 :             load_map->remove (node);
    3957           32 :           vect_free_slp_tree (node);
    3958              :         }
    3959              :     }
    3960              : 
    3961              :   return NULL;
    3962              : }
    3963              : 
    3964              : /* Temporary workaround for loads not being CSEd during SLP build.  This
    3965              :    function will traverse the SLP tree rooted in ROOT for INSTANCE and find
    3966              :    VEC_PERM nodes that blend vectors from multiple nodes that all read from the
    3967              :    same DR such that the final operation is equal to a permuted load.  Such
    3968              :    NODES are then directly converted into LOADS themselves.  The nodes are
    3969              :    CSEd using BST_MAP.  */
    3970              : 
    3971              : static void
    3972         4180 : optimize_load_redistribution (scalar_stmts_to_slp_tree_map_t *bst_map,
    3973              :                               vec_info *vinfo, unsigned int group_size,
    3974              :                               hash_map<slp_tree, slp_tree> *load_map,
    3975              :                               slp_tree root)
    3976              : {
    3977         4180 :   slp_tree node;
    3978         4180 :   unsigned i;
    3979              : 
    3980        10542 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (root), i , node)
    3981              :     {
    3982         6362 :       slp_tree value
    3983         6362 :         = optimize_load_redistribution_1 (bst_map, vinfo, group_size, load_map,
    3984              :                                           node);
    3985         6362 :       if (value)
    3986              :         {
    3987            0 :           SLP_TREE_REF_COUNT (value)++;
    3988            0 :           SLP_TREE_CHILDREN (root)[i] = value;
    3989              :           /* ???  We know the original leafs of the replaced nodes will
    3990              :              be referenced by bst_map, only the permutes created by
    3991              :              pattern matching are not.  */
    3992            0 :           if (SLP_TREE_REF_COUNT (node) == 1)
    3993            0 :             load_map->remove (node);
    3994            0 :           vect_free_slp_tree (node);
    3995              :         }
    3996              :     }
    3997         4180 : }
    3998              : 
    3999              : /* Helper function of vect_match_slp_patterns.
    4000              : 
    4001              :    Attempts to match patterns against the slp tree rooted in REF_NODE using
    4002              :    VINFO.  Patterns are matched in post-order traversal.
    4003              : 
    4004              :    If matching is successful the value in REF_NODE is updated and returned, if
    4005              :    not then it is returned unchanged.  */
    4006              : 
    4007              : static bool
    4008      6533293 : vect_match_slp_patterns_2 (slp_tree *ref_node, vec_info *vinfo,
    4009              :                            slp_tree_to_load_perm_map_t *perm_cache,
    4010              :                            slp_compat_nodes_map_t *compat_cache,
    4011              :                            hash_set<slp_tree> *visited)
    4012              : {
    4013      6533293 :   unsigned i;
    4014      6533293 :   slp_tree node = *ref_node;
    4015      6533293 :   bool found_p = false;
    4016      6533293 :   if (!node || visited->add (node))
    4017              :     return false;
    4018              : 
    4019              :   slp_tree child;
    4020     10488998 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    4021      4891745 :     found_p |= vect_match_slp_patterns_2 (&SLP_TREE_CHILDREN (node)[i],
    4022              :                                           vinfo, perm_cache, compat_cache,
    4023              :                                           visited);
    4024              : 
    4025     16791759 :   for (unsigned x = 0; x < num__slp_patterns; x++)
    4026              :     {
    4027     11194506 :       vect_pattern *pattern
    4028     11194506 :         = slp_patterns[x] (perm_cache, compat_cache, ref_node);
    4029     11194506 :       if (pattern)
    4030              :         {
    4031         1114 :           pattern->build (vinfo);
    4032         1114 :           delete pattern;
    4033              :           found_p = true;
    4034              :         }
    4035              :     }
    4036              : 
    4037              :   return found_p;
    4038              : }
    4039              : 
    4040              : /* Applies pattern matching to the given SLP tree rooted in REF_NODE using
    4041              :    vec_info VINFO.
    4042              : 
    4043              :    The modified tree is returned.  Patterns are tried in order and multiple
    4044              :    patterns may match.  */
    4045              : 
    4046              : static bool
    4047      1641548 : vect_match_slp_patterns (slp_instance instance, vec_info *vinfo,
    4048              :                          hash_set<slp_tree> *visited,
    4049              :                          slp_tree_to_load_perm_map_t *perm_cache,
    4050              :                          slp_compat_nodes_map_t *compat_cache)
    4051              : {
    4052      1641548 :   DUMP_VECT_SCOPE ("vect_match_slp_patterns");
    4053      1641548 :   slp_tree *ref_node = &SLP_INSTANCE_TREE (instance);
    4054              : 
    4055      1641548 :   if (dump_enabled_p ())
    4056        32512 :     dump_printf_loc (MSG_NOTE, vect_location,
    4057              :                      "Analyzing SLP tree %p for patterns\n",
    4058        32512 :                      (void *) SLP_INSTANCE_TREE (instance));
    4059              : 
    4060      1641548 :   return vect_match_slp_patterns_2 (ref_node, vinfo, perm_cache, compat_cache,
    4061      1641548 :                                     visited);
    4062              : }
    4063              : 
    4064              : /* STMT_INFO is a store group of size GROUP_SIZE that we are considering
    4065              :    vectorizing with VECTYPE that might be NULL.  MASKED_P indicates whether
    4066              :    the stores are masked.
    4067              :    Return true if we could use IFN_STORE_LANES instead and if that appears
    4068              :    to be the better approach.  */
    4069              : 
    4070              : static bool
    4071         6132 : vect_slp_prefer_store_lanes_p (vec_info *vinfo, stmt_vec_info stmt_info,
    4072              :                                tree vectype, bool masked_p,
    4073              :                                unsigned int group_size,
    4074              :                                unsigned int new_group_size)
    4075              : {
    4076         6132 :   if (!vectype)
    4077              :     {
    4078         6132 :       tree scalar_type = TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (stmt_info)));
    4079         6132 :       vectype = get_vectype_for_scalar_type (vinfo, scalar_type);
    4080              :     }
    4081         6132 :   if (!vectype)
    4082              :     return false;
    4083              :   /* Allow the split if one of the two new groups would operate on full
    4084              :      vectors *within* rather than across one scalar loop iteration.
    4085              :      This is purely a heuristic, but it should work well for group
    4086              :      sizes of 3 and 4, where the possible splits are:
    4087              : 
    4088              :        3->2+1:  OK if the vector has exactly two elements
    4089              :        4->2+2:  Likewise
    4090              :        4->3+1:  Less clear-cut.  */
    4091         6132 :   if (multiple_p (group_size - new_group_size, TYPE_VECTOR_SUBPARTS (vectype))
    4092         6132 :       || multiple_p (new_group_size, TYPE_VECTOR_SUBPARTS (vectype)))
    4093              :     return false;
    4094         3488 :   return vect_store_lanes_supported (vectype, group_size, masked_p) != IFN_LAST;
    4095              : }
    4096              : 
    4097              : /* Analyze an SLP instance starting from a group of grouped stores.  Call
    4098              :    vect_build_slp_tree to build a tree of packed stmts if possible.
    4099              :    Return FALSE if it's impossible to SLP any stmt in the loop.  */
    4100              : 
    4101              : static bool
    4102              : vect_analyze_slp_instance (vec_info *vinfo,
    4103              :                            scalar_stmts_to_slp_tree_map_t *bst_map,
    4104              :                            stmt_vec_info stmt_info, slp_instance_kind kind,
    4105              :                            unsigned max_tree_size, unsigned *limit,
    4106              :                            bool force_single_lane);
    4107              : 
    4108              : /* Build an interleaving scheme for the store sources RHS_NODES from
    4109              :    SCALAR_STMTS.  */
    4110              : 
    4111              : static slp_tree
    4112         8249 : vect_build_slp_store_interleaving (vec<slp_tree> &rhs_nodes,
    4113              :                                    vec<stmt_vec_info> &scalar_stmts)
    4114              : {
    4115         8249 :   unsigned int group_size = scalar_stmts.length ();
    4116        16498 :   slp_tree node = vect_create_new_slp_node (scalar_stmts,
    4117         8249 :                                             SLP_TREE_CHILDREN
    4118              :                                               (rhs_nodes[0]).length ());
    4119         8249 :   SLP_TREE_VECTYPE (node) = SLP_TREE_VECTYPE (rhs_nodes[0]);
    4120         8249 :   for (unsigned l = 0;
    4121        16525 :        l < SLP_TREE_CHILDREN (rhs_nodes[0]).length (); ++l)
    4122              :     {
    4123              :       /* And a permute merging all RHS SLP trees.  */
    4124         8276 :       slp_tree perm = vect_create_new_slp_node (rhs_nodes.length (),
    4125         8276 :                                                 VEC_PERM_EXPR);
    4126         8276 :       SLP_TREE_CHILDREN (node).quick_push (perm);
    4127         8276 :       SLP_TREE_LANE_PERMUTATION (perm).create (group_size);
    4128         8276 :       SLP_TREE_VECTYPE (perm) = SLP_TREE_VECTYPE (node);
    4129         8276 :       SLP_TREE_LANES (perm) = group_size;
    4130         8276 :       SLP_TREE_REPRESENTATIVE (perm) = NULL;
    4131        64708 :       for (unsigned j = 0; j < rhs_nodes.length (); ++j)
    4132              :         {
    4133        24078 :           SLP_TREE_CHILDREN (perm)
    4134        24078 :             .quick_push (SLP_TREE_CHILDREN (rhs_nodes[j])[l]);
    4135        24078 :           SLP_TREE_CHILDREN (rhs_nodes[j])[l]->refcnt++;
    4136        24078 :           for (unsigned k = 0;
    4137        50547 :                k < SLP_TREE_LANES (rhs_nodes[j]); ++k)
    4138              :             {
    4139              :               /* ???  We should populate SLP_TREE_SCALAR_STMTS
    4140              :                  or SLP_TREE_SCALAR_OPS but then we might have
    4141              :                  a mix of both in our children.  */
    4142        26469 :               SLP_TREE_LANE_PERMUTATION (perm)
    4143        26469 :                 .quick_push (std::make_pair (j, k));
    4144              :             }
    4145              :         }
    4146              : 
    4147              :       /* Now we have a single permute node but we cannot code-generate
    4148              :          the case with more than two inputs.
    4149              :          Perform pairwise reduction, reducing the two inputs
    4150              :          with the least number of lanes to one and then repeat until
    4151              :          we end up with two inputs.  That scheme makes sure we end
    4152              :          up with permutes satisfying the restriction of requiring at
    4153              :          most two vector inputs to produce a single vector output
    4154              :          when the number of lanes is even.  */
    4155        15802 :       while (SLP_TREE_CHILDREN (perm).length () > 2)
    4156              :         {
    4157              :           /* When we have three equal sized groups left the pairwise
    4158              :              reduction does not result in a scheme that avoids using
    4159              :              three vectors.  Instead merge the first two groups
    4160              :              to the final size with do-not-care elements (chosen
    4161              :              from the first group) and then merge with the third.
    4162              :                   { A0, B0,  x, A1, B1,  x, ... }
    4163              :                -> { A0, B0, C0, A1, B1, C1, ... }
    4164              :              This handles group size of three (and at least
    4165              :              power-of-two multiples of that).  */
    4166         7526 :           if (SLP_TREE_CHILDREN (perm).length () == 3
    4167         3370 :               && (SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[0])
    4168         3370 :                   == SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[1]))
    4169         7526 :               && (SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[0])
    4170         2489 :                   == SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[2])))
    4171              :             {
    4172         2183 :               int ai = 0;
    4173         2183 :               int bi = 1;
    4174         2183 :               slp_tree a = SLP_TREE_CHILDREN (perm)[ai];
    4175         2183 :               slp_tree b = SLP_TREE_CHILDREN (perm)[bi];
    4176         2183 :               unsigned n = SLP_TREE_LANES (perm);
    4177              : 
    4178         2183 :               slp_tree permab = vect_create_new_slp_node (2, VEC_PERM_EXPR);
    4179         2183 :               SLP_TREE_LANES (permab) = n;
    4180         2183 :               SLP_TREE_LANE_PERMUTATION (permab).create (n);
    4181         2183 :               SLP_TREE_VECTYPE (permab) = SLP_TREE_VECTYPE (perm);
    4182              :               /* ???  Should be NULL but that's not expected.  */
    4183         2183 :               SLP_TREE_REPRESENTATIVE (permab) = SLP_TREE_REPRESENTATIVE (perm);
    4184         2183 :               SLP_TREE_CHILDREN (permab).quick_push (a);
    4185         6563 :               for (unsigned k = 0; k < SLP_TREE_LANES (a); ++k)
    4186         2197 :                 SLP_TREE_LANE_PERMUTATION (permab)
    4187         2197 :                   .quick_push (std::make_pair (0, k));
    4188         2183 :               SLP_TREE_CHILDREN (permab).quick_push (b);
    4189         6563 :               for (unsigned k = 0; k < SLP_TREE_LANES (b); ++k)
    4190         2197 :                 SLP_TREE_LANE_PERMUTATION (permab)
    4191         2197 :                   .quick_push (std::make_pair (1, k));
    4192              :               /* Push the do-not-care lanes.  */
    4193         4380 :               for (unsigned k = 0; k < SLP_TREE_LANES (a); ++k)
    4194         2197 :                 SLP_TREE_LANE_PERMUTATION (permab)
    4195         2197 :                   .quick_push (std::make_pair (0, k));
    4196              : 
    4197              :               /* Put the merged node into 'perm', in place of a.  */
    4198         2183 :               SLP_TREE_CHILDREN (perm)[ai] = permab;
    4199              :               /* Adjust the references to b in the permutation
    4200              :                  of perm and to the later children which we'll
    4201              :                  remove.  */
    4202         8774 :               for (unsigned k = 0; k < SLP_TREE_LANES (perm); ++k)
    4203              :                 {
    4204         6591 :                   std::pair<unsigned, unsigned> &p
    4205         6591 :                     = SLP_TREE_LANE_PERMUTATION (perm)[k];
    4206         6591 :                   if (p.first == (unsigned) bi)
    4207              :                     {
    4208         2197 :                       p.first = ai;
    4209         2197 :                       p.second += SLP_TREE_LANES (a);
    4210              :                     }
    4211         4394 :                   else if (p.first > (unsigned) bi)
    4212         2197 :                     p.first--;
    4213              :                 }
    4214         2183 :               SLP_TREE_CHILDREN (perm).ordered_remove (bi);
    4215         2183 :               break;
    4216              :             }
    4217              : 
    4218              :           /* Pick the two nodes with the least number of lanes,
    4219              :              prefer the earliest candidate and maintain ai < bi.  */
    4220              :           int ai = -1;
    4221              :           int bi = -1;
    4222        50446 :           for (unsigned ci = 0; ci < SLP_TREE_CHILDREN (perm).length (); ++ci)
    4223              :             {
    4224        45103 :               if (ai == -1)
    4225         5343 :                 ai = ci;
    4226        39760 :               else if (bi == -1)
    4227         5343 :                 bi = ci;
    4228        34417 :               else if ((SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[ci])
    4229        34417 :                         < SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[ai]))
    4230        34417 :                        || (SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[ci])
    4231        28593 :                            < SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[bi])))
    4232              :                 {
    4233        12538 :                   if (SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[ai])
    4234         6269 :                       <= SLP_TREE_LANES (SLP_TREE_CHILDREN (perm)[bi]))
    4235         2892 :                     bi = ci;
    4236              :                   else
    4237              :                     {
    4238         3377 :                       ai = bi;
    4239         3377 :                       bi = ci;
    4240              :                     }
    4241              :                 }
    4242              :             }
    4243              : 
    4244              :           /* Produce a merge of nodes ai and bi.  */
    4245         5343 :           slp_tree a = SLP_TREE_CHILDREN (perm)[ai];
    4246         5343 :           slp_tree b = SLP_TREE_CHILDREN (perm)[bi];
    4247         5343 :           unsigned n = SLP_TREE_LANES (a) + SLP_TREE_LANES (b);
    4248         5343 :           slp_tree permab = vect_create_new_slp_node (2, VEC_PERM_EXPR);
    4249         5343 :           SLP_TREE_LANES (permab) = n;
    4250         5343 :           SLP_TREE_LANE_PERMUTATION (permab).create (n);
    4251         5343 :           SLP_TREE_VECTYPE (permab) = SLP_TREE_VECTYPE (perm);
    4252              :           /* ???  Should be NULL but that's not expected.  */
    4253         5343 :           SLP_TREE_REPRESENTATIVE (permab) = SLP_TREE_REPRESENTATIVE (perm);
    4254         5343 :           SLP_TREE_CHILDREN (permab).quick_push (a);
    4255        19553 :           for (unsigned k = 0; k < SLP_TREE_LANES (a); ++k)
    4256         8867 :             SLP_TREE_LANE_PERMUTATION (permab)
    4257         8867 :               .quick_push (std::make_pair (0, k));
    4258         5343 :           SLP_TREE_CHILDREN (permab).quick_push (b);
    4259        18829 :           for (unsigned k = 0; k < SLP_TREE_LANES (b); ++k)
    4260         8143 :             SLP_TREE_LANE_PERMUTATION (permab)
    4261         8143 :               .quick_push (std::make_pair (1, k));
    4262              : 
    4263              :           /* Put the merged node into 'perm', in place of a.  */
    4264         5343 :           SLP_TREE_CHILDREN (perm)[ai] = permab;
    4265              :           /* Adjust the references to b in the permutation
    4266              :              of perm and to the later children which we'll
    4267              :              remove.  */
    4268        81265 :           for (unsigned k = 0; k < SLP_TREE_LANES (perm); ++k)
    4269              :             {
    4270        75922 :               std::pair<unsigned, unsigned> &p
    4271        75922 :                 = SLP_TREE_LANE_PERMUTATION (perm)[k];
    4272        75922 :               if (p.first == (unsigned) bi)
    4273              :                 {
    4274         8143 :                   p.first = ai;
    4275         8143 :                   p.second += SLP_TREE_LANES (a);
    4276              :                 }
    4277        67779 :               else if (p.first > (unsigned) bi)
    4278        28686 :                 p.first--;
    4279              :             }
    4280         5343 :           SLP_TREE_CHILDREN (perm).ordered_remove (bi);
    4281              :         }
    4282              :     }
    4283              : 
    4284         8249 :   return node;
    4285              : }
    4286              : 
    4287              : /* Analyze an SLP instance starting from SCALAR_STMTS which are a group
    4288              :    of KIND.  Return true if successful.  SCALAR_STMTS is owned by this
    4289              :    function, REMAIN and ROOT_STMT_INFOS ownership is transferred back to
    4290              :    the caller upon failure.  */
    4291              : 
    4292              : static bool
    4293      2114337 : vect_build_slp_instance (vec_info *vinfo,
    4294              :                          slp_instance_kind kind,
    4295              :                          vec<stmt_vec_info> &scalar_stmts,
    4296              :                          vec<stmt_vec_info> &root_stmt_infos,
    4297              :                          vec<tree> &remain,
    4298              :                          unsigned max_tree_size, unsigned *limit,
    4299              :                          scalar_stmts_to_slp_tree_map_t *bst_map,
    4300              :                          bool force_single_lane)
    4301              : {
    4302              :   /* If there's no budget left bail out early.  */
    4303      2114337 :   if (*limit == 0)
    4304              :     {
    4305        16098 :       scalar_stmts.release ();
    4306        16098 :       return false;
    4307              :     }
    4308              : 
    4309      2098239 :   if (kind == slp_inst_kind_ctor)
    4310              :     {
    4311        15333 :       if (dump_enabled_p ())
    4312           98 :         dump_printf_loc (MSG_NOTE, vect_location,
    4313              :                          "Analyzing vectorizable constructor: %G\n",
    4314           49 :                          root_stmt_infos[0]->stmt);
    4315              :     }
    4316      2082906 :   else if (kind == slp_inst_kind_gcond)
    4317              :     {
    4318       296852 :       if (dump_enabled_p ())
    4319         6222 :         dump_printf_loc (MSG_NOTE, vect_location,
    4320              :                          "Analyzing vectorizable control flow: %G",
    4321         3111 :                          root_stmt_infos[0]->stmt);
    4322              :     }
    4323      1786054 :   else if (kind == slp_inst_kind_bb_reduc)
    4324              :     {
    4325      1390808 :       if (dump_enabled_p ())
    4326         7492 :         dump_printf_loc (MSG_NOTE, vect_location,
    4327              :                          "Analyzing vectorizable BB reduction: %G",
    4328         3746 :                          root_stmt_infos[0]->stmt);
    4329              :     }
    4330              : 
    4331      2098239 :   if (dump_enabled_p ())
    4332              :     {
    4333        27560 :       dump_printf_loc (MSG_NOTE, vect_location,
    4334              :                        "Starting SLP discovery for\n");
    4335        59568 :       for (unsigned i = 0; i < scalar_stmts.length (); ++i)
    4336        64016 :         dump_printf_loc (MSG_NOTE, vect_location,
    4337        32008 :                          "  %G", scalar_stmts[i]->stmt);
    4338              :     }
    4339              : 
    4340              :   /* Build the tree for the SLP instance.  */
    4341      2098239 :   unsigned int group_size = scalar_stmts.length ();
    4342      2098239 :   match_elt_t *matches = XALLOCAVEC (match_elt_t, group_size);
    4343      2098239 :   unsigned tree_size = 0;
    4344              : 
    4345      2098239 :   slp_tree node = NULL;
    4346      2098239 :   if (group_size > 1 && force_single_lane)
    4347              :     {
    4348            0 :       matches[0] = 0;
    4349            0 :       matches[1] = -1;
    4350              :     }
    4351              :   else
    4352      2098239 :     node = vect_build_slp_tree (vinfo, scalar_stmts, matches, limit,
    4353              :                                 &tree_size, bst_map);
    4354      2098239 :   if (node != NULL)
    4355              :     {
    4356              :       /* Create a new SLP instance.  */
    4357       834218 :       slp_instance new_instance = XNEW (class _slp_instance);
    4358       834218 :       SLP_INSTANCE_TREE (new_instance) = node;
    4359       834218 :       SLP_INSTANCE_LOADS (new_instance) = vNULL;
    4360       834218 :       SLP_INSTANCE_ROOT_STMTS (new_instance) = root_stmt_infos;
    4361       834218 :       SLP_INSTANCE_REMAIN_DEFS (new_instance) = remain;
    4362       834218 :       SLP_INSTANCE_KIND (new_instance) = kind;
    4363       834218 :       new_instance->reduc_phis = NULL;
    4364       834218 :       new_instance->cost_vec = vNULL;
    4365       834218 :       new_instance->subgraph_entries = vNULL;
    4366              : 
    4367       834218 :       if (dump_enabled_p ())
    4368        24237 :         dump_printf_loc (MSG_NOTE, vect_location,
    4369              :                          "SLP size %u vs. limit %u.\n",
    4370              :                          tree_size, max_tree_size);
    4371              : 
    4372       834218 :       vinfo->slp_instances.safe_push (new_instance);
    4373              : 
    4374              :       /* ???  We've replaced the old SLP_INSTANCE_GROUP_SIZE with
    4375              :          the number of SLP lanes of the root in a few places.
    4376              :          Verify that assumption holds.  */
    4377       834218 :       gcc_assert (SLP_TREE_LANES (SLP_INSTANCE_TREE (new_instance))
    4378              :                   == group_size);
    4379              : 
    4380       834218 :       if (dump_enabled_p ())
    4381              :         {
    4382        24237 :           if (kind == slp_inst_kind_reduc_group)
    4383         1509 :             dump_printf_loc (MSG_NOTE, vect_location,
    4384              :                              "SLP discovery of size %d reduction group "
    4385              :                              "succeeded\n", group_size);
    4386        24237 :           dump_printf_loc (MSG_NOTE, vect_location,
    4387              :                            "Final SLP tree for instance %p:\n",
    4388              :                            (void *) new_instance);
    4389        24237 :           vect_print_slp_graph (MSG_NOTE, vect_location,
    4390              :                                 SLP_INSTANCE_TREE (new_instance));
    4391              :         }
    4392              : 
    4393       834218 :       return true;
    4394              :     }
    4395              :   /* Failed to SLP.  */
    4396              : 
    4397              :   /* While we arrive here even with slp_inst_kind_store we should only
    4398              :      for group_size == 1.  The code to split store groups is only in
    4399              :      vect_analyze_slp_instance now.  */
    4400      1264021 :   gcc_assert (kind != slp_inst_kind_store || group_size == 1);
    4401              : 
    4402              :   /* For BB vectorization we get failures only in case of the need of
    4403              :      unrolling, as otherwise we'll simply get operands built from scalars.
    4404              :      Iff there is any mismatches in the toplevel stmts those will prevail,
    4405              :      otherwise we get the non-power-of-two tail of the lanes failed.
    4406              :      For BB reductions we mainly want to catch the first case so we pick
    4407              :      a more useful subset of lanes to reduce.  Pick the largest matching
    4408              :      subset of that covers half of the group or more.  */
    4409      1264021 :   if (kind == slp_inst_kind_bb_reduc && matches[0] != -1)
    4410              :     {
    4411       676502 :       unsigned *n_matching = XALLOCAVEC (unsigned, group_size);
    4412       676502 :       memset (n_matching, 0, sizeof (unsigned) * group_size);
    4413      2189758 :       for (unsigned i = 0; i < group_size; ++i)
    4414      1513256 :         if (matches[i] != -2 && matches[i] != -1)
    4415      1276273 :           n_matching[matches[i].v]++;
    4416              :       unsigned largest_i = 0;
    4417      1513256 :       for (unsigned i = 1; i < group_size; ++i)
    4418       836754 :         if (n_matching[i] > n_matching[largest_i])
    4419        62904 :           largest_i = i;
    4420              :       /* Pick the largest matching part and put the rest to remain.  */
    4421       676502 :       if (n_matching[largest_i] >= 2
    4422        50777 :           && n_matching[largest_i] >= group_size / 2)
    4423              :         {
    4424              :           /* As we know the matches[] stmts match up, recursing for
    4425              :              non-power-of-two sizes will just force-fail the tail
    4426              :              for us at hopefully optimal vector size and succesfully
    4427              :              finish discovery.  */
    4428        49413 :           vec<stmt_vec_info> scalar_stmts2;
    4429        49413 :           scalar_stmts2.create (n_matching[largest_i]);
    4430       292694 :           for (unsigned i = 0; i < group_size; ++i)
    4431       193868 :             if (matches[i] == (int)largest_i)
    4432       132230 :               scalar_stmts2.quick_push (scalar_stmts[i]);
    4433              :             else
    4434        61638 :               remain.safe_push
    4435        65624 :                 (gimple_get_lhs (vect_orig_stmt (scalar_stmts[i])->stmt));
    4436        49413 :           if (dump_enabled_p ())
    4437          228 :             dump_printf_loc (MSG_NOTE, vect_location, "Splitting %d "
    4438              :                              "non-matching lanes to scalar remains\n",
    4439          228 :                              scalar_stmts.length () - scalar_stmts2.length ());
    4440        49413 :           scalar_stmts.release ();
    4441        49413 :           return vect_build_slp_instance (vinfo, kind, scalar_stmts2,
    4442              :                                           root_stmt_infos, remain,
    4443              :                                           max_tree_size, limit, bst_map,
    4444              :                                           force_single_lane);
    4445              :         }
    4446              :     }
    4447              : 
    4448              :   /* Free the allocated memory.  */
    4449      1214608 :   scalar_stmts.release ();
    4450              : 
    4451              :   /* Failed to SLP.  */
    4452      1214608 :   if (dump_enabled_p ())
    4453         3209 :     dump_printf_loc (MSG_NOTE, vect_location, "SLP discovery failed\n");
    4454              :   return false;
    4455              : }
    4456              : 
    4457              : /* Analyze an SLP instance starting from a the start of a reduction chain.
    4458              :    Call vect_build_slp_tree to build a tree of packed stmts if possible.
    4459              :    Return FALSE if SLP build fails.  */
    4460              : 
    4461              : static bool
    4462        73600 : vect_analyze_slp_reduc_chain (loop_vec_info vinfo,
    4463              :                               scalar_stmts_to_slp_tree_map_t *bst_map,
    4464              :                               stmt_vec_info scalar_stmt,
    4465              :                               unsigned max_tree_size, unsigned *limit)
    4466              : {
    4467        73600 :   vec<stmt_vec_info> scalar_stmts = vNULL;
    4468              : 
    4469        73600 :   bool fail = false;
    4470              :   /* ???  We could leave operation code checking to SLP discovery.  */
    4471        73600 :   code_helper code = STMT_VINFO_REDUC_CODE (STMT_VINFO_REDUC_DEF
    4472              :                                               (vect_orig_stmt (scalar_stmt)));
    4473        73600 :   bool first = true;
    4474        73600 :   stmt_vec_info next_stmt = scalar_stmt;
    4475        83803 :   do
    4476              :     {
    4477        83803 :       stmt_vec_info stmt = next_stmt;
    4478        83803 :       gimple_match_op op, orig_op;
    4479        83803 :       if (!gimple_extract_op (STMT_VINFO_STMT (stmt), &op))
    4480            0 :         gcc_unreachable ();
    4481       167606 :       tree reduc_def = gimple_arg (STMT_VINFO_STMT (stmt),
    4482        83803 :                                    STMT_VINFO_REDUC_IDX (stmt));
    4483        83803 :       next_stmt = vect_stmt_to_vectorize (vinfo->lookup_def (reduc_def));
    4484        83803 :       gcc_assert (is_a <gphi *> (STMT_VINFO_STMT (next_stmt))
    4485              :                   || STMT_VINFO_REDUC_IDX (next_stmt) != -1);
    4486        89767 :       if (!gimple_extract_op (STMT_VINFO_STMT (vect_orig_stmt (stmt)),
    4487              :                               &orig_op))
    4488            0 :         gcc_unreachable ();
    4489        83803 :       if (CONVERT_EXPR_CODE_P (op.code)
    4490         4999 :           && tree_nop_conversion_p (op.type, TREE_TYPE (op.ops[0]))
    4491        88790 :           && (first
    4492         2498 :               || is_a <gphi *> (STMT_VINFO_STMT (next_stmt))))
    4493              :         ;
    4494        78876 :       else if (code != orig_op.code)
    4495              :         {
    4496         2728 :           fail = true;
    4497         2728 :           break;
    4498              :         }
    4499              :       else
    4500        76148 :         scalar_stmts.safe_push (stmt);
    4501        81075 :       first = false;
    4502              :     }
    4503        81075 :   while (!is_a <gphi *> (STMT_VINFO_STMT (next_stmt)));
    4504        73600 :   if (fail)
    4505         2728 :     return false;
    4506              : 
    4507              :   /* When the SSA def chain through reduc-idx does not form a natural
    4508              :      reduction chain try to linearize an associative operation manually.  */
    4509        70872 :   if (scalar_stmts.length () == 1
    4510        68202 :       && code.is_tree_code ()
    4511        62130 :       && associative_tree_code ((tree_code)code)
    4512              :       /* We may not associate if a fold-left reduction is required.  */
    4513       131572 :       && !needs_fold_left_reduction_p (TREE_TYPE (gimple_get_lhs
    4514              :                                                     (scalar_stmts[0]->stmt)),
    4515              :                                        code))
    4516              :     {
    4517              :       /* Remember a stmt with the actual reduction operation.  */
    4518        57426 :       stmt_vec_info reduc_scalar_stmt = scalar_stmts[0];
    4519        57426 :       auto_vec<chain_op_t> chain;
    4520        57426 :       auto_vec<std::pair<tree_code, gimple *> > worklist;
    4521        57426 :       gimple *op_stmt = NULL, *other_op_stmt = NULL;
    4522        57426 :       if (is_a <gassign *> (scalar_stmts[0]->stmt)
    4523              :           /* We cannot linearize an operation that vect_slp_linearize_chain
    4524              :              would not put on its worklist.  */
    4525        57426 :           && gimple_assign_rhs_code (scalar_stmts[0]->stmt) == (tree_code)code)
    4526              :         {
    4527        56770 :           vect_slp_linearize_chain (vinfo, worklist, chain, (tree_code)code,
    4528        56770 :                                     scalar_stmts[0]->stmt, op_stmt,
    4529              :                                     other_op_stmt,
    4530              :                                     NULL);
    4531              : 
    4532        56770 :           scalar_stmts.truncate (0);
    4533        56770 :           stmt_vec_info tail = NULL;
    4534       284151 :           for (auto el : chain)
    4535              :             {
    4536       114140 :               if (el.dt == vect_external_def
    4537       114140 :                   || el.dt == vect_constant_def
    4538       114140 :                   || el.code != (tree_code) code)
    4539              :                 {
    4540          299 :                   scalar_stmts.release ();
    4541          299 :                   return false;
    4542              :                 }
    4543       113841 :               stmt_vec_info stmt = vinfo->lookup_def (el.op);
    4544       113841 :               if (STMT_VINFO_REDUC_IDX (stmt) != -1
    4545       111555 :                   || STMT_VINFO_REDUC_DEF (stmt))
    4546              :                 {
    4547        56680 :                   gcc_assert (tail == NULL);
    4548        56680 :                   tail = stmt;
    4549        56680 :                   continue;
    4550              :                 }
    4551        57161 :               scalar_stmts.safe_push (stmt);
    4552              :             }
    4553        56471 :           gcc_assert (tail);
    4554              :         }
    4555              : 
    4556              :       /* When this linearization didn't produce a chain see if stripping
    4557              :          a wrapping sign conversion produces one.  */
    4558        57127 :       if (scalar_stmts.length () == 1
    4559        57127 :           && (code == PLUS_EXPR || code == MULT_EXPR || code == BIT_IOR_EXPR
    4560              :               || code == BIT_AND_EXPR || code == BIT_XOR_EXPR))
    4561              :         {
    4562        55310 :           gimple *stmt = scalar_stmts[0]->stmt;
    4563        55310 :           if (!is_gimple_assign (stmt)
    4564        54150 :               || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
    4565         4724 :               || TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME
    4566        60034 :               || !tree_nop_conversion_p (TREE_TYPE (gimple_assign_lhs (stmt)),
    4567         4724 :                                          TREE_TYPE (gimple_assign_rhs1 (stmt))))
    4568              :             {
    4569        53530 :               scalar_stmts.release ();
    4570        53530 :               return false;
    4571              :             }
    4572         1780 :           stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
    4573         1780 :           if (!is_gimple_assign (stmt)
    4574         1780 :               || gimple_assign_rhs_code (stmt) != (tree_code)code)
    4575              :             {
    4576         1762 :               scalar_stmts.release ();
    4577         1762 :               return false;
    4578              :             }
    4579           18 :           chain.truncate (0);
    4580           18 :           vect_slp_linearize_chain (vinfo, worklist, chain, (tree_code)code,
    4581              :                                     stmt, op_stmt, other_op_stmt, NULL);
    4582              : 
    4583           18 :           scalar_stmts.truncate (0);
    4584           18 :           stmt_vec_info tail = NULL;
    4585           88 :           for (auto el : chain)
    4586              :             {
    4587           42 :               if (el.dt == vect_external_def
    4588           42 :                   || el.dt == vect_constant_def
    4589           42 :                   || el.code != (tree_code) code)
    4590              :                 {
    4591            8 :                   scalar_stmts.release ();
    4592            8 :                   return false;
    4593              :                 }
    4594           34 :               stmt_vec_info stmt = vinfo->lookup_def (el.op);
    4595           34 :               if (STMT_VINFO_REDUC_IDX (stmt) != -1
    4596           34 :                   || STMT_VINFO_REDUC_DEF (stmt))
    4597              :                 {
    4598            0 :                   gcc_assert (tail == NULL);
    4599            0 :                   tail = stmt;
    4600            0 :                   continue;
    4601              :                 }
    4602           34 :               scalar_stmts.safe_push (stmt);
    4603              :             }
    4604              :           /* Unlike the above this does not include the reduction SSA
    4605              :              cycle.  */
    4606           10 :           gcc_assert (!tail);
    4607              :         }
    4608              : 
    4609         1827 :       if (scalar_stmts.length () < 2)
    4610              :         {
    4611         1697 :           scalar_stmts.release ();
    4612         1697 :           return false;
    4613              :         }
    4614              : 
    4615          130 :       if (dump_enabled_p ())
    4616              :         {
    4617           40 :           dump_printf_loc (MSG_NOTE, vect_location,
    4618              :                            "Starting SLP discovery of reduction chain for\n");
    4619          164 :           for (unsigned i = 0; i < scalar_stmts.length (); ++i)
    4620          248 :             dump_printf_loc (MSG_NOTE, vect_location,
    4621          124 :                              "  %G", scalar_stmts[i]->stmt);
    4622              :         }
    4623              : 
    4624          130 :       unsigned int group_size = scalar_stmts.length ();
    4625          130 :       match_elt_t *matches = XALLOCAVEC (match_elt_t, group_size);
    4626          130 :       unsigned tree_size = 0;
    4627          130 :       slp_tree node = vect_build_slp_tree (vinfo, scalar_stmts, matches, limit,
    4628          130 :                                            &tree_size, bst_map);
    4629          130 :       if (!node)
    4630              :         {
    4631           46 :           scalar_stmts.release ();
    4632           46 :           return false;
    4633              :         }
    4634              : 
    4635           84 :       unsigned cycle_id = vinfo->reduc_infos.length ();
    4636           84 :       vect_reduc_info reduc_info = new vect_reduc_info_s ();
    4637           84 :       vinfo->reduc_infos.safe_push (reduc_info);
    4638           84 :       VECT_REDUC_INFO_DEF_TYPE (reduc_info) = STMT_VINFO_DEF_TYPE (next_stmt);
    4639           84 :       VECT_REDUC_INFO_TYPE (reduc_info) = STMT_VINFO_REDUC_TYPE (next_stmt);
    4640           84 :       VECT_REDUC_INFO_CODE (reduc_info) = STMT_VINFO_REDUC_CODE (next_stmt);
    4641           84 :       VECT_REDUC_INFO_FN (reduc_info) = IFN_LAST;
    4642           84 :       reduc_info->is_reduc_chain = true;
    4643              : 
    4644              :       /* Build the node for the PHI and possibly the conversions.  */
    4645           84 :       slp_tree phis = vect_create_new_slp_node (2, ERROR_MARK);
    4646           84 :       SLP_TREE_REPRESENTATIVE (phis) = next_stmt;
    4647           84 :       phis->cycle_info.id = cycle_id;
    4648           84 :       SLP_TREE_LANES (phis) = group_size;
    4649           84 :       if (reduc_scalar_stmt == scalar_stmt)
    4650           80 :         SLP_TREE_VECTYPE (phis) = SLP_TREE_VECTYPE (node);
    4651              :       else
    4652            4 :         SLP_TREE_VECTYPE (phis)
    4653            4 :           = signed_or_unsigned_type_for (TYPE_UNSIGNED
    4654              :                                            (TREE_TYPE (gimple_get_lhs
    4655              :                                                          (scalar_stmt->stmt))),
    4656              :                                          SLP_TREE_VECTYPE (node));
    4657              :       /* ???  vect_cse_slp_nodes cannot cope with cycles without any
    4658              :          SLP_TREE_SCALAR_STMTS.  */
    4659           84 :       SLP_TREE_SCALAR_STMTS (phis).create (group_size);
    4660          501 :       for (unsigned i = 0; i < group_size; ++i)
    4661          333 :         SLP_TREE_SCALAR_STMTS (phis).quick_push (next_stmt);
    4662              : 
    4663           84 :       slp_tree op_input = phis;
    4664           84 :       if (reduc_scalar_stmt != scalar_stmt)
    4665              :         {
    4666            4 :           slp_tree conv = vect_create_new_slp_node (1, ERROR_MARK);
    4667            4 :           SLP_TREE_REPRESENTATIVE (conv)
    4668            4 :             = vinfo->lookup_def (gimple_arg (reduc_scalar_stmt->stmt,
    4669            4 :                                              STMT_VINFO_REDUC_IDX
    4670              :                                                (reduc_scalar_stmt)));
    4671            4 :           SLP_TREE_CHILDREN (conv).quick_push (phis);
    4672            4 :           conv->cycle_info.id = cycle_id;
    4673            4 :           SLP_TREE_REDUC_IDX (conv) = 0;
    4674            4 :           SLP_TREE_LANES (conv) = group_size;
    4675            4 :           SLP_TREE_VECTYPE (conv) = SLP_TREE_VECTYPE (node);
    4676            4 :           SLP_TREE_SCALAR_STMTS (conv) = vNULL;
    4677            4 :           op_input = conv;
    4678              :         }
    4679              : 
    4680           84 :       slp_tree reduc = vect_create_new_slp_node (2, ERROR_MARK);
    4681           84 :       SLP_TREE_REPRESENTATIVE (reduc) = reduc_scalar_stmt;
    4682           84 :       SLP_TREE_CHILDREN (reduc).quick_push (op_input);
    4683           84 :       SLP_TREE_CHILDREN (reduc).quick_push (node);
    4684           84 :       reduc->cycle_info.id = cycle_id;
    4685           84 :       SLP_TREE_REDUC_IDX (reduc) = 0;
    4686           84 :       SLP_TREE_LANES (reduc) = group_size;
    4687           84 :       SLP_TREE_VECTYPE (reduc) = SLP_TREE_VECTYPE (node);
    4688              :       /* ???  For the reduction epilogue we need a live lane.  */
    4689           84 :       SLP_TREE_SCALAR_STMTS (reduc).create (group_size);
    4690           84 :       SLP_TREE_SCALAR_STMTS (reduc).quick_push (reduc_scalar_stmt);
    4691          417 :       for (unsigned i = 1; i < group_size; ++i)
    4692          249 :         SLP_TREE_SCALAR_STMTS (reduc).quick_push (NULL);
    4693              : 
    4694           84 :       if (reduc_scalar_stmt != scalar_stmt)
    4695              :         {
    4696            4 :           slp_tree conv = vect_create_new_slp_node (1, ERROR_MARK);
    4697            4 :           SLP_TREE_REPRESENTATIVE (conv) = scalar_stmt;
    4698            4 :           SLP_TREE_CHILDREN (conv).quick_push (reduc);
    4699            4 :           conv->cycle_info.id = cycle_id;
    4700            4 :           SLP_TREE_REDUC_IDX (conv) = 0;
    4701            4 :           SLP_TREE_LANES (conv) = group_size;
    4702            4 :           SLP_TREE_VECTYPE (conv) = SLP_TREE_VECTYPE (phis);
    4703              :           /* ???  For the reduction epilogue we need a live lane.  */
    4704            4 :           SLP_TREE_SCALAR_STMTS (conv).create (group_size);
    4705            4 :           SLP_TREE_SCALAR_STMTS (conv).quick_push (scalar_stmt);
    4706           12 :           for (unsigned i = 1; i < group_size; ++i)
    4707            4 :             SLP_TREE_SCALAR_STMTS (conv).quick_push (NULL);
    4708            4 :           reduc = conv;
    4709              :         }
    4710              : 
    4711           84 :       edge le = loop_latch_edge (LOOP_VINFO_LOOP (vinfo));
    4712           84 :       SLP_TREE_CHILDREN (phis).quick_push (NULL);
    4713           84 :       SLP_TREE_CHILDREN (phis).quick_push (NULL);
    4714           84 :       SLP_TREE_CHILDREN (phis)[le->dest_idx] = reduc;
    4715           84 :       SLP_TREE_REF_COUNT (reduc)++;
    4716              : 
    4717              :       /* Create a new SLP instance.  */
    4718           84 :       slp_instance new_instance = XNEW (class _slp_instance);
    4719           84 :       SLP_INSTANCE_TREE (new_instance) = reduc;
    4720           84 :       SLP_INSTANCE_LOADS (new_instance) = vNULL;
    4721           84 :       SLP_INSTANCE_ROOT_STMTS (new_instance) = vNULL;
    4722           84 :       SLP_INSTANCE_REMAIN_DEFS (new_instance) = vNULL;
    4723           84 :       SLP_INSTANCE_KIND (new_instance) = slp_inst_kind_reduc_chain;
    4724           84 :       new_instance->reduc_phis = NULL;
    4725           84 :       new_instance->cost_vec = vNULL;
    4726           84 :       new_instance->subgraph_entries = vNULL;
    4727              : 
    4728           84 :       vinfo->slp_instances.safe_push (new_instance);
    4729              : 
    4730           84 :       if (dump_enabled_p ())
    4731              :         {
    4732           30 :           dump_printf_loc (MSG_NOTE, vect_location,
    4733              :                            "Final SLP tree for instance %p:\n",
    4734              :                            (void *) new_instance);
    4735           30 :           vect_print_slp_graph (MSG_NOTE, vect_location,
    4736              :                                 SLP_INSTANCE_TREE (new_instance));
    4737              :         }
    4738              : 
    4739              :       return true;
    4740        57426 :     }
    4741              : 
    4742        13446 :   if (scalar_stmts.length () <= 1)
    4743              :     {
    4744        10782 :       scalar_stmts.release ();
    4745        10782 :       return false;
    4746              :     }
    4747              : 
    4748         2664 :   scalar_stmts.reverse ();
    4749         2664 :   stmt_vec_info reduc_phi_info = next_stmt;
    4750              : 
    4751              :   /* Build the tree for the SLP instance.  */
    4752         2664 :   vec<stmt_vec_info> root_stmt_infos = vNULL;
    4753         2664 :   vec<tree> remain = vNULL;
    4754              : 
    4755         2664 :   if (dump_enabled_p ())
    4756              :     {
    4757          219 :       dump_printf_loc (MSG_NOTE, vect_location,
    4758              :                        "Starting SLP discovery of reduction chain for\n");
    4759         1143 :       for (unsigned i = 0; i < scalar_stmts.length (); ++i)
    4760         1848 :         dump_printf_loc (MSG_NOTE, vect_location,
    4761          924 :                          "  %G", scalar_stmts[i]->stmt);
    4762              :     }
    4763              : 
    4764              :   /* Build the tree for the SLP instance.  */
    4765         2664 :   unsigned int group_size = scalar_stmts.length ();
    4766         2664 :   match_elt_t *matches = XALLOCAVEC (match_elt_t, group_size);
    4767         2664 :   unsigned tree_size = 0;
    4768              : 
    4769              :   /* ???  We need this only for SLP discovery.  */
    4770        10528 :   for (unsigned i = 0; i < scalar_stmts.length (); ++i)
    4771         7864 :     REDUC_GROUP_FIRST_ELEMENT (scalar_stmts[i]) = scalar_stmts[0];
    4772              : 
    4773         2664 :   slp_tree node = vect_build_slp_tree (vinfo, scalar_stmts, matches, limit,
    4774         2664 :                                        &tree_size, bst_map);
    4775              : 
    4776        10528 :   for (unsigned i = 0; i < scalar_stmts.length (); ++i)
    4777         7864 :     REDUC_GROUP_FIRST_ELEMENT (scalar_stmts[i]) = NULL;
    4778              : 
    4779         2664 :   if (node != NULL)
    4780              :     {
    4781              :       /* Create a new SLP instance.  */
    4782         2385 :       slp_instance new_instance = XNEW (class _slp_instance);
    4783         2385 :       SLP_INSTANCE_TREE (new_instance) = node;
    4784         2385 :       SLP_INSTANCE_LOADS (new_instance) = vNULL;
    4785         2385 :       SLP_INSTANCE_ROOT_STMTS (new_instance) = root_stmt_infos;
    4786         2385 :       SLP_INSTANCE_REMAIN_DEFS (new_instance) = remain;
    4787         2385 :       SLP_INSTANCE_KIND (new_instance) = slp_inst_kind_reduc_chain;
    4788         2385 :       new_instance->reduc_phis = NULL;
    4789         2385 :       new_instance->cost_vec = vNULL;
    4790         2385 :       new_instance->subgraph_entries = vNULL;
    4791              : 
    4792         2385 :       vect_reduc_info reduc_info = info_for_reduction (vinfo, node);
    4793         2385 :       reduc_info->is_reduc_chain = true;
    4794              : 
    4795         2385 :       if (dump_enabled_p ())
    4796          153 :         dump_printf_loc (MSG_NOTE, vect_location,
    4797              :                          "SLP size %u vs. limit %u.\n",
    4798              :                          tree_size, max_tree_size);
    4799              : 
    4800              :       /* Fixup SLP reduction chains.  If this is a reduction chain with
    4801              :          a conversion in front amend the SLP tree with a node for that.  */
    4802         2385 :       gimple *scalar_def = STMT_VINFO_REDUC_DEF (reduc_phi_info)->stmt;
    4803         2385 :       if (is_gimple_assign (scalar_def)
    4804         2385 :           && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (scalar_def)))
    4805              :         {
    4806           43 :           stmt_vec_info conv_info = vect_stmt_to_vectorize
    4807           43 :                                         (STMT_VINFO_REDUC_DEF (reduc_phi_info));
    4808           43 :           scalar_stmts = vNULL;
    4809           43 :           scalar_stmts.create (group_size);
    4810          178 :           for (unsigned i = 0; i < group_size; ++i)
    4811           92 :             scalar_stmts.quick_push (conv_info);
    4812           43 :           slp_tree conv = vect_create_new_slp_node (scalar_stmts, 1);
    4813           43 :           SLP_TREE_VECTYPE (conv)
    4814           43 :             = get_vectype_for_scalar_type (vinfo,
    4815           43 :                                            TREE_TYPE
    4816              :                                              (gimple_assign_lhs (scalar_def)),
    4817              :                                            group_size);
    4818           43 :           SLP_TREE_REDUC_IDX (conv) = 0;
    4819           43 :           conv->cycle_info.id = node->cycle_info.id;
    4820           43 :           SLP_TREE_CHILDREN (conv).quick_push (node);
    4821           43 :           SLP_INSTANCE_TREE (new_instance) = conv;
    4822              :         }
    4823              :       /* Fill the backedge child of the PHI SLP node.  The
    4824              :          general matching code cannot find it because the
    4825              :          scalar code does not reflect how we vectorize the
    4826              :          reduction.  */
    4827         2385 :       use_operand_p use_p;
    4828         2385 :       imm_use_iterator imm_iter;
    4829         2385 :       class loop *loop = LOOP_VINFO_LOOP (vinfo);
    4830         9058 :       FOR_EACH_IMM_USE_FAST (use_p, imm_iter,
    4831              :                              gimple_get_lhs (scalar_def))
    4832              :         /* There are exactly two non-debug uses, the reduction
    4833              :            PHI and the loop-closed PHI node.  */
    4834         6673 :         if (!is_gimple_debug (USE_STMT (use_p))
    4835         6673 :             && gimple_bb (USE_STMT (use_p)) == loop->header)
    4836              :           {
    4837         2385 :             auto_vec<stmt_vec_info, 64> phis (group_size);
    4838         2385 :             stmt_vec_info phi_info = vinfo->lookup_stmt (USE_STMT (use_p));
    4839         9541 :             for (unsigned i = 0; i < group_size; ++i)
    4840         7156 :               phis.quick_push (phi_info);
    4841         2385 :             slp_tree *phi_node = bst_map->get (phis);
    4842         2385 :             unsigned dest_idx = loop_latch_edge (loop)->dest_idx;
    4843         4770 :             SLP_TREE_CHILDREN (*phi_node)[dest_idx]
    4844         2385 :               = SLP_INSTANCE_TREE (new_instance);
    4845         2385 :             SLP_INSTANCE_TREE (new_instance)->refcnt++;
    4846         2385 :           }
    4847              : 
    4848         2385 :       vinfo->slp_instances.safe_push (new_instance);
    4849              : 
    4850              :       /* ???  We've replaced the old SLP_INSTANCE_GROUP_SIZE with
    4851              :          the number of SLP lanes of the root in a few places.
    4852              :          Verify that assumption holds.  */
    4853         2385 :       gcc_assert (SLP_TREE_LANES (SLP_INSTANCE_TREE (new_instance))
    4854              :                   == group_size);
    4855              : 
    4856         2385 :       if (dump_enabled_p ())
    4857              :         {
    4858          153 :           dump_printf_loc (MSG_NOTE, vect_location,
    4859              :                            "Final SLP tree for instance %p:\n",
    4860              :                            (void *) new_instance);
    4861          153 :           vect_print_slp_graph (MSG_NOTE, vect_location,
    4862              :                                 SLP_INSTANCE_TREE (new_instance));
    4863              :         }
    4864              : 
    4865         2385 :       return true;
    4866              :     }
    4867              : 
    4868              :   /* Failed to SLP.  */
    4869          279 :   scalar_stmts.release ();
    4870          279 :   if (dump_enabled_p ())
    4871           66 :     dump_printf_loc (MSG_NOTE, vect_location,
    4872              :                      "SLP discovery of reduction chain failed\n");
    4873              :   return false;
    4874              : }
    4875              : 
    4876              : /* Analyze an SLP instance starting from SCALAR_STMTS which are a group
    4877              :    of KIND.  Return true if successful.  */
    4878              : 
    4879              : static bool
    4880       100793 : vect_analyze_slp_reduction (loop_vec_info vinfo,
    4881              :                             stmt_vec_info scalar_stmt,
    4882              :                             unsigned max_tree_size, unsigned *limit,
    4883              :                             scalar_stmts_to_slp_tree_map_t *bst_map,
    4884              :                             bool force_single_lane)
    4885              : {
    4886       100793 :   slp_instance_kind kind = slp_inst_kind_reduc_group;
    4887              : 
    4888              :   /* Try to gather a reduction chain.  Only attempt if there's budget left
    4889              :      since chain analysis may build multi-lane trees that consume limit.  */
    4890       100793 :   if (! force_single_lane
    4891        73885 :       && *limit != 0
    4892        73885 :       && STMT_VINFO_DEF_TYPE (scalar_stmt) == vect_reduction_def
    4893       174393 :       && vect_analyze_slp_reduc_chain (vinfo, bst_map, scalar_stmt,
    4894              :                                        max_tree_size, limit))
    4895              :     return true;
    4896              : 
    4897        98324 :   vec<stmt_vec_info> scalar_stmts;
    4898        98324 :   scalar_stmts.create (1);
    4899        98324 :   scalar_stmts.quick_push (scalar_stmt);
    4900              : 
    4901        98324 :   if (dump_enabled_p ())
    4902              :     {
    4903         3945 :       dump_printf_loc (MSG_NOTE, vect_location,
    4904              :                        "Starting SLP discovery for\n");
    4905         7890 :       for (unsigned i = 0; i < scalar_stmts.length (); ++i)
    4906         7890 :         dump_printf_loc (MSG_NOTE, vect_location,
    4907         3945 :                          "  %G", scalar_stmts[i]->stmt);
    4908              :     }
    4909              : 
    4910              :   /* Build the tree for the SLP instance.  */
    4911        98324 :   unsigned int group_size = scalar_stmts.length ();
    4912        98324 :   match_elt_t *matches = XALLOCAVEC (match_elt_t, group_size);
    4913        98324 :   unsigned tree_size = 0;
    4914              : 
    4915        98324 :   slp_tree node = vect_build_slp_tree (vinfo, scalar_stmts, matches, limit,
    4916              :                                        &tree_size, bst_map);
    4917        98324 :   if (node != NULL)
    4918              :     {
    4919              :       /* Create a new SLP instance.  */
    4920        96428 :       slp_instance new_instance = XNEW (class _slp_instance);
    4921        96428 :       SLP_INSTANCE_TREE (new_instance) = node;
    4922        96428 :       SLP_INSTANCE_LOADS (new_instance) = vNULL;
    4923        96428 :       SLP_INSTANCE_ROOT_STMTS (new_instance) = vNULL;
    4924        96428 :       SLP_INSTANCE_REMAIN_DEFS (new_instance) = vNULL;
    4925        96428 :       SLP_INSTANCE_KIND (new_instance) = kind;
    4926        96428 :       new_instance->reduc_phis = NULL;
    4927        96428 :       new_instance->cost_vec = vNULL;
    4928        96428 :       new_instance->subgraph_entries = vNULL;
    4929              : 
    4930        96428 :       if (dump_enabled_p ())
    4931         3868 :         dump_printf_loc (MSG_NOTE, vect_location,
    4932              :                          "SLP size %u vs. limit %u.\n",
    4933              :                          tree_size, max_tree_size);
    4934              : 
    4935        96428 :       vinfo->slp_instances.safe_push (new_instance);
    4936              : 
    4937              :       /* ???  We've replaced the old SLP_INSTANCE_GROUP_SIZE with
    4938              :          the number of SLP lanes of the root in a few places.
    4939              :          Verify that assumption holds.  */
    4940        96428 :       gcc_assert (SLP_TREE_LANES (SLP_INSTANCE_TREE (new_instance))
    4941              :                   == group_size);
    4942              : 
    4943        96428 :       if (dump_enabled_p ())
    4944              :         {
    4945         3868 :           dump_printf_loc (MSG_NOTE, vect_location,
    4946              :                            "Final SLP tree for instance %p:\n",
    4947              :                            (void *) new_instance);
    4948         3868 :           vect_print_slp_graph (MSG_NOTE, vect_location,
    4949              :                                 SLP_INSTANCE_TREE (new_instance));
    4950              :         }
    4951              : 
    4952        96428 :       return true;
    4953              :     }
    4954              :   /* Failed to SLP.  */
    4955              : 
    4956              :   /* Free the allocated memory.  */
    4957         1896 :   scalar_stmts.release ();
    4958              : 
    4959              :   /* Failed to SLP.  */
    4960         1896 :   if (dump_enabled_p ())
    4961           77 :     dump_printf_loc (MSG_NOTE, vect_location, "SLP discovery failed\n");
    4962              :   return false;
    4963              : }
    4964              : 
    4965              : /* Analyze a single SLP reduction group.  If successful add a SLP instance
    4966              :    for it and return true, otherwise return false and have *MATCHES
    4967              :    populated.  */
    4968              : 
    4969              : static bool
    4970        24242 : vect_analyze_slp_reduction_group (loop_vec_info loop_vinfo,
    4971              :                                   vec<stmt_vec_info> scalar_stmts,
    4972              :                                   scalar_stmts_to_slp_tree_map_t *bst_map,
    4973              :                                   unsigned max_tree_size, unsigned *limit,
    4974              :                                   match_elt_t *matches)
    4975              : {
    4976              :   /* Try to form a reduction group.  Size-1 groups are not suitable
    4977              :      for SLP reduction and should fall back to single-lane reduction.  */
    4978        24242 :   unsigned int group_size = scalar_stmts.length ();
    4979        24242 :   if (group_size <= 1)
    4980              :     return false;
    4981        17523 :   if (!matches)
    4982         4547 :     matches = XALLOCAVEC (match_elt_t, group_size);
    4983        17523 :   unsigned tree_size = 0;
    4984        17523 :   slp_tree node = vect_build_slp_tree (loop_vinfo, scalar_stmts, matches, limit,
    4985              :                                        &tree_size, bst_map);
    4986        17523 :   if (!node)
    4987              :     return false;
    4988              : 
    4989              :   /* Create a new SLP instance.  */
    4990         2784 :   slp_instance new_instance = XNEW (class _slp_instance);
    4991         2784 :   SLP_INSTANCE_TREE (new_instance) = node;
    4992         2784 :   SLP_INSTANCE_LOADS (new_instance) = vNULL;
    4993         2784 :   SLP_INSTANCE_ROOT_STMTS (new_instance) = vNULL;
    4994         2784 :   SLP_INSTANCE_REMAIN_DEFS (new_instance) = vNULL;
    4995         2784 :   SLP_INSTANCE_KIND (new_instance) = slp_inst_kind_reduc_group;
    4996         2784 :   new_instance->reduc_phis = NULL;
    4997         2784 :   new_instance->cost_vec = vNULL;
    4998         2784 :   new_instance->subgraph_entries = vNULL;
    4999              : 
    5000         2784 :   if (dump_enabled_p ())
    5001          203 :     dump_printf_loc (MSG_NOTE, vect_location,
    5002              :                      "SLP size %u vs. limit %u.\n",
    5003              :                      tree_size, max_tree_size);
    5004              : 
    5005         2784 :   loop_vinfo->slp_instances.safe_push (new_instance);
    5006              : 
    5007              :   /* ???  We've replaced the old SLP_INSTANCE_GROUP_SIZE with
    5008              :      the number of SLP lanes of the root in a few places.
    5009              :      Verify that assumption holds.  */
    5010         2784 :   gcc_assert (SLP_TREE_LANES (SLP_INSTANCE_TREE (new_instance))
    5011              :               == group_size);
    5012              : 
    5013         2784 :   if (dump_enabled_p ())
    5014              :     {
    5015          203 :       dump_printf_loc (MSG_NOTE, vect_location,
    5016              :                        "SLP discovery of size %d reduction group "
    5017              :                        "succeeded\n", group_size);
    5018          203 :       dump_printf_loc (MSG_NOTE, vect_location,
    5019              :                        "Final SLP tree for instance %p:\n",
    5020              :                        (void *) new_instance);
    5021          203 :       vect_print_slp_graph (MSG_NOTE, vect_location,
    5022              :                             SLP_INSTANCE_TREE (new_instance));
    5023              :     }
    5024              : 
    5025              :   return true;
    5026              : }
    5027              : 
    5028              : /* Analyze reductions in LOOP_VINFO and populate SLP instances
    5029              :    accordingly.  Returns false if something fails.  */
    5030              : 
    5031              : static bool
    5032       520454 : vect_analyze_slp_reductions (loop_vec_info loop_vinfo,
    5033              :                              unsigned max_tree_size, unsigned *limit,
    5034              :                              scalar_stmts_to_slp_tree_map_t *bst_map,
    5035              :                              bool force_single_lane)
    5036              : {
    5037       520454 :   if (loop_vinfo->reductions.is_empty ())
    5038              :     return true;
    5039              : 
    5040              :   /* Collect reduction statements we can combine into
    5041              :      a SLP reduction.  */
    5042        74884 :   vec<stmt_vec_info> scalar_stmts;
    5043        74884 :   scalar_stmts.create (loop_vinfo->reductions.length ());
    5044       331877 :   for (auto next_info : loop_vinfo->reductions)
    5045              :     {
    5046       107225 :       next_info = vect_stmt_to_vectorize (next_info);
    5047       107225 :       if ((STMT_VINFO_RELEVANT_P (next_info)
    5048           14 :            || STMT_VINFO_LIVE_P (next_info))
    5049              :           /* ???  Make sure we didn't skip a conversion around a
    5050              :              reduction path.  In that case we'd have to reverse
    5051              :              engineer that conversion stmt following the chain using
    5052              :              reduc_idx and from the PHI using reduc_def.  */
    5053       107211 :           && (STMT_VINFO_DEF_TYPE (next_info) == vect_reduction_def
    5054       107211 :               || (STMT_VINFO_DEF_TYPE (next_info)
    5055              :                   == vect_double_reduction_def)))
    5056              :         {
    5057              :           /* Do not discover SLP reductions combining lane-reducing
    5058              :              ops, that will fail later.  */
    5059       107211 :           if (!force_single_lane
    5060       107211 :               && !lane_reducing_stmt_p (STMT_VINFO_STMT (next_info)))
    5061        79588 :             scalar_stmts.quick_push (next_info);
    5062              :           /* Do SLP discovery for single-lane reductions.  */
    5063        27623 :           else if (! vect_analyze_slp_reduction (loop_vinfo, next_info,
    5064              :                                                  max_tree_size, limit,
    5065              :                                                  bst_map,
    5066              :                                                  force_single_lane))
    5067              :             {
    5068            0 :               scalar_stmts.release ();
    5069            0 :               return false;
    5070              :             }
    5071              :         }
    5072              :     }
    5073              : 
    5074        74884 :   if (scalar_stmts.length () > 1)
    5075              :     {
    5076              :       /* Try to form a reduction group.  */
    5077         4675 :       unsigned int group_size = scalar_stmts.length ();
    5078         4675 :       match_elt_t *matches = XALLOCAVEC (match_elt_t, group_size);
    5079         4675 :       if (vect_analyze_slp_reduction_group (loop_vinfo, scalar_stmts, bst_map,
    5080              :                                             max_tree_size, limit, matches))
    5081         1601 :         return true;
    5082              : 
    5083              :       /* When analysis as a single SLP reduction group failed try to
    5084              :          form sub-groups by collecting matching lanes.  Do not recurse
    5085              :          that on failure (to limit compile-time costs), but recurse
    5086              :          for the initial non-matching parts.  Everything not covered
    5087              :          by a sub-group gets single-reduction treatment.  */
    5088              :       /* ???  Improve this with the matches[] improvements.  */
    5089         3526 :       vec<stmt_vec_info> cands = vNULL;
    5090        11397 :       while (matches[0] == 0)
    5091              :         {
    5092        11266 :           cands.truncate (0);
    5093        11266 :           cands.reserve (group_size, true);
    5094        99737 :           for (unsigned i = 0; i < group_size; ++i)
    5095        77205 :             if (matches[i] == 0)
    5096        19596 :               cands.quick_push (scalar_stmts[i]);
    5097              : 
    5098              :           /* Try to form a reduction group.  */
    5099        11266 :           if (vect_analyze_slp_reduction_group (loop_vinfo, cands, bst_map,
    5100              :                                                 max_tree_size, limit, NULL))
    5101         1205 :             cands = vNULL;
    5102              :           else
    5103              :             {
    5104              :               /* Do SLP discovery for single-lane reductions.  */
    5105        47319 :               for (auto stmt_info : cands)
    5106        17158 :                 if (! vect_analyze_slp_reduction (loop_vinfo,
    5107              :                                                   vect_stmt_to_vectorize
    5108              :                                                     (stmt_info),
    5109              :                                                   max_tree_size, limit,
    5110              :                                                   bst_map, force_single_lane))
    5111              :                   {
    5112           22 :                     scalar_stmts.release ();
    5113           22 :                     cands.release ();
    5114           22 :                     return false;
    5115              :                   }
    5116              :             }
    5117              :           /* Remove the handled stmts from scalar_stmts and try again,
    5118              :              possibly repeating the above with updated matches[].  */
    5119        11244 :           unsigned j = 0;
    5120        88387 :           for (unsigned i = 0; i < group_size; ++i)
    5121        77143 :             if (matches[i] != 0)
    5122              :               {
    5123        57582 :                 scalar_stmts[j] = scalar_stmts[i];
    5124        57582 :                 ++j;
    5125              :               }
    5126        11244 :           scalar_stmts.truncate (j);
    5127        11375 :           group_size = scalar_stmts.length ();
    5128        11244 :           if (group_size <= 1)
    5129              :             break;
    5130         8301 :           if (vect_analyze_slp_reduction_group (loop_vinfo, scalar_stmts,
    5131              :                                                 bst_map, max_tree_size, limit,
    5132              :                                                 matches))
    5133              :             return true;
    5134              :         }
    5135              :     }
    5136              :   /* Do SLP discovery for single-lane reductions.  */
    5137       273987 :   for (auto stmt_info : scalar_stmts)
    5138        56012 :     if (! vect_analyze_slp_reduction (loop_vinfo,
    5139              :                                       vect_stmt_to_vectorize (stmt_info),
    5140              :                                       max_tree_size, limit,
    5141              :                                       bst_map, force_single_lane))
    5142              :       {
    5143         1874 :         scalar_stmts.release ();
    5144         1874 :         return false;
    5145              :       }
    5146              : 
    5147        71409 :   scalar_stmts.release ();
    5148        71409 :   return true;
    5149              : }
    5150              : 
    5151              : /* Analyze an SLP instance starting from a group of grouped stores.  Call
    5152              :    vect_build_slp_tree to build a tree of packed stmts if possible.
    5153              :    Return FALSE if it's impossible to SLP any stmt in the group.  */
    5154              : 
    5155              : static bool
    5156      1106208 : vect_analyze_slp_instance (vec_info *vinfo,
    5157              :                            scalar_stmts_to_slp_tree_map_t *bst_map,
    5158              :                            stmt_vec_info stmt_info,
    5159              :                            slp_instance_kind kind,
    5160              :                            unsigned max_tree_size, unsigned *limit,
    5161              :                            bool force_single_lane)
    5162              : {
    5163      1106208 :   vec<stmt_vec_info> scalar_stmts;
    5164              : 
    5165      1106208 :   if (is_a <bb_vec_info> (vinfo))
    5166      1075903 :     vect_location = stmt_info->stmt;
    5167              : 
    5168      1106208 :   gcc_assert (kind == slp_inst_kind_store);
    5169              : 
    5170              :   /* Collect the stores and store them in scalar_stmts.  */
    5171      1106208 :   scalar_stmts.create (DR_GROUP_SIZE (stmt_info));
    5172      1106208 :   stmt_vec_info next_info = stmt_info;
    5173      5495262 :   while (next_info)
    5174              :     {
    5175      3282846 :       scalar_stmts.quick_push (vect_stmt_to_vectorize (next_info));
    5176      3282846 :       next_info = DR_GROUP_NEXT_ELEMENT (next_info);
    5177              :     }
    5178              : 
    5179      1106208 :   vec<stmt_vec_info> root_stmt_infos = vNULL;
    5180      1106208 :   vec<tree> remain = vNULL;
    5181              : 
    5182              :   /* Build the tree for the SLP instance.  */
    5183              : 
    5184              :   /* If there's no budget left bail out early.  */
    5185      1106208 :   if (*limit == 0)
    5186              :     return false;
    5187              : 
    5188      1106188 :   if (dump_enabled_p ())
    5189              :     {
    5190         4220 :       dump_printf_loc (MSG_NOTE, vect_location,
    5191              :                        "Starting SLP discovery for\n");
    5192        24541 :       for (unsigned i = 0; i < scalar_stmts.length (); ++i)
    5193        40642 :         dump_printf_loc (MSG_NOTE, vect_location,
    5194        20321 :                          "  %G", scalar_stmts[i]->stmt);
    5195              :     }
    5196              : 
    5197              :   /* Build the tree for the SLP instance.  */
    5198      1106188 :   unsigned int group_size = scalar_stmts.length ();
    5199      1106188 :   match_elt_t *matches = XALLOCAVEC (match_elt_t, group_size);
    5200      1106188 :   unsigned tree_size = 0;
    5201      1106188 :   unsigned i;
    5202              : 
    5203      1106188 :   slp_tree node = NULL;
    5204      1106188 :   if (group_size > 1 && force_single_lane)
    5205              :     {
    5206         1774 :       matches[0] = 0;
    5207         1774 :       matches[1] = -1;
    5208              :     }
    5209              :   else
    5210      1104414 :     node = vect_build_slp_tree (vinfo, scalar_stmts, matches, limit,
    5211              :                                 &tree_size, bst_map);
    5212      1106188 :   if (node != NULL)
    5213              :     {
    5214              :       /* Create a new SLP instance.  */
    5215       699556 :       slp_instance new_instance = XNEW (class _slp_instance);
    5216       699556 :       SLP_INSTANCE_TREE (new_instance) = node;
    5217       699556 :       SLP_INSTANCE_LOADS (new_instance) = vNULL;
    5218       699556 :       SLP_INSTANCE_ROOT_STMTS (new_instance) = root_stmt_infos;
    5219       699556 :       SLP_INSTANCE_REMAIN_DEFS (new_instance) = remain;
    5220       699556 :       SLP_INSTANCE_KIND (new_instance) = kind;
    5221       699556 :       new_instance->reduc_phis = NULL;
    5222       699556 :       new_instance->cost_vec = vNULL;
    5223       699556 :       new_instance->subgraph_entries = vNULL;
    5224              : 
    5225       699556 :       if (dump_enabled_p ())
    5226         3214 :         dump_printf_loc (MSG_NOTE, vect_location,
    5227              :                          "SLP size %u vs. limit %u.\n",
    5228              :                          tree_size, max_tree_size);
    5229              : 
    5230       699556 :       vinfo->slp_instances.safe_push (new_instance);
    5231              : 
    5232              :       /* ???  We've replaced the old SLP_INSTANCE_GROUP_SIZE with
    5233              :          the number of SLP lanes of the root in a few places.
    5234              :          Verify that assumption holds.  */
    5235       699556 :       gcc_assert (SLP_TREE_LANES (SLP_INSTANCE_TREE (new_instance))
    5236              :                   == group_size);
    5237              : 
    5238       699556 :       if (dump_enabled_p ())
    5239              :         {
    5240         3214 :           dump_printf_loc (MSG_NOTE, vect_location,
    5241              :                            "Final SLP tree for instance %p:\n",
    5242              :                            (void *) new_instance);
    5243         3214 :           vect_print_slp_graph (MSG_NOTE, vect_location,
    5244              :                                 SLP_INSTANCE_TREE (new_instance));
    5245              :         }
    5246       699556 :       return true;
    5247              :     }
    5248              :   /* Failed to SLP.  */
    5249              : 
    5250              :   /* Try to break the group up into pieces.  */
    5251              :   /* ???  Improve this with the matches[] improvements.  */
    5252       406632 :   if (*limit > 0 && kind == slp_inst_kind_store)
    5253              :     {
    5254              :       /* ???  We could delay all the actual splitting of store-groups
    5255              :          until after SLP discovery of the original group completed.
    5256              :          Then we can recurse to vect_build_slp_instance directly.  */
    5257      1013835 :       for (i = 0; i < group_size; i++)
    5258      1013835 :         if (matches[i] != 0)
    5259              :           break;
    5260              : 
    5261              :       /* For basic block SLP, try to break the group up into multiples of
    5262              :          a vector size.  */
    5263       406631 :       if (is_a <bb_vec_info> (vinfo)
    5264       406631 :           && (i > 1 && i < group_size))
    5265              :         {
    5266              :           /* Free the allocated memory.  */
    5267       134863 :           scalar_stmts.release ();
    5268              : 
    5269       134863 :           tree scalar_type
    5270       134863 :             = TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (stmt_info)));
    5271       269726 :           tree vectype = get_vectype_for_scalar_type (vinfo, scalar_type,
    5272       134863 :                                                       1 << floor_log2 (i));
    5273       134863 :           unsigned HOST_WIDE_INT const_nunits;
    5274       134863 :           if (vectype
    5275       134863 :               && TYPE_VECTOR_SUBPARTS (vectype).is_constant (&const_nunits))
    5276              :             {
    5277              :               /* Split into two groups at the first vector boundary.  */
    5278       134863 :               gcc_assert ((const_nunits & (const_nunits - 1)) == 0);
    5279       134863 :               unsigned group1_size = i & ~(const_nunits - 1);
    5280              : 
    5281       134863 :               if (dump_enabled_p ())
    5282           83 :                 dump_printf_loc (MSG_NOTE, vect_location,
    5283              :                                  "Splitting SLP group at stmt %u\n", i);
    5284       134863 :               stmt_vec_info rest = vect_split_slp_store_group (stmt_info,
    5285              :                                                                group1_size);
    5286       134863 :               bool res = vect_analyze_slp_instance (vinfo, bst_map, stmt_info,
    5287              :                                                     kind, max_tree_size,
    5288              :                                                     limit, false);
    5289              :               /* Split the rest at the failure point and possibly
    5290              :                  re-analyze the remaining matching part if it has
    5291              :                  at least two lanes.  */
    5292       134863 :               if (group1_size < i
    5293         5773 :                   && (i + 1 < group_size
    5294         2563 :                       || i - group1_size > 1))
    5295              :                 {
    5296         3244 :                   stmt_vec_info rest2 = rest;
    5297         3244 :                   rest = vect_split_slp_store_group (rest, i - group1_size);
    5298         3244 :                   if (i - group1_size > 1)
    5299           69 :                     res |= vect_analyze_slp_instance (vinfo, bst_map, rest2,
    5300              :                                                       kind, max_tree_size,
    5301              :                                                       limit, false);
    5302              :                 }
    5303              :               /* Re-analyze the non-matching tail if it has at least
    5304              :                  two lanes.  */
    5305       134863 :               if (i + 1 < group_size)
    5306        22428 :                 res |= vect_analyze_slp_instance (vinfo, bst_map,
    5307              :                                                   rest, kind, max_tree_size,
    5308              :                                                   limit, false);
    5309      1106208 :               return res;
    5310              :             }
    5311              :         }
    5312              : 
    5313              :       /* For loop vectorization split the RHS into arbitrary pieces of
    5314              :          size >= 1.  */
    5315       271768 :       else if (is_a <loop_vec_info> (vinfo)
    5316       271768 :                && (group_size != 1 && i < group_size))
    5317              :         {
    5318         8364 :           gcall *call = dyn_cast <gcall *> (stmt_info->stmt);
    5319           28 :           bool masked_p = call
    5320           28 :               && gimple_call_internal_p (call)
    5321           28 :               && internal_fn_mask_index (gimple_call_internal_fn (call)) != -1;
    5322              :           /* There are targets that cannot do even/odd interleaving schemes
    5323              :              so they absolutely need to use load/store-lanes.  For now
    5324              :              force single-lane SLP for them - they would be happy with
    5325              :              uniform power-of-two lanes (but depending on element size),
    5326              :              but even if we can use 'i' as indicator we would need to
    5327              :              backtrack when later lanes fail to discover with the same
    5328              :              granularity.  We cannot turn any of strided or scatter store
    5329              :              into store-lanes.  */
    5330              :           /* ???  If this is not in sync with what get_load_store_type
    5331              :              later decides the SLP representation is not good for other
    5332              :              store vectorization methods.  */
    5333         8364 :           bool want_store_lanes
    5334         8364 :             = (! STMT_VINFO_GATHER_SCATTER_P (stmt_info)
    5335         8364 :                && ! STMT_VINFO_STRIDED_P (stmt_info)
    5336         6245 :                && ! STMT_VINFO_SLP_VECT_ONLY (stmt_info)
    5337         6241 :                && compare_step_with_zero (vinfo, stmt_info) > 0
    5338        14496 :                && vect_slp_prefer_store_lanes_p (vinfo, stmt_info, NULL_TREE,
    5339        16728 :                                                  masked_p, group_size, i));
    5340         8364 :           if (want_store_lanes || force_single_lane)
    5341              :             i = 1;
    5342              : 
    5343              :           /* A fatal discovery fail doesn't always mean single-lane SLP
    5344              :              isn't a possibility, so try.  */
    5345         6590 :           if (i == 0)
    5346              :             i = 1;
    5347              : 
    5348         8364 :           if (dump_enabled_p ())
    5349          873 :             dump_printf_loc (MSG_NOTE, vect_location,
    5350              :                              "Splitting SLP group at stmt %u\n", i);
    5351              : 
    5352              :           /* Analyze the stored values and pinch them together with
    5353              :              a permute node so we can preserve the whole store group.  */
    5354         8364 :           auto_vec<slp_tree> rhs_nodes;
    5355              : 
    5356         8364 :           unsigned int rhs_common_nlanes = 0;
    5357         8364 :           unsigned int start = 0, end = i;
    5358        38324 :           while (start < group_size)
    5359              :             {
    5360        30075 :               gcc_assert (end - start >= 1);
    5361        30075 :               vec<stmt_vec_info> substmts;
    5362        30075 :               substmts.create (end - start);
    5363       126402 :               for (unsigned j = start; j < end; ++j)
    5364        66252 :                 substmts.quick_push (scalar_stmts[j]);
    5365        30075 :               node = vect_build_slp_tree (vinfo, substmts,
    5366              :                                           matches, limit, &tree_size, bst_map);
    5367        30075 :               if (node)
    5368              :                 {
    5369        24015 :                   rhs_nodes.safe_push (node);
    5370        24015 :                   if (start == 0)
    5371         8249 :                     rhs_common_nlanes = SLP_TREE_LANES (node);
    5372        15766 :                   else if (rhs_common_nlanes != SLP_TREE_LANES (node))
    5373         1419 :                     rhs_common_nlanes = 0;
    5374        24015 :                   start = end;
    5375        24015 :                   if (want_store_lanes || force_single_lane)
    5376         5323 :                     end = start + 1;
    5377              :                   else
    5378              :                     end = group_size;
    5379              :                 }
    5380              :               else
    5381              :                 {
    5382         6060 :                   substmts.release ();
    5383         6060 :                   if (end - start == 1)
    5384              :                     {
    5385              :                       /* Single-lane discovery failed.  Free resources.  */
    5386          115 :                       for (auto node : rhs_nodes)
    5387            0 :                         vect_free_slp_tree (node);
    5388          115 :                       scalar_stmts.release ();
    5389          115 :                       if (dump_enabled_p ())
    5390           14 :                         dump_printf_loc (MSG_NOTE, vect_location,
    5391              :                                          "SLP discovery failed\n");
    5392          115 :                       return false;
    5393              :                     }
    5394              : 
    5395              :                   /* ???  It really happens that we soft-fail SLP
    5396              :                      build at a mismatch but the matching part hard-fails
    5397              :                      later.  As we know we arrived here with a group
    5398              :                      larger than one try a group of size one!  */
    5399         5945 :                   if (matches[0] != 0)
    5400           12 :                     end = start + 1;
    5401              :                   else
    5402        13037 :                     for (unsigned j = start; j < end; j++)
    5403        13037 :                       if (matches[j - start] != 0)
    5404              :                         {
    5405              :                           end = j;
    5406              :                           break;
    5407              :                         }
    5408              :                 }
    5409              :             }
    5410              : 
    5411              :           /* Now re-assess whether we want store lanes in case the
    5412              :              discovery ended up producing all single-lane RHSs.  */
    5413         8249 :           if (! want_store_lanes
    5414         8249 :               && rhs_common_nlanes == 1
    5415         7163 :               && ! STMT_VINFO_GATHER_SCATTER_P (stmt_info)
    5416         7163 :               && ! STMT_VINFO_STRIDED_P (stmt_info)
    5417         5415 :               && ! STMT_VINFO_SLP_VECT_ONLY (stmt_info)
    5418         5412 :               && compare_step_with_zero (vinfo, stmt_info) > 0
    5419        13570 :               && (vect_store_lanes_supported (SLP_TREE_VECTYPE (rhs_nodes[0]),
    5420              :                                               group_size, masked_p)
    5421              :                   != IFN_LAST))
    5422              :             want_store_lanes = true;
    5423              : 
    5424              :           /* Now we assume we can build the root SLP node from all stores.  */
    5425         8249 :           if (want_store_lanes)
    5426              :             {
    5427              :               /* For store-lanes feed the store node with all RHS nodes
    5428              :                  in order.  */
    5429            0 :               node = vect_create_new_slp_node (scalar_stmts,
    5430            0 :                                                SLP_TREE_CHILDREN
    5431              :                                                  (rhs_nodes[0]).length ());
    5432            0 :               SLP_TREE_VECTYPE (node) = SLP_TREE_VECTYPE (rhs_nodes[0]);
    5433            0 :               node->ldst_lanes = true;
    5434            0 :               SLP_TREE_CHILDREN (node)
    5435            0 :                 .reserve_exact (SLP_TREE_CHILDREN (rhs_nodes[0]).length ()
    5436            0 :                                 + rhs_nodes.length () - 1);
    5437              :               /* First store value and possibly mask.  */
    5438            0 :               SLP_TREE_CHILDREN (node)
    5439            0 :                 .splice (SLP_TREE_CHILDREN (rhs_nodes[0]));
    5440              :               /* Rest of the store values.  All mask nodes are the same,
    5441              :                  this should be guaranteed by dataref group discovery.  */
    5442            0 :               for (unsigned j = 1; j < rhs_nodes.length (); ++j)
    5443            0 :                 SLP_TREE_CHILDREN (node)
    5444            0 :                   .quick_push (SLP_TREE_CHILDREN (rhs_nodes[j])[0]);
    5445            0 :               for (slp_tree child : SLP_TREE_CHILDREN (node))
    5446            0 :                 child->refcnt++;
    5447              :             }
    5448              :           else
    5449         8249 :             node = vect_build_slp_store_interleaving (rhs_nodes, scalar_stmts);
    5450              : 
    5451        32264 :           while (!rhs_nodes.is_empty ())
    5452        24015 :             vect_free_slp_tree (rhs_nodes.pop ());
    5453              : 
    5454              :           /* Create a new SLP instance.  */
    5455         8249 :           slp_instance new_instance = XNEW (class _slp_instance);
    5456         8249 :           SLP_INSTANCE_TREE (new_instance) = node;
    5457         8249 :           SLP_INSTANCE_LOADS (new_instance) = vNULL;
    5458         8249 :           SLP_INSTANCE_ROOT_STMTS (new_instance) = root_stmt_infos;
    5459         8249 :           SLP_INSTANCE_REMAIN_DEFS (new_instance) = remain;
    5460         8249 :           SLP_INSTANCE_KIND (new_instance) = kind;
    5461         8249 :           new_instance->reduc_phis = NULL;
    5462         8249 :           new_instance->cost_vec = vNULL;
    5463         8249 :           new_instance->subgraph_entries = vNULL;
    5464              : 
    5465         8249 :           if (dump_enabled_p ())
    5466          859 :             dump_printf_loc (MSG_NOTE, vect_location,
    5467              :                              "SLP size %u vs. limit %u.\n",
    5468              :                              tree_size, max_tree_size);
    5469              : 
    5470         8249 :           vinfo->slp_instances.safe_push (new_instance);
    5471              : 
    5472              :           /* ???  We've replaced the old SLP_INSTANCE_GROUP_SIZE with
    5473              :              the number of SLP lanes of the root in a few places.
    5474              :              Verify that assumption holds.  */
    5475         8249 :           gcc_assert (SLP_TREE_LANES (SLP_INSTANCE_TREE (new_instance))
    5476              :                       == group_size);
    5477              : 
    5478         8249 :           if (dump_enabled_p ())
    5479              :             {
    5480          859 :               dump_printf_loc (MSG_NOTE, vect_location,
    5481              :                                "Final SLP tree for instance %p:\n",
    5482              :                                (void *) new_instance);
    5483          859 :               vect_print_slp_graph (MSG_NOTE, vect_location,
    5484              :                                     SLP_INSTANCE_TREE (new_instance));
    5485              :             }
    5486              :           return true;
    5487         8364 :         }
    5488              :       else
    5489              :         /* Free the allocated memory.  */
    5490       263404 :         scalar_stmts.release ();
    5491              : 
    5492              :       /* Even though the first vector did not all match, we might be able to SLP
    5493              :          (some) of the remainder.  FORNOW ignore this possibility.  */
    5494              :     }
    5495              :   else
    5496              :     /* Free the allocated memory.  */
    5497            1 :     scalar_stmts.release ();
    5498              : 
    5499              :   /* Failed to SLP.  */
    5500       263405 :   if (dump_enabled_p ())
    5501           50 :     dump_printf_loc (MSG_NOTE, vect_location, "SLP discovery failed\n");
    5502              :   return false;
    5503              : }
    5504              : 
    5505              : /* qsort comparator ordering SLP load nodes.  */
    5506              : 
    5507              : static int
    5508      2693607 : vllp_cmp (const void *a_, const void *b_)
    5509              : {
    5510      2693607 :   const slp_tree a = *(const slp_tree *)a_;
    5511      2693607 :   const slp_tree b = *(const slp_tree *)b_;
    5512      2693607 :   stmt_vec_info a0 = SLP_TREE_SCALAR_STMTS (a)[0];
    5513      2693607 :   stmt_vec_info b0 = SLP_TREE_SCALAR_STMTS (b)[0];
    5514      2693607 :   if (STMT_VINFO_GROUPED_ACCESS (a0)
    5515      1547612 :       && STMT_VINFO_GROUPED_ACCESS (b0)
    5516      4179211 :       && DR_GROUP_FIRST_ELEMENT (a0) == DR_GROUP_FIRST_ELEMENT (b0))
    5517              :     {
    5518              :       /* Same group, order after lanes used.  */
    5519       349662 :       if (SLP_TREE_LANES (a) < SLP_TREE_LANES (b))
    5520              :         return 1;
    5521       340689 :       else if (SLP_TREE_LANES (a) > SLP_TREE_LANES (b))
    5522              :         return -1;
    5523              :       else
    5524              :         {
    5525              :           /* Try to order loads using the same lanes together, breaking
    5526              :              the tie with the lane number that first differs.  */
    5527       330952 :           if (!SLP_TREE_LOAD_PERMUTATION (a).exists ()
    5528       330952 :               && !SLP_TREE_LOAD_PERMUTATION (b).exists ())
    5529              :             return 0;
    5530       330952 :           else if (SLP_TREE_LOAD_PERMUTATION (a).exists ()
    5531       330952 :                    && !SLP_TREE_LOAD_PERMUTATION (b).exists ())
    5532              :             return 1;
    5533       326885 :           else if (!SLP_TREE_LOAD_PERMUTATION (a).exists ()
    5534       326885 :                    && SLP_TREE_LOAD_PERMUTATION (b).exists ())
    5535              :             return -1;
    5536              :           else
    5537              :             {
    5538       319395 :               for (unsigned i = 0; i < SLP_TREE_LANES (a); ++i)
    5539       319395 :                 if (SLP_TREE_LOAD_PERMUTATION (a)[i]
    5540       319395 :                     != SLP_TREE_LOAD_PERMUTATION (b)[i])
    5541              :                   {
    5542              :                     /* In-order lane first, that's what the above case for
    5543              :                        no permutation does.  */
    5544       318083 :                     if (SLP_TREE_LOAD_PERMUTATION (a)[i] == i)
    5545              :                       return -1;
    5546       195407 :                     else if (SLP_TREE_LOAD_PERMUTATION (b)[i] == i)
    5547              :                       return 1;
    5548       103150 :                     else if (SLP_TREE_LOAD_PERMUTATION (a)[i]
    5549       103150 :                              < SLP_TREE_LOAD_PERMUTATION (b)[i])
    5550              :                       return -1;
    5551              :                     else
    5552        38638 :                       return 1;
    5553              :                   }
    5554              :               return 0;
    5555              :             }
    5556              :         }
    5557              :     }
    5558              :   else /* Different groups or non-groups.  */
    5559              :     {
    5560              :       /* Order groups as their first element to keep them together.  */
    5561      2343945 :       if (STMT_VINFO_GROUPED_ACCESS (a0))
    5562      2343945 :         a0 = DR_GROUP_FIRST_ELEMENT (a0);
    5563      2343945 :       if (STMT_VINFO_GROUPED_ACCESS (b0))
    5564      2343945 :         b0 = DR_GROUP_FIRST_ELEMENT (b0);
    5565      2343945 :       if (a0 == b0)
    5566              :         return 0;
    5567              :       /* Tie using UID.  */
    5568      2343825 :       else if (gimple_uid (STMT_VINFO_STMT (a0))
    5569      2343825 :                < gimple_uid (STMT_VINFO_STMT (b0)))
    5570              :         return -1;
    5571              :       else
    5572              :         {
    5573      1041580 :           gcc_assert (gimple_uid (STMT_VINFO_STMT (a0))
    5574              :                       != gimple_uid (STMT_VINFO_STMT (b0)));
    5575              :           return 1;
    5576              :         }
    5577              :     }
    5578              : }
    5579              : 
    5580              : /* Return whether if the load permutation of NODE is consecutive starting
    5581              :    with value START_VAL in the first element.  If START_VAL is not given
    5582              :    the first element's value is used.  */
    5583              : 
    5584              : bool
    5585       653007 : vect_load_perm_consecutive_p (slp_tree node, unsigned start_val)
    5586              : {
    5587       653007 :   load_permutation_t perm = SLP_TREE_LOAD_PERMUTATION (node);
    5588              : 
    5589       653007 :   if (!perm.exists () || !perm.length ())
    5590              :     return false;
    5591              : 
    5592       653007 :   if (start_val == UINT_MAX)
    5593        79870 :     start_val = perm[0];
    5594              : 
    5595      1289936 :   for (unsigned int i = 0; i < perm.length (); i++)
    5596       660627 :     if (perm[i] != start_val + (unsigned int) i)
    5597              :       return false;
    5598              : 
    5599              :   return true;
    5600              : }
    5601              : 
    5602              : /* Process the set of LOADS that are all from the same dataref group.  */
    5603              : 
    5604              : static void
    5605       162421 : vect_lower_load_permutations (loop_vec_info loop_vinfo,
    5606              :                               scalar_stmts_to_slp_tree_map_t *bst_map,
    5607              :                               const array_slice<slp_tree> &loads,
    5608              :                               bool force_single_lane)
    5609              : {
    5610              :   /* We at this point want to lower without a fixed VF or vector
    5611              :      size in mind which means we cannot actually compute whether we
    5612              :      need three or more vectors for a load permutation yet.  So always
    5613              :      lower.  */
    5614       162421 :   stmt_vec_info first
    5615       162421 :     = DR_GROUP_FIRST_ELEMENT (SLP_TREE_SCALAR_STMTS (loads[0])[0]);
    5616       162421 :   unsigned group_lanes = DR_GROUP_SIZE (first);
    5617              : 
    5618              :   /* Verify if all load permutations can be implemented with a suitably
    5619              :      large element load-lanes operation.  */
    5620       162421 :   unsigned ld_lanes_lanes = SLP_TREE_LANES (loads[0]);
    5621       162421 :   if (STMT_VINFO_STRIDED_P (first)
    5622       159943 :       || compare_step_with_zero (loop_vinfo, first) <= 0
    5623       157290 :       || exact_log2 (ld_lanes_lanes) == -1
    5624              :       /* ???  For now only support the single-lane case as there is
    5625              :          missing support on the store-lane side and code generation
    5626              :          isn't up to the task yet.  */
    5627       154459 :       || ld_lanes_lanes != 1
    5628       305818 :       || vect_load_lanes_supported (SLP_TREE_VECTYPE (loads[0]),
    5629              :                                     group_lanes / ld_lanes_lanes,
    5630              :                                     false) == IFN_LAST)
    5631              :     ld_lanes_lanes = 0;
    5632              :   else
    5633              :     /* Verify the loads access the same number of lanes aligned to
    5634              :        ld_lanes_lanes.  */
    5635            0 :     for (slp_tree load : loads)
    5636              :       {
    5637            0 :         if (SLP_TREE_LANES (load) != ld_lanes_lanes)
    5638              :           {
    5639              :             ld_lanes_lanes = 0;
    5640              :             break;
    5641              :           }
    5642            0 :         unsigned first = SLP_TREE_LOAD_PERMUTATION (load)[0];
    5643            0 :         if (first % ld_lanes_lanes != 0)
    5644              :           {
    5645              :             ld_lanes_lanes = 0;
    5646              :             break;
    5647              :           }
    5648            0 :         if (!vect_load_perm_consecutive_p (load))
    5649              :           {
    5650              :             ld_lanes_lanes = 0;
    5651              :             break;
    5652              :           }
    5653              :       }
    5654              : 
    5655              :   /* Only a power-of-two number of lanes matches interleaving with N levels.
    5656              :      ???  An even number of lanes could be reduced to 1<<ceil_log2(N)-1 lanes
    5657              :      at each step.  */
    5658       263383 :   if (ld_lanes_lanes == 0 && exact_log2 (group_lanes) == -1 && group_lanes != 3)
    5659              :     return;
    5660              : 
    5661       267046 :   for (slp_tree load : loads)
    5662              :     {
    5663              :       /* Leave masked or gather loads alone for now.  */
    5664       188465 :       if (!SLP_TREE_CHILDREN (load).is_empty ())
    5665        61166 :         continue;
    5666              : 
    5667              :       /* For single-element interleaving spanning multiple vectors avoid
    5668              :          lowering, we want to use VMAT_ELEMENTWISE later.  */
    5669       188459 :       if (ld_lanes_lanes == 0
    5670       188459 :           && SLP_TREE_LANES (load) == 1
    5671       168935 :           && !DR_GROUP_NEXT_ELEMENT (first)
    5672       268462 :           && maybe_gt (group_lanes,
    5673              :                        TYPE_VECTOR_SUBPARTS (SLP_TREE_VECTYPE (load))))
    5674        51490 :         return;
    5675              : 
    5676              :       /* We want to pattern-match special cases here and keep those
    5677              :          alone.  Candidates are splats and load-lane.  */
    5678              : 
    5679              :       /* We need to lower only loads of less than half of the groups
    5680              :          lanes, including duplicate lanes.  Note this leaves nodes
    5681              :          with a non-1:1 load permutation around instead of canonicalizing
    5682              :          those into a load and a permute node.  Removing this early
    5683              :          check would do such canonicalization.  */
    5684       136969 :       if (SLP_TREE_LANES (load) >= (group_lanes + 1) / 2
    5685        57588 :           && ld_lanes_lanes == 0)
    5686        57588 :         continue;
    5687              : 
    5688              :       /* Build the permute to get the original load permutation order.  */
    5689        79381 :       bool contiguous = vect_load_perm_consecutive_p (load);
    5690        79381 :       lane_permutation_t final_perm;
    5691        79381 :       final_perm.create (SLP_TREE_LANES (load));
    5692       239087 :       for (unsigned i = 0; i < SLP_TREE_LANES (load); ++i)
    5693       160650 :         final_perm.quick_push (
    5694        80325 :           std::make_pair (0, SLP_TREE_LOAD_PERMUTATION (load)[i]));
    5695              : 
    5696              :       /* When the load permutation accesses a contiguous unpermuted,
    5697              :          power-of-two aligned and sized chunk leave the load alone.
    5698              :          We can likely (re-)load it more efficiently rather than
    5699              :          extracting it from the larger load.
    5700              :          ???  Long-term some of the lowering should move to where
    5701              :          the vector types involved are fixed.  */
    5702        82953 :       if (!force_single_lane
    5703        79381 :           && ld_lanes_lanes == 0
    5704        53518 :           && contiguous
    5705        53258 :           && (SLP_TREE_LANES (load) > 1 || loads.size () == 1)
    5706         6586 :           && pow2p_hwi (SLP_TREE_LANES (load))
    5707         6550 :           && pow2p_hwi (group_lanes)
    5708         3572 :           && SLP_TREE_LOAD_PERMUTATION (load)[0] % SLP_TREE_LANES (load) == 0
    5709        82953 :           && group_lanes % SLP_TREE_LANES (load) == 0)
    5710              :         {
    5711         3572 :           final_perm.release ();
    5712         3572 :           continue;
    5713              :         }
    5714              : 
    5715              :       /* First build (and possibly re-use) a load node for the
    5716              :          unpermuted group.  Gaps in the middle and on the end are
    5717              :          represented with NULL stmts.  */
    5718        75809 :       vec<stmt_vec_info> stmts;
    5719        75809 :       stmts.create (group_lanes);
    5720       270605 :       for (stmt_vec_info s = first; s; s = DR_GROUP_NEXT_ELEMENT (s))
    5721              :         {
    5722       194796 :           if (s != first)
    5723       124042 :             for (unsigned i = 1; i < DR_GROUP_GAP (s); ++i)
    5724         5055 :               stmts.quick_push (NULL);
    5725       194796 :           stmts.quick_push (s);
    5726              :         }
    5727       139721 :       for (unsigned i = 0; i < DR_GROUP_GAP (first); ++i)
    5728        63912 :         stmts.quick_push (NULL);
    5729        75809 :       match_elt_t *matches = XALLOCAVEC (match_elt_t, group_lanes);
    5730        75809 :       unsigned limit = 1;
    5731        75809 :       unsigned tree_size = 0;
    5732        75809 :       slp_tree l0 = vect_build_slp_tree (loop_vinfo, stmts, matches, &limit,
    5733        75809 :                                          &tree_size, bst_map);
    5734        75809 :       gcc_assert (!SLP_TREE_LOAD_PERMUTATION (l0).exists ());
    5735              : 
    5736        75809 :       if (ld_lanes_lanes != 0)
    5737              :         {
    5738              :           /* ???  If this is not in sync with what get_load_store_type
    5739              :              later decides the SLP representation is not good for other
    5740              :              store vectorization methods.  */
    5741            0 :           l0->ldst_lanes = true;
    5742            0 :           load->ldst_lanes = true;
    5743              :         }
    5744              : 
    5745       236089 :       while (1)
    5746              :         {
    5747       155949 :           unsigned group_lanes = SLP_TREE_LANES (l0);
    5748       155949 :           if (ld_lanes_lanes != 0
    5749       155949 :               || SLP_TREE_LANES (load) >= (group_lanes + 1) / 2)
    5750              :             break;
    5751              : 
    5752              :           /* Try to lower by reducing the group to half its size using an
    5753              :              interleaving scheme.  For this try to compute whether all
    5754              :              elements needed for this load are in even or odd elements of
    5755              :              an even/odd decomposition with N consecutive elements.
    5756              :              Thus { e, e, o, o, e, e, o, o } would be an even/odd decomposition
    5757              :              with N == 2.  */
    5758              :           /* ???  Only an even number of lanes can be handed this way, but the
    5759              :              fallback below could work for any number.  We have to make sure
    5760              :              to round up in that case.  */
    5761        80140 :           gcc_assert ((group_lanes & 1) == 0 || group_lanes == 3);
    5762        12147 :           unsigned even = 0, odd = 0;
    5763        12147 :           if ((group_lanes & 1) == 0)
    5764              :             {
    5765        12147 :               even = (1 << ceil_log2 (group_lanes)) - 1;
    5766        12147 :               odd = even;
    5767        49337 :               for (auto l : final_perm)
    5768              :                 {
    5769        12896 :                   even &= ~l.second;
    5770        12896 :                   odd &= l.second;
    5771              :                 }
    5772              :             }
    5773              : 
    5774              :           /* Now build an even or odd extraction from the unpermuted load.  */
    5775        80140 :           lane_permutation_t perm;
    5776        80140 :           perm.create ((group_lanes + 1) / 2);
    5777        80140 :           unsigned even_level = even ? 1 << ctz_hwi (even) : 0;
    5778        80140 :           unsigned odd_level = odd ? 1 << ctz_hwi (odd) : 0;
    5779        80140 :           if (even_level
    5780        11169 :               && group_lanes % (2 * even_level) == 0
    5781              :               /* ???  When code generating permutes we do not try to pun
    5782              :                  to larger component modes so level != 1 isn't a natural
    5783              :                  even/odd extract.  Prefer one if possible.  */
    5784        11169 :               && (even_level == 1 || !odd_level || odd_level != 1))
    5785              :             {
    5786              :               /* { 0, 1, ... 4, 5 ..., } */
    5787        39506 :               for (unsigned i = 0; i < group_lanes / 2 / even_level; ++i)
    5788        62345 :                 for (unsigned j = 0; j < even_level; ++j)
    5789        31368 :                   perm.quick_push (std::make_pair (0, 2 * i * even_level + j));
    5790              :             }
    5791        68971 :           else if (odd_level)
    5792              :             {
    5793              :               /* { ..., 2, 3, ... 6, 7 } */
    5794         3588 :               gcc_assert (group_lanes % (2 * odd_level) == 0);
    5795        15474 :               for (unsigned i = 0; i < group_lanes / 2 / odd_level; ++i)
    5796        23826 :                 for (unsigned j = 0; j < odd_level; ++j)
    5797        11940 :                   perm.quick_push
    5798        11940 :                     (std::make_pair (0, (2 * i + 1) * odd_level + j));
    5799              :             }
    5800              :           else
    5801              :             {
    5802              :               /* As fallback extract all used lanes and fill to half the
    5803              :                  group size by repeating the last element.
    5804              :                  ???  This is quite a bad strathegy for re-use - we could
    5805              :                  brute force our way to find more optimal filling lanes to
    5806              :                  maximize re-use when looking at all loads from the group.  */
    5807        68023 :               auto_bitmap l;
    5808       272148 :               for (auto p : final_perm)
    5809        68079 :                 bitmap_set_bit (l, p.second);
    5810        68023 :               unsigned i = 0;
    5811        68023 :               bitmap_iterator bi;
    5812       136102 :               EXECUTE_IF_SET_IN_BITMAP (l, 0, i, bi)
    5813        68079 :                   perm.quick_push (std::make_pair (0, i));
    5814       272244 :               while (perm.length () < (group_lanes + 1) / 2)
    5815        68099 :                 perm.quick_push (perm.last ());
    5816        68023 :             }
    5817              : 
    5818              :           /* Update final_perm with the intermediate permute.  */
    5819       161029 :           for (unsigned i = 0; i < final_perm.length (); ++i)
    5820              :             {
    5821        80889 :               unsigned l = final_perm[i].second;
    5822        80889 :               unsigned j;
    5823        90463 :               for (j = 0; j < perm.length (); ++j)
    5824        90463 :                 if (perm[j].second == l)
    5825              :                   {
    5826        80889 :                     final_perm[i].second = j;
    5827        80889 :                     break;
    5828              :                   }
    5829        80889 :               gcc_assert (j < perm.length ());
    5830              :             }
    5831              : 
    5832              :           /* And create scalar stmts.  */
    5833        80140 :           vec<stmt_vec_info> perm_stmts;
    5834        80140 :           perm_stmts.create (perm.length ());
    5835       339766 :           for (unsigned i = 0; i < perm.length (); ++i)
    5836       179486 :             perm_stmts.quick_push (SLP_TREE_SCALAR_STMTS (l0)[perm[i].second]);
    5837              : 
    5838        80140 :           slp_tree p = vect_create_new_slp_node (1, VEC_PERM_EXPR);
    5839        80140 :           SLP_TREE_CHILDREN (p).quick_push (l0);
    5840        80140 :           SLP_TREE_LANE_PERMUTATION (p) = perm;
    5841        80140 :           SLP_TREE_VECTYPE (p) = SLP_TREE_VECTYPE (load);
    5842        80140 :           SLP_TREE_LANES (p) = perm.length ();
    5843              :           /* ???  As we have scalar stmts for this intermediate permute we
    5844              :              could CSE it via bst_map but we do not want to pick up
    5845              :              another SLP node with a load permutation.  We instead should
    5846              :              have a "local" CSE map here.  */
    5847        80140 :           SLP_TREE_SCALAR_STMTS (p) = perm_stmts;
    5848              : 
    5849              :           /* We now have a node for (group_lanes + 1) / 2 lanes.  */
    5850        80140 :           l0 = p;
    5851        80140 :         }
    5852              : 
    5853              :       /* And finally from the ordered reduction node create the
    5854              :          permute to shuffle the lanes into the original load-permutation
    5855              :          order.  We replace the original load node with this.  */
    5856        75809 :       SLP_TREE_CODE (load) = VEC_PERM_EXPR;
    5857        75809 :       SLP_TREE_LOAD_PERMUTATION (load).release ();
    5858        75809 :       SLP_TREE_LANE_PERMUTATION (load) = final_perm;
    5859        75809 :       SLP_TREE_CHILDREN (load).create (1);
    5860        75809 :       SLP_TREE_CHILDREN (load).quick_push (l0);
    5861        75809 :       SLP_TREE_REPRESENTATIVE (load) = NULL;
    5862              :     }
    5863              : }
    5864              : 
    5865              : /* Transform SLP loads in the SLP graph created by SLP discovery to
    5866              :    group loads from the same group and lower load permutations that
    5867              :    are unlikely to be supported into a series of permutes.
    5868              :    In the degenerate case of having only single-lane SLP instances
    5869              :    this should result in a series of permute nodes emulating an
    5870              :    interleaving scheme.  */
    5871              : 
    5872              : static void
    5873       505784 : vect_lower_load_permutations (loop_vec_info loop_vinfo,
    5874              :                               scalar_stmts_to_slp_tree_map_t *bst_map,
    5875              :                               bool force_single_lane)
    5876              : {
    5877              :   /* Gather and sort loads across all instances.  */
    5878       505784 :   hash_set<slp_tree> visited;
    5879       505784 :   auto_vec<slp_tree> loads;
    5880      2322411 :   for (auto inst : loop_vinfo->slp_instances)
    5881       807127 :     vect_gather_slp_loads (loads, SLP_INSTANCE_TREE (inst), visited);
    5882       505784 :   if (loads.is_empty ())
    5883        94073 :     return;
    5884       411711 :   loads.qsort (vllp_cmp);
    5885              : 
    5886              :   /* Now process each dataref group separately.  */
    5887       411711 :   unsigned firsti = 0;
    5888      1168895 :   for (unsigned i = 1; i < loads.length (); ++i)
    5889              :     {
    5890       345473 :       slp_tree first = loads[firsti];
    5891       345473 :       slp_tree next = loads[i];
    5892       345473 :       stmt_vec_info a0 = SLP_TREE_SCALAR_STMTS (first)[0];
    5893       345473 :       stmt_vec_info b0 = SLP_TREE_SCALAR_STMTS (next)[0];
    5894       345473 :       if (STMT_VINFO_GROUPED_ACCESS (a0)
    5895       158923 :           && STMT_VINFO_GROUPED_ACCESS (b0)
    5896       491194 :           && DR_GROUP_FIRST_ELEMENT (a0) == DR_GROUP_FIRST_ELEMENT (b0))
    5897        63583 :         continue;
    5898              :       /* Now we have one or multiple SLP loads of the same group from
    5899              :          firsti to i - 1.  */
    5900       281890 :       if (STMT_VINFO_GROUPED_ACCESS (a0))
    5901        95340 :         vect_lower_load_permutations (loop_vinfo, bst_map,
    5902        95340 :                                       make_array_slice (&loads[firsti],
    5903              :                                                         i - firsti),
    5904              :                                       force_single_lane);
    5905              :       firsti = i;
    5906              :     }
    5907       823422 :   if (firsti < loads.length ()
    5908       823422 :       && STMT_VINFO_GROUPED_ACCESS (SLP_TREE_SCALAR_STMTS (loads[firsti])[0]))
    5909        67081 :     vect_lower_load_permutations (loop_vinfo, bst_map,
    5910        67081 :                                   make_array_slice (&loads[firsti],
    5911        67081 :                                                     loads.length () - firsti),
    5912              :                                   force_single_lane);
    5913       505784 : }
    5914              : 
    5915              : /* Check if there are stmts in the loop can be vectorized using SLP.  Build SLP
    5916              :    trees of packed scalar stmts if SLP is possible.  */
    5917              : 
    5918              : opt_result
    5919      1203111 : vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size,
    5920              :                   bool force_single_lane)
    5921              : {
    5922      1203111 :   loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo);
    5923      1203111 :   unsigned int i;
    5924      1203111 :   stmt_vec_info first_element;
    5925      1203111 :   slp_instance instance;
    5926              : 
    5927      1203111 :   DUMP_VECT_SCOPE ("vect_analyze_slp");
    5928              : 
    5929      1203111 :   unsigned limit = max_tree_size;
    5930              : 
    5931      1203111 :   scalar_stmts_to_slp_tree_map_t *bst_map
    5932      1203111 :     = new scalar_stmts_to_slp_tree_map_t ();
    5933              : 
    5934              :   /* Find SLP sequences starting from groups of grouped stores.  */
    5935      3354947 :   FOR_EACH_VEC_ELT (vinfo->grouped_stores, i, first_element)
    5936       948848 :     if (! vect_analyze_slp_instance (vinfo, bst_map, first_element,
    5937              :                                      slp_inst_kind_store, max_tree_size, &limit,
    5938              :                                      force_single_lane)
    5939       948848 :         && loop_vinfo)
    5940              :       {
    5941          123 :         release_scalar_stmts_to_slp_tree_map (bst_map);
    5942          123 :         return opt_result::failure_at (vect_location, "SLP build failed.\n");
    5943              :       }
    5944              : 
    5945              :   /* For loops also start SLP discovery from non-grouped stores.  */
    5946      1202988 :   if (loop_vinfo)
    5947              :     {
    5948              :       data_reference_p dr;
    5949      1701584 :       FOR_EACH_VEC_ELT (vinfo->shared->datarefs, i, dr)
    5950      1181130 :         if (DR_IS_WRITE (dr))
    5951              :           {
    5952       381540 :             stmt_vec_info stmt_info = vinfo->lookup_dr (dr)->stmt;
    5953              :             /* Grouped stores are already handled above.  */
    5954       381540 :             if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
    5955       103592 :               continue;
    5956       277948 :             vec<stmt_vec_info> stmts;
    5957       277948 :             vec<stmt_vec_info> roots = vNULL;
    5958       277948 :             vec<tree> remain = vNULL;
    5959       277948 :             stmts.create (1);
    5960       277948 :             stmts.quick_push (stmt_info);
    5961       277948 :             if (! vect_build_slp_instance (vinfo, slp_inst_kind_store,
    5962              :                                            stmts, roots, remain, max_tree_size,
    5963              :                                            &limit, bst_map, force_single_lane))
    5964              :               {
    5965         3646 :                 release_scalar_stmts_to_slp_tree_map (bst_map);
    5966         3646 :                 return opt_result::failure_at (vect_location,
    5967              :                                                "SLP build failed.\n");
    5968              :               }
    5969              :           }
    5970              : 
    5971              :       stmt_vec_info stmt_info;
    5972       520494 :       FOR_EACH_VEC_ELT (LOOP_VINFO_ALTERNATE_DEFS (loop_vinfo), i, stmt_info)
    5973              :         {
    5974           20 :           vec<stmt_vec_info> stmts;
    5975           20 :           vec<stmt_vec_info> roots = vNULL;
    5976           20 :           vec<tree> remain = vNULL;
    5977           20 :           stmts.create (1);
    5978           20 :           stmts.quick_push (stmt_info);
    5979           20 :           if (! vect_build_slp_instance (vinfo, slp_inst_kind_store,
    5980              :                                          stmts, roots, remain, max_tree_size,
    5981              :                                          &limit, bst_map, force_single_lane))
    5982              :             {
    5983            0 :               release_scalar_stmts_to_slp_tree_map (bst_map);
    5984            0 :               return opt_result::failure_at (vect_location,
    5985              :                                              "SLP build failed.\n");
    5986              :             }
    5987              :         }
    5988              :     }
    5989              : 
    5990      1199342 :   if (bb_vec_info bb_vinfo = dyn_cast <bb_vec_info> (vinfo))
    5991              :     {
    5992      2051714 :       for (unsigned i = 0; i < bb_vinfo->roots.length (); ++i)
    5993              :         {
    5994      1372826 :           vect_location = bb_vinfo->roots[i].roots[0]->stmt;
    5995              :           /* Apply patterns.  */
    5996      4490403 :           for (unsigned j = 0; j < bb_vinfo->roots[i].stmts.length (); ++j)
    5997      6235154 :             bb_vinfo->roots[i].stmts[j]
    5998      3226044 :               = vect_stmt_to_vectorize (bb_vinfo->roots[i].stmts[j]);
    5999      1372826 :           if (vect_build_slp_instance (bb_vinfo, bb_vinfo->roots[i].kind,
    6000      1372826 :                                        bb_vinfo->roots[i].stmts,
    6001      1372826 :                                        bb_vinfo->roots[i].roots,
    6002      1372826 :                                        bb_vinfo->roots[i].remain,
    6003              :                                        max_tree_size, &limit, bst_map, false))
    6004              :             {
    6005       156798 :               bb_vinfo->roots[i].roots = vNULL;
    6006       156798 :               bb_vinfo->roots[i].remain = vNULL;
    6007              :             }
    6008      1372826 :           bb_vinfo->roots[i].stmts = vNULL;
    6009              :         }
    6010              :     }
    6011              : 
    6012      1199342 :   if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
    6013              :     {
    6014              :       /* Find SLP sequences starting from groups of reductions.  */
    6015       520454 :       if (!vect_analyze_slp_reductions (loop_vinfo, max_tree_size, &limit,
    6016              :                                         bst_map, force_single_lane))
    6017              :         {
    6018         1896 :           release_scalar_stmts_to_slp_tree_map (bst_map);
    6019         1896 :           return opt_result::failure_at (vect_location, "SLP build failed.\n");
    6020              :         }
    6021              : 
    6022              :       /* Make sure to vectorize only-live stmts, usually inductions.  */
    6023      2337542 :       for (edge e : get_loop_exit_edges (LOOP_VINFO_LOOP (loop_vinfo)))
    6024      1512929 :         for (auto gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi);
    6025       720938 :              gsi_next (&gsi))
    6026              :           {
    6027       731061 :             gphi *lc_phi = *gsi;
    6028       731061 :             tree def = gimple_phi_arg_def_from_edge (lc_phi, e);
    6029       731061 :             stmt_vec_info stmt_info;
    6030       731061 :             if (TREE_CODE (def) == SSA_NAME
    6031       614037 :                 && !virtual_operand_p (def)
    6032       317895 :                 && (stmt_info = loop_vinfo->lookup_def (def))
    6033       285354 :                 && ((stmt_info = vect_stmt_to_vectorize (stmt_info)), true)
    6034       285354 :                 && STMT_VINFO_RELEVANT (stmt_info) == vect_used_only_live
    6035       222015 :                 && STMT_VINFO_LIVE_P (stmt_info)
    6036       222015 :                 && !VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))
    6037       848427 :                 && STMT_VINFO_REDUC_IDX (stmt_info) == -1)
    6038              :               {
    6039       117278 :                 vec<stmt_vec_info> stmts;
    6040       117278 :                 vec<stmt_vec_info> roots = vNULL;
    6041       117278 :                 vec<tree> remain = vNULL;
    6042       117278 :                 stmts.create (1);
    6043       117278 :                 stmts.quick_push (vect_stmt_to_vectorize (stmt_info));
    6044       117278 :                 if (! vect_build_slp_instance (vinfo,
    6045              :                                                slp_inst_kind_reduc_group,
    6046              :                                                stmts, roots, remain,
    6047              :                                                max_tree_size, &limit,
    6048              :                                                bst_map, force_single_lane))
    6049              :                   {
    6050        10123 :                     release_scalar_stmts_to_slp_tree_map (bst_map);
    6051        10123 :                     return opt_result::failure_at (vect_location,
    6052              :                                                    "SLP build failed.\n");
    6053              :                   }
    6054              :               }
    6055        10123 :           }
    6056              : 
    6057              :       /* Find SLP sequences starting from gconds.  */
    6058      1277190 :       for (auto cond : LOOP_VINFO_LOOP_CONDS (loop_vinfo))
    6059              :         {
    6060       298594 :           auto cond_info = loop_vinfo->lookup_stmt (cond);
    6061              : 
    6062       298594 :           cond_info = vect_stmt_to_vectorize (cond_info);
    6063       298594 :           vec<stmt_vec_info> roots = vNULL;
    6064       298594 :           roots.safe_push (cond_info);
    6065       298594 :           gimple *stmt = STMT_VINFO_STMT (cond_info);
    6066       298594 :           tree args0 = gimple_cond_lhs (stmt);
    6067       298594 :           tree args1 = gimple_cond_rhs (stmt);
    6068              : 
    6069              :           /* These should be enforced by cond lowering, but if it failed
    6070              :              bail.  */
    6071       298594 :           if (gimple_cond_code (stmt) != NE_EXPR
    6072       297451 :               || TREE_TYPE (args0) != boolean_type_node
    6073       595446 :               || !integer_zerop (args1))
    6074              :             {
    6075         1742 :               roots.release ();
    6076         1742 :               release_scalar_stmts_to_slp_tree_map (bst_map);
    6077         1742 :               return opt_result::failure_at (vect_location,
    6078              :                                              "SLP build failed.\n");
    6079              :             }
    6080              : 
    6081              :           /* An argument without a loop def will be codegened from vectorizing the
    6082              :              root gcond itself.  As such we don't need to try to build an SLP tree
    6083              :              from them.  It's highly likely that the resulting SLP tree here if both
    6084              :              arguments have a def will be incompatible, but we rely on it being split
    6085              :              later on.  */
    6086       296852 :           auto varg = loop_vinfo->lookup_def (args0);
    6087       296852 :           vec<stmt_vec_info> stmts;
    6088       296852 :           vec<tree> remain = vNULL;
    6089       296852 :           stmts.create (1);
    6090       296852 :           stmts.quick_push (vect_stmt_to_vectorize (varg));
    6091              : 
    6092       296852 :           if (! vect_build_slp_instance (vinfo, slp_inst_kind_gcond,
    6093              :                                          stmts, roots, remain,
    6094              :                                          max_tree_size, &limit,
    6095              :                                          bst_map, force_single_lane))
    6096              :             {
    6097          909 :               roots.release ();
    6098          909 :               release_scalar_stmts_to_slp_tree_map (bst_map);
    6099          909 :               return opt_result::failure_at (vect_location,
    6100              :                                              "SLP build failed.\n");
    6101              :             }
    6102              :         }
    6103              :     }
    6104              : 
    6105      1184672 :   hash_set<slp_tree> visited_patterns;
    6106      1184672 :   slp_tree_to_load_perm_map_t perm_cache;
    6107      1184672 :   slp_compat_nodes_map_t compat_cache;
    6108              : 
    6109              :   /* See if any patterns can be found in the SLP tree.  */
    6110      1184672 :   bool pattern_found = false;
    6111      4010892 :   FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (vinfo), i, instance)
    6112      1641548 :     pattern_found |= vect_match_slp_patterns (instance, vinfo,
    6113              :                                               &visited_patterns, &perm_cache,
    6114              :                                               &compat_cache);
    6115              : 
    6116              :   /* If any were found optimize permutations of loads.  */
    6117      1184672 :   if (pattern_found)
    6118              :     {
    6119          267 :       hash_map<slp_tree, slp_tree> load_map;
    6120         4981 :       FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (vinfo), i, instance)
    6121              :         {
    6122         4180 :           slp_tree root = SLP_INSTANCE_TREE (instance);
    6123         4180 :           optimize_load_redistribution (bst_map, vinfo, SLP_TREE_LANES (root),
    6124              :                                         &load_map, root);
    6125              :         }
    6126          267 :     }
    6127              : 
    6128              :   /* Check whether we should force some SLP instances to use load/store-lanes
    6129              :      and do so by forcing SLP re-discovery with single lanes.  We used
    6130              :      to cancel SLP when this applied to all instances in a loop but now
    6131              :      we decide this per SLP instance.  It's important to do this only
    6132              :      after SLP pattern recognition.  */
    6133      1184672 :   if (is_a <loop_vec_info> (vinfo))
    6134      1312911 :     FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (vinfo), i, instance)
    6135       807127 :       if (SLP_INSTANCE_KIND (instance) == slp_inst_kind_store
    6136       303014 :           && !SLP_INSTANCE_TREE (instance)->ldst_lanes)
    6137              :         {
    6138       303014 :           slp_tree slp_root = SLP_INSTANCE_TREE (instance);
    6139       303014 :           unsigned int group_size = SLP_TREE_LANES (slp_root);
    6140       303014 :           tree vectype = SLP_TREE_VECTYPE (slp_root);
    6141              : 
    6142       303014 :           stmt_vec_info rep_info = SLP_TREE_REPRESENTATIVE (slp_root);
    6143       303014 :           gimple *rep = STMT_VINFO_STMT (rep_info);
    6144       303014 :           bool masked = (is_gimple_call (rep)
    6145         2446 :                          && gimple_call_internal_p (rep)
    6146       305440 :                          && internal_fn_mask_index
    6147         2426 :                               (gimple_call_internal_fn (rep)) != -1);
    6148       302994 :           if (!STMT_VINFO_GROUPED_ACCESS (rep_info)
    6149        30147 :               || slp_root->ldst_lanes
    6150       333161 :               || (vect_store_lanes_supported (vectype, group_size, masked)
    6151              :                   == IFN_LAST))
    6152       303014 :             continue;
    6153              : 
    6154            0 :           auto_vec<slp_tree> loads;
    6155            0 :           hash_set<slp_tree> visited;
    6156            0 :           vect_gather_slp_loads (loads, slp_root, visited);
    6157              : 
    6158              :           /* Check whether any load in the SLP instance is possibly
    6159              :              permuted.  */
    6160            0 :           bool loads_permuted = false;
    6161            0 :           slp_tree load_node;
    6162            0 :           unsigned j;
    6163            0 :           FOR_EACH_VEC_ELT (loads, j, load_node)
    6164              :             {
    6165            0 :               if (!SLP_TREE_LOAD_PERMUTATION (load_node).exists ())
    6166            0 :                 continue;
    6167            0 :               for (unsigned k = 0; k < SLP_TREE_LANES (load_node); k++)
    6168            0 :                 if (SLP_TREE_LOAD_PERMUTATION (load_node)[k] != k)
    6169              :                   {
    6170              :                     loads_permuted = true;
    6171              :                     break;
    6172              :                   }
    6173              :             }
    6174              : 
    6175              :           /* If the loads and stores can use load/store-lanes force re-discovery
    6176              :              with single lanes.  */
    6177            0 :           if (loads_permuted)
    6178              :             {
    6179            0 :               bool can_use_lanes = true;
    6180              :               bool prefer_load_lanes = false;
    6181            0 :               FOR_EACH_VEC_ELT (loads, j, load_node)
    6182            0 :                 if (STMT_VINFO_GROUPED_ACCESS
    6183              :                       (SLP_TREE_REPRESENTATIVE (load_node)))
    6184              :                   {
    6185            0 :                     stmt_vec_info stmt_vinfo = DR_GROUP_FIRST_ELEMENT
    6186              :                         (SLP_TREE_REPRESENTATIVE (load_node));
    6187            0 :                     rep = STMT_VINFO_STMT (stmt_vinfo);
    6188            0 :                     masked = (is_gimple_call (rep)
    6189            0 :                               && gimple_call_internal_p (rep)
    6190            0 :                               && internal_fn_mask_index
    6191            0 :                                    (gimple_call_internal_fn (rep)));
    6192              :                     /* Use SLP for strided accesses (or if we can't
    6193              :                        load-lanes).  */
    6194            0 :                     if (STMT_VINFO_STRIDED_P (stmt_vinfo)
    6195            0 :                         || compare_step_with_zero (vinfo, stmt_vinfo) <= 0
    6196            0 :                         || vect_load_lanes_supported
    6197            0 :                              (SLP_TREE_VECTYPE (load_node),
    6198            0 :                               DR_GROUP_SIZE (stmt_vinfo), masked) == IFN_LAST
    6199              :                         /* ???  During SLP re-discovery with a single lane
    6200              :                            a masked grouped load will appear permuted and
    6201              :                            discovery will fail.  We have to rework this
    6202              :                            on the discovery side - for now avoid ICEing.  */
    6203            0 :                         || masked)
    6204              :                       {
    6205              :                         can_use_lanes = false;
    6206              :                         break;
    6207              :                       }
    6208              :                     /* Make sure that the target would prefer store-lanes
    6209              :                        for at least one of the loads.
    6210              : 
    6211              :                        ??? Perhaps we should instead require this for
    6212              :                        all loads?  */
    6213            0 :                     prefer_load_lanes
    6214              :                       = (prefer_load_lanes
    6215            0 :                          || SLP_TREE_LANES (load_node) == group_size
    6216            0 :                          || (vect_slp_prefer_store_lanes_p
    6217            0 :                              (vinfo, stmt_vinfo,
    6218              :                               SLP_TREE_VECTYPE (load_node), masked,
    6219              :                               group_size, SLP_TREE_LANES (load_node))));
    6220              :                   }
    6221              : 
    6222            0 :               if (can_use_lanes && prefer_load_lanes)
    6223              :                 {
    6224            0 :                   if (dump_enabled_p ())
    6225            0 :                     dump_printf_loc (MSG_NOTE, vect_location,
    6226              :                                      "SLP instance %p can use load/store-lanes,"
    6227              :                                      " re-discovering with single-lanes\n",
    6228              :                                      (void *) instance);
    6229              : 
    6230            0 :                   stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (slp_root);
    6231              : 
    6232            0 :                   vect_free_slp_instance (instance);
    6233            0 :                   limit = max_tree_size;
    6234            0 :                   bool res = vect_analyze_slp_instance (vinfo, bst_map,
    6235              :                                                         stmt_info,
    6236              :                                                         slp_inst_kind_store,
    6237              :                                                         max_tree_size, &limit,
    6238              :                                                         true);
    6239            0 :                   gcc_assert (res);
    6240            0 :                   auto new_inst = LOOP_VINFO_SLP_INSTANCES (vinfo).pop ();
    6241            0 :                   LOOP_VINFO_SLP_INSTANCES (vinfo)[i] = new_inst;
    6242              :                 }
    6243              :             }
    6244            0 :         }
    6245              : 
    6246              :   /* When we end up with load permutations that we cannot possibly handle,
    6247              :      like those requiring three vector inputs, lower them using interleaving
    6248              :      like schemes.  */
    6249      1184672 :   if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
    6250              :     {
    6251       505784 :       vect_lower_load_permutations (loop_vinfo, bst_map, force_single_lane);
    6252       505784 :       if (dump_enabled_p ())
    6253              :         {
    6254        21550 :           dump_printf_loc (MSG_NOTE, vect_location,
    6255              :                            "SLP graph after lowering permutations:\n");
    6256        21550 :           hash_set<slp_tree> visited;
    6257        95606 :           FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (vinfo), i, instance)
    6258        30983 :             vect_print_slp_graph (MSG_NOTE, vect_location,
    6259              :                                   SLP_INSTANCE_TREE (instance), visited);
    6260        21550 :         }
    6261              :     }
    6262              : 
    6263      1184672 :   release_scalar_stmts_to_slp_tree_map (bst_map);
    6264              : 
    6265      1184672 :   if (pattern_found && dump_enabled_p ())
    6266              :     {
    6267           20 :       dump_printf_loc (MSG_NOTE, vect_location,
    6268              :                        "Pattern matched SLP tree\n");
    6269           20 :       hash_set<slp_tree> visited;
    6270          101 :       FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (vinfo), i, instance)
    6271           41 :         vect_print_slp_graph (MSG_NOTE, vect_location,
    6272              :                               SLP_INSTANCE_TREE (instance), visited);
    6273           20 :     }
    6274              : 
    6275      1184672 :   return opt_result::success ();
    6276      1184672 : }
    6277              : 
    6278              : /* Estimates the cost of inserting layout changes into the SLP graph.
    6279              :    It can also say that the insertion is impossible.  */
    6280              : 
    6281              : struct slpg_layout_cost
    6282              : {
    6283     11293664 :   slpg_layout_cost () = default;
    6284              :   slpg_layout_cost (sreal, bool);
    6285              : 
    6286       532873 :   static slpg_layout_cost impossible () { return { sreal::max (), 0 }; }
    6287      5624160 :   bool is_possible () const { return depth != sreal::max (); }
    6288              : 
    6289              :   bool operator== (const slpg_layout_cost &) const;
    6290              :   bool operator!= (const slpg_layout_cost &) const;
    6291              : 
    6292              :   bool is_better_than (const slpg_layout_cost &, bool) const;
    6293              : 
    6294              :   void add_parallel_cost (const slpg_layout_cost &);
    6295              :   void add_serial_cost (const slpg_layout_cost &);
    6296              :   void split (unsigned int);
    6297              : 
    6298              :   /* The longest sequence of layout changes needed during any traversal
    6299              :      of the partition dag, weighted by execution frequency.
    6300              : 
    6301              :      This is the most important metric when optimizing for speed, since
    6302              :      it helps to ensure that we keep the number of operations on
    6303              :      critical paths to a minimum.  */
    6304              :   sreal depth = 0;
    6305              : 
    6306              :   /* An estimate of the total number of operations needed.  It is weighted by
    6307              :      execution frequency when optimizing for speed but not when optimizing for
    6308              :      size.  In order to avoid double-counting, a node with a fanout of N will
    6309              :      distribute 1/N of its total cost to each successor.
    6310              : 
    6311              :      This is the most important metric when optimizing for size, since
    6312              :      it helps to keep the total number of operations to a minimum,  */
    6313              :   sreal total = 0;
    6314              : };
    6315              : 
    6316              : /* Construct costs for a node with weight WEIGHT.  A higher weight
    6317              :    indicates more frequent execution.  IS_FOR_SIZE is true if we are
    6318              :    optimizing for size rather than speed.  */
    6319              : 
    6320      1326236 : slpg_layout_cost::slpg_layout_cost (sreal weight, bool is_for_size)
    6321      1333943 :   : depth (weight), total (is_for_size && weight > 0 ? 1 : weight)
    6322              : {
    6323      1326236 : }
    6324              : 
    6325              : bool
    6326            0 : slpg_layout_cost::operator== (const slpg_layout_cost &other) const
    6327              : {
    6328            0 :   return depth == other.depth && total == other.total;
    6329              : }
    6330              : 
    6331              : bool
    6332            0 : slpg_layout_cost::operator!= (const slpg_layout_cost &other) const
    6333              : {
    6334            0 :   return !operator== (other);
    6335              : }
    6336              : 
    6337              : /* Return true if these costs are better than OTHER.  IS_FOR_SIZE is
    6338              :    true if we are optimizing for size rather than speed.  */
    6339              : 
    6340              : bool
    6341       318212 : slpg_layout_cost::is_better_than (const slpg_layout_cost &other,
    6342              :                                   bool is_for_size) const
    6343              : {
    6344       318212 :   if (is_for_size)
    6345              :     {
    6346         3295 :       if (total != other.total)
    6347         1678 :         return total < other.total;
    6348         1617 :       return depth < other.depth;
    6349              :     }
    6350              :   else
    6351              :     {
    6352       314917 :       if (depth != other.depth)
    6353       128738 :         return depth < other.depth;
    6354       186179 :       return total < other.total;
    6355              :     }
    6356              : }
    6357              : 
    6358              : /* Increase the costs to account for something with cost INPUT_COST
    6359              :    happening in parallel with the current costs.  */
    6360              : 
    6361              : void
    6362       381704 : slpg_layout_cost::add_parallel_cost (const slpg_layout_cost &input_cost)
    6363              : {
    6364       381704 :   depth = std::max (depth, input_cost.depth);
    6365       381704 :   total += input_cost.total;
    6366       381704 : }
    6367              : 
    6368              : /* Increase the costs to account for something with cost INPUT_COST
    6369              :    happening in series with the current costs.  */
    6370              : 
    6371              : void
    6372      1575039 : slpg_layout_cost::add_serial_cost (const slpg_layout_cost &other)
    6373              : {
    6374      1575039 :   depth += other.depth;
    6375      1575039 :   total += other.total;
    6376      1575039 : }
    6377              : 
    6378              : /* Split the total cost among TIMES successors or predecessors.  */
    6379              : 
    6380              : void
    6381      1250833 : slpg_layout_cost::split (unsigned int times)
    6382              : {
    6383      1250833 :   if (times > 1)
    6384       602141 :     total /= times;
    6385      1250833 : }
    6386              : 
    6387              : /* Information about one node in the SLP graph, for use during
    6388              :    vect_optimize_slp_pass.  */
    6389              : 
    6390              : struct slpg_vertex
    6391              : {
    6392     10541076 :   slpg_vertex (slp_tree node_) : node (node_) {}
    6393              : 
    6394              :   /* The node itself.  */
    6395              :   slp_tree node;
    6396              : 
    6397              :   /* Which partition the node belongs to, or -1 if none.  Nodes outside of
    6398              :      partitions are flexible; they can have whichever layout consumers
    6399              :      want them to have.  */
    6400              :   int partition = -1;
    6401              : 
    6402              :   /* The number of nodes that directly use the result of this one
    6403              :      (i.e. the number of nodes that count this one as a child).  */
    6404              :   unsigned int out_degree = 0;
    6405              : 
    6406              :   /* The execution frequency of the node.  */
    6407              :   sreal weight = 0;
    6408              : 
    6409              :   /* The total execution frequency of all nodes that directly use the
    6410              :      result of this one.  */
    6411              :   sreal out_weight = 0;
    6412              : };
    6413              : 
    6414              : /* Information about one partition of the SLP graph, for use during
    6415              :    vect_optimize_slp_pass.  */
    6416              : 
    6417              : struct slpg_partition_info
    6418              : {
    6419              :   /* The nodes in the partition occupy indices [NODE_BEGIN, NODE_END)
    6420              :      of m_partitioned_nodes.  */
    6421              :   unsigned int node_begin = 0;
    6422              :   unsigned int node_end = 0;
    6423              : 
    6424              :   /* Which layout we've chosen to use for this partition, or -1 if
    6425              :      we haven't picked one yet.  */
    6426              :   int layout = -1;
    6427              : 
    6428              :   /* The number of predecessors and successors in the partition dag.
    6429              :      The predecessors always have lower partition numbers and the
    6430              :      successors always have higher partition numbers.
    6431              : 
    6432              :      Note that the directions of these edges are not necessarily the
    6433              :      same as in the data flow graph.  For example, if an SCC has separate
    6434              :      partitions for an inner loop and an outer loop, the inner loop's
    6435              :      partition will have at least two incoming edges from the outer loop's
    6436              :      partition: one for a live-in value and one for a live-out value.
    6437              :      In data flow terms, one of these edges would also be from the outer loop
    6438              :      to the inner loop, but the other would be in the opposite direction.  */
    6439              :   unsigned int in_degree = 0;
    6440              :   unsigned int out_degree = 0;
    6441              : };
    6442              : 
    6443              : /* Information about the costs of using a particular layout for a
    6444              :    particular partition.  It can also say that the combination is
    6445              :    impossible.  */
    6446              : 
    6447              : struct slpg_partition_layout_costs
    6448              : {
    6449      1658995 :   bool is_possible () const { return internal_cost.is_possible (); }
    6450        69687 :   void mark_impossible () { internal_cost = slpg_layout_cost::impossible (); }
    6451              : 
    6452              :   /* The costs inherited from predecessor partitions.  */
    6453              :   slpg_layout_cost in_cost;
    6454              : 
    6455              :   /* The inherent cost of the layout within the node itself.  For example,
    6456              :      this is nonzero for a load if choosing a particular layout would require
    6457              :      the load to permute the loaded elements.  It is nonzero for a
    6458              :      VEC_PERM_EXPR if the permutation cannot be eliminated or converted
    6459              :      to full-vector moves.  */
    6460              :   slpg_layout_cost internal_cost;
    6461              : 
    6462              :   /* The costs inherited from successor partitions.  */
    6463              :   slpg_layout_cost out_cost;
    6464              : };
    6465              : 
    6466              : /* This class tries to optimize the layout of vectors in order to avoid
    6467              :    unnecessary shuffling.  At the moment, the set of possible layouts are
    6468              :    restricted to bijective permutations.
    6469              : 
    6470              :    The goal of the pass depends on whether we're optimizing for size or
    6471              :    for speed.  When optimizing for size, the goal is to reduce the overall
    6472              :    number of layout changes (including layout changes implied by things
    6473              :    like load permutations).  When optimizing for speed, the goal is to
    6474              :    reduce the maximum latency attributable to layout changes on any
    6475              :    non-cyclical path through the data flow graph.
    6476              : 
    6477              :    For example, when optimizing a loop nest for speed, we will prefer
    6478              :    to make layout changes outside of a loop rather than inside of a loop,
    6479              :    and will prefer to make layout changes in parallel rather than serially,
    6480              :    even if that increases the overall number of layout changes.
    6481              : 
    6482              :    The high-level procedure is:
    6483              : 
    6484              :    (1) Build a graph in which edges go from uses (parents) to definitions
    6485              :        (children).
    6486              : 
    6487              :    (2) Divide the graph into a dag of strongly-connected components (SCCs).
    6488              : 
    6489              :    (3) When optimizing for speed, partition the nodes in each SCC based
    6490              :        on their containing cfg loop.  When optimizing for size, treat
    6491              :        each SCC as a single partition.
    6492              : 
    6493              :        This gives us a dag of partitions.  The goal is now to assign a
    6494              :        layout to each partition.
    6495              : 
    6496              :    (4) Construct a set of vector layouts that are worth considering.
    6497              :        Record which nodes must keep their current layout.
    6498              : 
    6499              :    (5) Perform a forward walk over the partition dag (from loads to stores)
    6500              :        accumulating the "forward" cost of using each layout.  When visiting
    6501              :        each partition, assign a tentative choice of layout to the partition
    6502              :        and use that choice when calculating the cost of using a different
    6503              :        layout in successor partitions.
    6504              : 
    6505              :    (6) Perform a backward walk over the partition dag (from stores to loads),
    6506              :        accumulating the "backward" cost of using each layout.  When visiting
    6507              :        each partition, make a final choice of layout for that partition based
    6508              :        on the accumulated forward costs (from (5)) and backward costs
    6509              :        (from (6)).
    6510              : 
    6511              :    (7) Apply the chosen layouts to the SLP graph.
    6512              : 
    6513              :    For example, consider the SLP statements:
    6514              : 
    6515              :    S1:      a_1 = load
    6516              :        loop:
    6517              :    S2:      a_2 = PHI<a_1, a_3>
    6518              :    S3:      b_1 = load
    6519              :    S4:      a_3 = a_2 + b_1
    6520              :        exit:
    6521              :    S5:      a_4 = PHI<a_3>
    6522              :    S6:      store a_4
    6523              : 
    6524              :    S2 and S4 form an SCC and are part of the same loop.  Every other
    6525              :    statement is in a singleton SCC.  In this example there is a one-to-one
    6526              :    mapping between SCCs and partitions and the partition dag looks like this;
    6527              : 
    6528              :         S1     S3
    6529              :          \     /
    6530              :           S2+S4
    6531              :             |
    6532              :            S5
    6533              :             |
    6534              :            S6
    6535              : 
    6536              :    S2, S3 and S4 will have a higher execution frequency than the other
    6537              :    statements, so when optimizing for speed, the goal is to avoid any
    6538              :    layout changes:
    6539              : 
    6540              :    - within S3
    6541              :    - within S2+S4
    6542              :    - on the S3->S2+S4 edge
    6543              : 
    6544              :    For example, if S3 was originally a reversing load, the goal of the
    6545              :    pass is to make it an unreversed load and change the layout on the
    6546              :    S1->S2+S4 and S2+S4->S5 edges to compensate.  (Changing the layout
    6547              :    on S1->S2+S4 and S5->S6 would also be acceptable.)
    6548              : 
    6549              :    The difference between SCCs and partitions becomes important if we
    6550              :    add an outer loop:
    6551              : 
    6552              :    S1:      a_1 = ...
    6553              :        loop1:
    6554              :    S2:      a_2 = PHI<a_1, a_6>
    6555              :    S3:      b_1 = load
    6556              :    S4:      a_3 = a_2 + b_1
    6557              :        loop2:
    6558              :    S5:      a_4 = PHI<a_3, a_5>
    6559              :    S6:      c_1 = load
    6560              :    S7:      a_5 = a_4 + c_1
    6561              :        exit2:
    6562              :    S8:      a_6 = PHI<a_5>
    6563              :    S9:      store a_6
    6564              :        exit1:
    6565              : 
    6566              :    Here, S2, S4, S5, S7 and S8 form a single SCC.  However, when optimizing
    6567              :    for speed, we usually do not want restrictions in the outer loop to "infect"
    6568              :    the decision for the inner loop.  For example, if an outer-loop node
    6569              :    in the SCC contains a statement with a fixed layout, that should not
    6570              :    prevent the inner loop from using a different layout.  Conversely,
    6571              :    the inner loop should not dictate a layout to the outer loop: if the
    6572              :    outer loop does a lot of computation, then it may not be efficient to
    6573              :    do all of that computation in the inner loop's preferred layout.
    6574              : 
    6575              :    So when optimizing for speed, we partition the SCC into S2+S4+S8 (outer)
    6576              :    and S5+S7 (inner).  We also try to arrange partitions so that:
    6577              : 
    6578              :    - the partition for an outer loop comes before the partition for
    6579              :      an inner loop
    6580              : 
    6581              :    - if a sibling loop A dominates a sibling loop B, A's partition
    6582              :      comes before B's
    6583              : 
    6584              :    This gives the following partition dag for the example above:
    6585              : 
    6586              :         S1        S3
    6587              :          \        /
    6588              :           S2+S4+S8   S6
    6589              :            |   \\    /
    6590              :            |    S5+S7
    6591              :            |
    6592              :           S9
    6593              : 
    6594              :    There are two edges from S2+S4+S8 to S5+S7: one for the edge S4->S5 and
    6595              :    one for a reversal of the edge S7->S8.
    6596              : 
    6597              :    The backward walk picks a layout for S5+S7 before S2+S4+S8.  The choice
    6598              :    for S2+S4+S8 therefore has to balance the cost of using the outer loop's
    6599              :    preferred layout against the cost of changing the layout on entry to the
    6600              :    inner loop (S4->S5) and on exit from the inner loop (S7->S8 reversed).
    6601              : 
    6602              :    Although this works well when optimizing for speed, it has the downside
    6603              :    when optimizing for size that the choice of layout for S5+S7 is completely
    6604              :    independent of S9, which lessens the chance of reducing the overall number
    6605              :    of permutations.  We therefore do not partition SCCs when optimizing
    6606              :    for size.
    6607              : 
    6608              :    To give a concrete example of the difference between optimizing
    6609              :    for size and speed, consider:
    6610              : 
    6611              :    a[0] = (b[1] << c[3]) - d[1];
    6612              :    a[1] = (b[0] << c[2]) - d[0];
    6613              :    a[2] = (b[3] << c[1]) - d[3];
    6614              :    a[3] = (b[2] << c[0]) - d[2];
    6615              : 
    6616              :    There are three different layouts here: one for a, one for b and d,
    6617              :    and one for c.  When optimizing for speed it is better to permute each
    6618              :    of b, c and d into the order required by a, since those permutations
    6619              :    happen in parallel.  But when optimizing for size, it is better to:
    6620              : 
    6621              :    - permute c into the same order as b
    6622              :    - do the arithmetic
    6623              :    - permute the result into the order required by a
    6624              : 
    6625              :    This gives 2 permutations rather than 3.  */
    6626              : 
    6627              : class vect_optimize_slp_pass
    6628              : {
    6629              : public:
    6630       721496 :   vect_optimize_slp_pass (vec_info *vinfo) : m_vinfo (vinfo) {}
    6631              :   void run ();
    6632              : 
    6633              : private:
    6634              :   /* Graph building.  */
    6635              :   struct loop *containing_loop (slp_tree);
    6636              :   bool is_cfg_latch_edge (graph_edge *);
    6637              :   void build_vertices (hash_set<slp_tree> &, slp_tree);
    6638              :   void build_vertices ();
    6639              :   void build_graph ();
    6640              : 
    6641              :   /* Partitioning.  */
    6642              :   void create_partitions ();
    6643              :   template<typename T> void for_each_partition_edge (unsigned int, T);
    6644              : 
    6645              :   /* Layout selection.  */
    6646              :   bool is_compatible_layout (slp_tree, unsigned int);
    6647              :   bool is_compatible_layout (const slpg_partition_info &, unsigned int);
    6648              :   int change_layout_cost (slp_tree, unsigned int, unsigned int);
    6649              :   slpg_partition_layout_costs &partition_layout_costs (unsigned int,
    6650              :                                                        unsigned int);
    6651              :   void change_vec_perm_layout (slp_tree, lane_permutation_t &,
    6652              :                                int, unsigned int);
    6653              :   int internal_node_cost (slp_tree, int, unsigned int);
    6654              :   void start_choosing_layouts ();
    6655              :   bool legitimize ();
    6656              : 
    6657              :   /* Cost propagation.  */
    6658              :   slpg_layout_cost edge_layout_cost (graph_edge *, unsigned int,
    6659              :                                      unsigned int, unsigned int);
    6660              :   slpg_layout_cost total_in_cost (unsigned int);
    6661              :   slpg_layout_cost forward_cost (graph_edge *, unsigned int, unsigned int);
    6662              :   slpg_layout_cost backward_cost (graph_edge *, unsigned int, unsigned int);
    6663              :   void forward_pass ();
    6664              :   void backward_pass ();
    6665              : 
    6666              :   /* Rematerialization.  */
    6667              :   slp_tree get_result_with_layout (slp_tree, unsigned int);
    6668              :   void materialize ();
    6669              : 
    6670              :   /* Clean-up.  */
    6671              :   void remove_redundant_permutations ();
    6672              : 
    6673              :   /* Masked load lanes discovery.  */
    6674              :   void decide_masked_load_lanes ();
    6675              : 
    6676              :   void dump ();
    6677              : 
    6678              :   vec_info *m_vinfo;
    6679              : 
    6680              :   /* True if we should optimize the graph for size, false if we should
    6681              :      optimize it for speed.  (It wouldn't be easy to make this decision
    6682              :      more locally.)  */
    6683              :   bool m_optimize_size;
    6684              : 
    6685              :   /* A graph of all SLP nodes, with edges leading from uses to definitions.
    6686              :      In other words, a node's predecessors are its slp_tree parents and
    6687              :      a node's successors are its slp_tree children.  */
    6688              :   graph *m_slpg = nullptr;
    6689              : 
    6690              :   /* The vertices of M_SLPG, indexed by slp_tree::vertex.  */
    6691              :   auto_vec<slpg_vertex> m_vertices;
    6692              : 
    6693              :   /* The list of all leaves of M_SLPG. such as external definitions, constants,
    6694              :      and loads.  */
    6695              :   auto_vec<int> m_leafs;
    6696              : 
    6697              :   /* This array has one entry for every vector layout that we're considering.
    6698              :      Element 0 is null and indicates "no change".  Other entries describe
    6699              :      permutations that are inherent in the current graph and that we would
    6700              :      like to reverse if possible.
    6701              : 
    6702              :      For example, a permutation { 1, 2, 3, 0 } means that something has
    6703              :      effectively been permuted in that way, such as a load group
    6704              :      { a[1], a[2], a[3], a[0] } (viewed as a permutation of a[0:3]).
    6705              :      We'd then like to apply the reverse permutation { 3, 0, 1, 2 }
    6706              :      in order to put things "back" in order.  */
    6707              :   auto_vec<vec<unsigned> > m_perms;
    6708              : 
    6709              :   /* A partitioning of the nodes for which a layout must be chosen.
    6710              :      Each partition represents an <SCC, cfg loop> pair; that is,
    6711              :      nodes in different SCCs belong to different partitions, and nodes
    6712              :      within an SCC can be further partitioned according to a containing
    6713              :      cfg loop.  Partition <SCC1, L1> comes before <SCC2, L2> if:
    6714              : 
    6715              :      - SCC1 != SCC2 and SCC1 is a predecessor of SCC2 in a forward walk
    6716              :        from leaves (such as loads) to roots (such as stores).
    6717              : 
    6718              :      - SCC1 == SCC2 and L1's header strictly dominates L2's header.  */
    6719              :   auto_vec<slpg_partition_info> m_partitions;
    6720              : 
    6721              :   /* The list of all nodes for which a layout must be chosen.  Nodes for
    6722              :      partition P come before the nodes for partition P+1.  Nodes within a
    6723              :      partition are in reverse postorder.  */
    6724              :   auto_vec<unsigned int> m_partitioned_nodes;
    6725              : 
    6726              :   /* Index P * num-layouts + L contains the cost of using layout L
    6727              :      for partition P.  */
    6728              :   auto_vec<slpg_partition_layout_costs> m_partition_layout_costs;
    6729              : 
    6730              :   /* Index N * num-layouts + L, if nonnull, is a node that provides the
    6731              :      original output of node N adjusted to have layout L.  */
    6732              :   auto_vec<slp_tree> m_node_layouts;
    6733              : };
    6734              : 
    6735              : /* Fill the vertices and leafs vector with all nodes in the SLP graph.
    6736              :    Also record whether we should optimize anything for speed rather
    6737              :    than size.  */
    6738              : 
    6739              : void
    6740     11390004 : vect_optimize_slp_pass::build_vertices (hash_set<slp_tree> &visited,
    6741              :                                         slp_tree node)
    6742              : {
    6743     11390004 :   unsigned i;
    6744     11390004 :   slp_tree child;
    6745              : 
    6746     11390004 :   if (visited.add (node))
    6747     11390004 :     return;
    6748              : 
    6749     10541076 :   if (stmt_vec_info rep = SLP_TREE_REPRESENTATIVE (node))
    6750              :     {
    6751      8062724 :       basic_block bb = gimple_bb (vect_orig_stmt (rep)->stmt);
    6752      7105052 :       if (optimize_bb_for_speed_p (bb))
    6753      6975078 :         m_optimize_size = false;
    6754              :     }
    6755              : 
    6756     10541076 :   node->vertex = m_vertices.length ();
    6757     10541076 :   m_vertices.safe_push (slpg_vertex (node));
    6758              : 
    6759     10541076 :   bool leaf = true;
    6760     10541076 :   bool force_leaf = false;
    6761     19762758 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    6762      9221682 :     if (child)
    6763              :       {
    6764      8296768 :         leaf = false;
    6765      8296768 :         build_vertices (visited, child);
    6766              :       }
    6767              :     else
    6768              :       force_leaf = true;
    6769              :   /* Since SLP discovery works along use-def edges all cycles have an
    6770              :      entry - but there's the exception of cycles where we do not handle
    6771              :      the entry explicitly (but with a NULL SLP node), like some reductions
    6772              :      and inductions.  Force those SLP PHIs to act as leafs to make them
    6773              :      backwards reachable.  */
    6774     10541076 :   if (leaf || force_leaf)
    6775      5227452 :     m_leafs.safe_push (node->vertex);
    6776              : }
    6777              : 
    6778              : /* Fill the vertices and leafs vector with all nodes in the SLP graph.  */
    6779              : 
    6780              : void
    6781      1442992 : vect_optimize_slp_pass::build_vertices ()
    6782              : {
    6783      1442992 :   hash_set<slp_tree> visited;
    6784      1442992 :   unsigned i;
    6785      1442992 :   slp_instance instance;
    6786      1442992 :   m_vertices.truncate (0);
    6787      1442992 :   m_leafs.truncate (0);
    6788      7422212 :   FOR_EACH_VEC_ELT (m_vinfo->slp_instances, i, instance)
    6789      3093236 :     build_vertices (visited, SLP_INSTANCE_TREE (instance));
    6790      1442992 : }
    6791              : 
    6792              : /* Apply (reverse) bijectite PERM to VEC.  */
    6793              : 
    6794              : template <class T>
    6795              : static void
    6796       232367 : vect_slp_permute (vec<unsigned> perm,
    6797              :                   vec<T> &vec, bool reverse)
    6798              : {
    6799       232367 :   auto_vec<T, 64> saved;
    6800       232367 :   saved.create (vec.length ());
    6801       770243 :   for (unsigned i = 0; i < vec.length (); ++i)
    6802       537876 :     saved.quick_push (vec[i]);
    6803              : 
    6804       232367 :   if (reverse)
    6805              :     {
    6806      1520829 :       for (unsigned i = 0; i < vec.length (); ++i)
    6807       535756 :         vec[perm[i]] = saved[i];
    6808       767123 :       for (unsigned i = 0; i < vec.length (); ++i)
    6809       905811 :         gcc_assert (vec[perm[i]] == saved[i]);
    6810              :     }
    6811              :   else
    6812              :     {
    6813         6240 :       for (unsigned i = 0; i < vec.length (); ++i)
    6814         2120 :         vec[i] = saved[perm[i]];
    6815       234487 :       for (unsigned i = 0; i < vec.length (); ++i)
    6816         3180 :         gcc_assert (vec[i] == saved[perm[i]]);
    6817              :     }
    6818       232367 : }
    6819              : 
    6820              : /* Return the cfg loop that contains NODE.  */
    6821              : 
    6822              : struct loop *
    6823      4102941 : vect_optimize_slp_pass::containing_loop (slp_tree node)
    6824              : {
    6825      4102941 :   stmt_vec_info rep = SLP_TREE_REPRESENTATIVE (node);
    6826              :   /* ???  This is imprecise, VEC_PERM nodes do not have a representative
    6827              :      but are laid out close to their children.  */
    6828      4102941 :   if (!rep)
    6829       144951 :     return m_vinfo->bbs[0]->loop_father;
    6830      4450179 :   return gimple_bb (vect_orig_stmt (rep)->stmt)->loop_father;
    6831              : }
    6832              : 
    6833              : /* Return true if UD (an edge from a use to a definition) is associated
    6834              :    with a loop latch edge in the cfg.  */
    6835              : 
    6836              : bool
    6837      8296768 : vect_optimize_slp_pass::is_cfg_latch_edge (graph_edge *ud)
    6838              : {
    6839      8296768 :   slp_tree use = m_vertices[ud->src].node;
    6840      8296768 :   slp_tree def = m_vertices[ud->dest].node;
    6841      8296768 :   if ((SLP_TREE_DEF_TYPE (use) != vect_internal_def
    6842      8296768 :        || SLP_TREE_PERMUTE_P (use))
    6843      7976142 :       || SLP_TREE_DEF_TYPE (def) != vect_internal_def)
    6844              :     return false;
    6845              : 
    6846      4829866 :   stmt_vec_info use_rep = vect_orig_stmt (SLP_TREE_REPRESENTATIVE (use));
    6847      4829866 :   return (is_a<gphi *> (use_rep->stmt)
    6848       386998 :           && bb_loop_header_p (gimple_bb (use_rep->stmt))
    6849      5048672 :           && containing_loop (def) == containing_loop (use));
    6850              : }
    6851              : 
    6852              : /* Build the graph.  Mark edges that correspond to cfg loop latch edges with
    6853              :    a nonnull data field.  */
    6854              : 
    6855              : void
    6856      1442992 : vect_optimize_slp_pass::build_graph ()
    6857              : {
    6858      1442992 :   m_optimize_size = true;
    6859      1442992 :   build_vertices ();
    6860              : 
    6861      2885984 :   m_slpg = new_graph (m_vertices.length ());
    6862     14870052 :   for (slpg_vertex &v : m_vertices)
    6863     31500566 :     for (slp_tree child : SLP_TREE_CHILDREN (v.node))
    6864      9221682 :       if (child)
    6865              :         {
    6866      8296768 :           graph_edge *ud = add_edge (m_slpg, v.node->vertex, child->vertex);
    6867      8296768 :           if (is_cfg_latch_edge (ud))
    6868       208958 :             ud->data = this;
    6869              :         }
    6870      1442992 : }
    6871              : 
    6872              : /* Return true if E corresponds to a loop latch edge in the cfg.  */
    6873              : 
    6874              : static bool
    6875      4252294 : skip_cfg_latch_edges (graph_edge *e)
    6876              : {
    6877      4252294 :   return e->data;
    6878              : }
    6879              : 
    6880              : /* Create the node partitions.  */
    6881              : 
    6882              : void
    6883       721496 : vect_optimize_slp_pass::create_partitions ()
    6884              : {
    6885              :   /* Calculate a postorder of the graph, ignoring edges that correspond
    6886              :      to natural latch edges in the cfg.  Reading the vector from the end
    6887              :      to the beginning gives the reverse postorder.  */
    6888       721496 :   auto_vec<int> initial_rpo;
    6889      1442992 :   graphds_dfs (m_slpg, &m_leafs[0], m_leafs.length (), &initial_rpo,
    6890              :                false, NULL, skip_cfg_latch_edges);
    6891      2164488 :   gcc_assert (initial_rpo.length () == m_vertices.length ());
    6892              : 
    6893              :   /* Calculate the strongly connected components of the graph.  */
    6894       721496 :   auto_vec<int> scc_grouping;
    6895       721496 :   unsigned int num_sccs = graphds_scc (m_slpg, NULL, NULL, &scc_grouping);
    6896              : 
    6897              :   /* Create a new index order in which all nodes from the same SCC are
    6898              :      consecutive.  Use scc_pos to record the index of the first node in
    6899              :      each SCC.  */
    6900       721496 :   auto_vec<unsigned int> scc_pos (num_sccs);
    6901       721496 :   int last_component = -1;
    6902       721496 :   unsigned int node_count = 0;
    6903      7434463 :   for (unsigned int node_i : scc_grouping)
    6904              :     {
    6905      5269975 :       if (last_component != m_slpg->vertices[node_i].component)
    6906              :         {
    6907      5138981 :           last_component = m_slpg->vertices[node_i].component;
    6908     10277962 :           gcc_assert (last_component == int (scc_pos.length ()));
    6909      5138981 :           scc_pos.quick_push (node_count);
    6910              :         }
    6911      5269975 :       node_count += 1;
    6912              :     }
    6913      1442992 :   gcc_assert (node_count == initial_rpo.length ()
    6914              :               && last_component + 1 == int (num_sccs));
    6915              : 
    6916              :   /* Use m_partitioned_nodes to group nodes into SCC order, with the nodes
    6917              :      inside each SCC following the RPO we calculated above.  The fact that
    6918              :      we ignored natural latch edges when calculating the RPO should ensure
    6919              :      that, for natural loop nests:
    6920              : 
    6921              :      - the first node that we encounter in a cfg loop is the loop header phi
    6922              :      - the loop header phis are in dominance order
    6923              : 
    6924              :      Arranging for this is an optimization (see below) rather than a
    6925              :      correctness issue.  Unnatural loops with a tangled mess of backedges
    6926              :      will still work correctly, but might give poorer results.
    6927              : 
    6928              :      Also update scc_pos so that it gives 1 + the index of the last node
    6929              :      in the SCC.  */
    6930       721496 :   m_partitioned_nodes.safe_grow (node_count);
    6931      6712967 :   for (unsigned int old_i = initial_rpo.length (); old_i-- > 0;)
    6932              :     {
    6933      5269975 :       unsigned int node_i = initial_rpo[old_i];
    6934      5269975 :       unsigned int new_i = scc_pos[m_slpg->vertices[node_i].component]++;
    6935      5269975 :       m_partitioned_nodes[new_i] = node_i;
    6936              :     }
    6937              : 
    6938              :   /* When optimizing for speed, partition each SCC based on the containing
    6939              :      cfg loop. The order we constructed above should ensure that, for natural
    6940              :      cfg loops, we'll create sub-SCC partitions for outer loops before
    6941              :      the corresponding sub-SCC partitions for inner loops.  Similarly,
    6942              :      when one sibling loop A dominates another sibling loop B, we should
    6943              :      create a sub-SCC partition for A before a sub-SCC partition for B.
    6944              : 
    6945              :      As above, nothing depends for correctness on whether this achieves
    6946              :      a natural nesting, but we should get better results when it does.  */
    6947      1442992 :   m_partitions.reserve (m_vertices.length ());
    6948       721496 :   unsigned int next_partition_i = 0;
    6949       721496 :   hash_map<struct loop *, int> loop_partitions;
    6950       721496 :   unsigned int rpo_begin = 0;
    6951       721496 :   unsigned int num_partitioned_nodes = 0;
    6952      7303469 :   for (unsigned int rpo_end : scc_pos)
    6953              :     {
    6954      5138981 :       loop_partitions.empty ();
    6955      5138981 :       unsigned int partition_i = next_partition_i;
    6956     10408956 :       for (unsigned int rpo_i = rpo_begin; rpo_i < rpo_end; ++rpo_i)
    6957              :         {
    6958              :           /* Handle externals and constants optimistically throughout.
    6959              :              But treat existing vectors as fixed since we do not handle
    6960              :              permuting them.  */
    6961      5269975 :           unsigned int node_i = m_partitioned_nodes[rpo_i];
    6962      5269975 :           auto &vertex = m_vertices[node_i];
    6963      5269975 :           if ((SLP_TREE_DEF_TYPE (vertex.node) == vect_external_def
    6964       532245 :                && !SLP_TREE_VEC_DEFS (vertex.node).exists ())
    6965      5273119 :               || SLP_TREE_DEF_TYPE (vertex.node) == vect_constant_def)
    6966      1574350 :             vertex.partition = -1;
    6967              :           else
    6968              :             {
    6969      3695625 :               bool existed;
    6970      3695625 :               if (m_optimize_size)
    6971        30296 :                 existed = next_partition_i > partition_i;
    6972              :               else
    6973              :                 {
    6974      3665329 :                   struct loop *loop = containing_loop (vertex.node);
    6975      3665329 :                   auto &entry = loop_partitions.get_or_insert (loop, &existed);
    6976      3665329 :                   if (!existed)
    6977      3535564 :                     entry = next_partition_i;
    6978      3665329 :                   partition_i = entry;
    6979              :                 }
    6980      3695625 :               if (!existed)
    6981              :                 {
    6982      3565768 :                   m_partitions.quick_push (slpg_partition_info ());
    6983      3565768 :                   next_partition_i += 1;
    6984              :                 }
    6985      3695625 :               vertex.partition = partition_i;
    6986      3695625 :               num_partitioned_nodes += 1;
    6987      3695625 :               m_partitions[partition_i].node_end += 1;
    6988              :             }
    6989              :         }
    6990      5138981 :       rpo_begin = rpo_end;
    6991              :     }
    6992              : 
    6993              :   /* Assign ranges of consecutive node indices to each partition,
    6994              :      in partition order.  Start with node_end being the same as
    6995              :      node_begin so that the next loop can use it as a counter.  */
    6996       721496 :   unsigned int node_begin = 0;
    6997      5730256 :   for (auto &partition : m_partitions)
    6998              :     {
    6999      3565768 :       partition.node_begin = node_begin;
    7000      3565768 :       node_begin += partition.node_end;
    7001      3565768 :       partition.node_end = partition.node_begin;
    7002              :     }
    7003       721496 :   gcc_assert (node_begin == num_partitioned_nodes);
    7004              : 
    7005              :   /* Finally build the list of nodes in partition order.  */
    7006       721496 :   m_partitioned_nodes.truncate (num_partitioned_nodes);
    7007      6712967 :   for (unsigned int node_i = 0; node_i < m_vertices.length (); ++node_i)
    7008              :     {
    7009      5269975 :       int partition_i = m_vertices[node_i].partition;
    7010      5269975 :       if (partition_i >= 0)
    7011              :         {
    7012      3695625 :           unsigned int order_i = m_partitions[partition_i].node_end++;
    7013      3695625 :           m_partitioned_nodes[order_i] = node_i;
    7014              :         }
    7015              :     }
    7016       721496 : }
    7017              : 
    7018              : /* Look for edges from earlier partitions into node NODE_I and edges from
    7019              :    node NODE_I into later partitions.  Call:
    7020              : 
    7021              :       FN (ud, other_node_i)
    7022              : 
    7023              :    for each such use-to-def edge ud, where other_node_i is the node at the
    7024              :    other end of the edge.  */
    7025              : 
    7026              : template<typename T>
    7027              : void
    7028      4160370 : vect_optimize_slp_pass::for_each_partition_edge (unsigned int node_i, T fn)
    7029              : {
    7030      4160370 :   int partition_i = m_vertices[node_i].partition;
    7031      4160370 :   for (graph_edge *pred = m_slpg->vertices[node_i].pred;
    7032      7187235 :        pred; pred = pred->pred_next)
    7033              :     {
    7034      3026865 :       int src_partition_i = m_vertices[pred->src].partition;
    7035      3026865 :       if (src_partition_i >= 0 && src_partition_i != partition_i)
    7036      2696372 :         fn (pred, pred->src);
    7037              :     }
    7038      4160370 :   for (graph_edge *succ = m_slpg->vertices[node_i].succ;
    7039      8934733 :        succ; succ = succ->succ_next)
    7040              :     {
    7041      4774363 :       int dest_partition_i = m_vertices[succ->dest].partition;
    7042      4774363 :       if (dest_partition_i >= 0 && dest_partition_i != partition_i)
    7043      2732947 :         fn (succ, succ->dest);
    7044              :     }
    7045      4160370 : }
    7046              : 
    7047              : /* Return true if layout LAYOUT_I is compatible with the number of SLP lanes
    7048              :    that NODE would operate on.  This test is independent of NODE's actual
    7049              :    operation.  */
    7050              : 
    7051              : bool
    7052      1771288 : vect_optimize_slp_pass::is_compatible_layout (slp_tree node,
    7053              :                                               unsigned int layout_i)
    7054              : {
    7055      1771288 :   if (layout_i == 0)
    7056              :     return true;
    7057              : 
    7058      1043550 :   if (SLP_TREE_LANES (node) != m_perms[layout_i].length ())
    7059        18509 :     return false;
    7060              : 
    7061              :   return true;
    7062              : }
    7063              : 
    7064              : /* Return true if layout LAYOUT_I is compatible with the number of SLP lanes
    7065              :    that NODE would operate on for each NODE in PARTITION.
    7066              :    This test is independent of NODE's actual operations.  */
    7067              : 
    7068              : bool
    7069        25849 : vect_optimize_slp_pass::is_compatible_layout (const slpg_partition_info
    7070              :                                                 &partition,
    7071              :                                               unsigned int layout_i)
    7072              : {
    7073        52133 :   for (unsigned int order_i = partition.node_begin;
    7074        52133 :        order_i < partition.node_end; ++order_i)
    7075              :     {
    7076        26383 :       unsigned int node_i = m_partitioned_nodes[order_i];
    7077        26383 :       auto &vertex = m_vertices[node_i];
    7078              : 
    7079              :       /* The layout is incompatible if it is individually incompatible
    7080              :          with any node in the partition.  */
    7081        26383 :       if (!is_compatible_layout (vertex.node, layout_i))
    7082              :         return false;
    7083              :     }
    7084              :   return true;
    7085              : }
    7086              : 
    7087              : /* Return the cost (in arbitrary units) of going from layout FROM_LAYOUT_I
    7088              :    to layout TO_LAYOUT_I for a node like NODE.  Return -1 if either of the
    7089              :    layouts is incompatible with NODE or if the change is not possible for
    7090              :    some other reason.
    7091              : 
    7092              :    The properties taken from NODE include the number of lanes and the
    7093              :    vector type.  The actual operation doesn't matter.  */
    7094              : 
    7095              : int
    7096       745918 : vect_optimize_slp_pass::change_layout_cost (slp_tree node,
    7097              :                                             unsigned int from_layout_i,
    7098              :                                             unsigned int to_layout_i)
    7099              : {
    7100       745918 :   if (!is_compatible_layout (node, from_layout_i)
    7101       745918 :       || !is_compatible_layout (node, to_layout_i))
    7102              :     return -1;
    7103              : 
    7104       745239 :   if (from_layout_i == to_layout_i)
    7105              :     return 0;
    7106              : 
    7107       308631 :   auto_vec<slp_tree, 1> children (1);
    7108       308631 :   children.quick_push (node);
    7109       308631 :   auto_lane_permutation_t perm (SLP_TREE_LANES (node));
    7110       308631 :   if (from_layout_i > 0)
    7111       871033 :     for (unsigned int i : m_perms[from_layout_i])
    7112       386911 :       perm.quick_push ({ 0, i });
    7113              :   else
    7114       483214 :     for (unsigned int i = 0; i < SLP_TREE_LANES (node); ++i)
    7115       335957 :       perm.quick_push ({ 0, i });
    7116       308631 :   if (to_layout_i > 0)
    7117       148006 :     vect_slp_permute (m_perms[to_layout_i], perm, true);
    7118       308631 :   auto count = vectorizable_slp_permutation_1 (m_vinfo, nullptr, node, perm,
    7119              :                                                children, false);
    7120       308631 :   if (count >= 0)
    7121       303232 :     return MAX (count, 1);
    7122              : 
    7123              :   /* ??? In principle we could try changing via layout 0, giving two
    7124              :      layout changes rather than 1.  Doing that would require
    7125              :      corresponding support in get_result_with_layout.  */
    7126              :   return -1;
    7127       308631 : }
    7128              : 
    7129              : /* Return the costs of assigning layout LAYOUT_I to partition PARTITION_I.  */
    7130              : 
    7131              : inline slpg_partition_layout_costs &
    7132      1125203 : vect_optimize_slp_pass::partition_layout_costs (unsigned int partition_i,
    7133              :                                                 unsigned int layout_i)
    7134              : {
    7135      2250406 :   return m_partition_layout_costs[partition_i * m_perms.length () + layout_i];
    7136              : }
    7137              : 
    7138              : /* Change PERM in one of two ways:
    7139              : 
    7140              :    - if IN_LAYOUT_I < 0, accept input operand I in the layout that has been
    7141              :      chosen for child I of NODE.
    7142              : 
    7143              :    - if IN_LAYOUT >= 0, accept all inputs operands with that layout.
    7144              : 
    7145              :    In both cases, arrange for the output to have layout OUT_LAYOUT_I  */
    7146              : 
    7147              : void
    7148        38300 : vect_optimize_slp_pass::
    7149              : change_vec_perm_layout (slp_tree node, lane_permutation_t &perm,
    7150              :                         int in_layout_i, unsigned int out_layout_i)
    7151              : {
    7152       224470 :   for (auto &entry : perm)
    7153              :     {
    7154       109570 :       int this_in_layout_i = in_layout_i;
    7155       109570 :       if (this_in_layout_i < 0)
    7156              :         {
    7157        74759 :           slp_tree in_node = SLP_TREE_CHILDREN (node)[entry.first];
    7158        74759 :           unsigned int in_partition_i = m_vertices[in_node->vertex].partition;
    7159        74759 :           if (in_partition_i == -1u)
    7160          329 :             continue;
    7161        74430 :           this_in_layout_i = m_partitions[in_partition_i].layout;
    7162              :         }
    7163       109241 :       if (this_in_layout_i > 0)
    7164        24965 :         entry.second = m_perms[this_in_layout_i][entry.second];
    7165              :     }
    7166        38300 :   if (out_layout_i > 0)
    7167        10611 :     vect_slp_permute (m_perms[out_layout_i], perm, true);
    7168        38300 : }
    7169              : 
    7170              : /* Check whether the target allows NODE to be rearranged so that the node's
    7171              :    output has layout OUT_LAYOUT_I.  Return the cost of the change if so,
    7172              :    in the same arbitrary units as for change_layout_cost.  Return -1 otherwise.
    7173              : 
    7174              :    If NODE is a VEC_PERM_EXPR and IN_LAYOUT_I < 0, also check whether
    7175              :    NODE can adapt to the layout changes that have (perhaps provisionally)
    7176              :    been chosen for NODE's children, so that no extra permutations are
    7177              :    needed on either the input or the output of NODE.
    7178              : 
    7179              :    If NODE is a VEC_PERM_EXPR and IN_LAYOUT_I >= 0, instead assume
    7180              :    that all inputs will be forced into layout IN_LAYOUT_I beforehand.
    7181              : 
    7182              :    IN_LAYOUT_I has no meaning for other types of node.
    7183              : 
    7184              :    Keeping the node as-is is always valid.  If the target doesn't appear
    7185              :    to support the node as-is, but might realistically support other layouts,
    7186              :    then layout 0 instead has the cost of a worst-case permutation.  On the
    7187              :    one hand, this ensures that every node has at least one valid layout,
    7188              :    avoiding what would otherwise be an awkward special case.  On the other,
    7189              :    it still encourages the pass to change an invalid pre-existing layout
    7190              :    choice into a valid one.  */
    7191              : 
    7192              : int
    7193       248558 : vect_optimize_slp_pass::internal_node_cost (slp_tree node, int in_layout_i,
    7194              :                                             unsigned int out_layout_i)
    7195              : {
    7196       248558 :   const int fallback_cost = 1;
    7197              : 
    7198       248558 :   if (SLP_TREE_PERMUTE_P (node))
    7199              :     {
    7200        31804 :       auto_lane_permutation_t tmp_perm;
    7201        31804 :       tmp_perm.safe_splice (SLP_TREE_LANE_PERMUTATION (node));
    7202              : 
    7203              :       /* Check that the child nodes support the chosen layout.  Checking
    7204              :          the first child is enough, since any second child would have the
    7205              :          same shape.  */
    7206        31804 :       auto first_child = SLP_TREE_CHILDREN (node)[0];
    7207        31804 :       if (in_layout_i > 0
    7208        31804 :           && !is_compatible_layout (first_child, in_layout_i))
    7209              :         return -1;
    7210              : 
    7211        31130 :       change_vec_perm_layout (node, tmp_perm, in_layout_i, out_layout_i);
    7212        62260 :       int count = vectorizable_slp_permutation_1 (m_vinfo, nullptr,
    7213              :                                                   node, tmp_perm,
    7214        31130 :                                                   SLP_TREE_CHILDREN (node),
    7215              :                                                   false);
    7216        31130 :       if (count < 0)
    7217              :         {
    7218         2563 :           if (in_layout_i == 0 && out_layout_i == 0)
    7219              :             {
    7220              :               /* Use the fallback cost if the node could in principle support
    7221              :                  some nonzero layout for both the inputs and the outputs.
    7222              :                  Otherwise assume that the node will be rejected later
    7223              :                  and rebuilt from scalars.  */
    7224          638 :               if (SLP_TREE_LANES (node) == SLP_TREE_LANES (first_child))
    7225              :                 return fallback_cost;
    7226          353 :               return 0;
    7227              :             }
    7228              :           return -1;
    7229              :         }
    7230              : 
    7231              :       /* We currently have no way of telling whether the new layout is cheaper
    7232              :          or more expensive than the old one.  But at least in principle,
    7233              :          it should be worth making zero permutations (whole-vector shuffles)
    7234              :          cheaper than real permutations, in case the pass is able to remove
    7235              :          the latter.  */
    7236        28567 :       return count == 0 ? 0 : 1;
    7237        31804 :     }
    7238              : 
    7239       216754 :   stmt_vec_info rep = SLP_TREE_REPRESENTATIVE (node);
    7240       216754 :   if (rep
    7241       214883 :       && STMT_VINFO_DATA_REF (rep)
    7242        73879 :       && DR_IS_READ (STMT_VINFO_DATA_REF (rep))
    7243       264439 :       && SLP_TREE_LOAD_PERMUTATION (node).exists ())
    7244              :     {
    7245        39208 :       auto_load_permutation_t tmp_perm;
    7246        39208 :       tmp_perm.safe_splice (SLP_TREE_LOAD_PERMUTATION (node));
    7247        39208 :       if (out_layout_i > 0)
    7248        15061 :         vect_slp_permute (m_perms[out_layout_i], tmp_perm, true);
    7249              : 
    7250        39208 :       poly_uint64 vf = 1;
    7251        39208 :       if (auto loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo))
    7252        12176 :         vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
    7253        39208 :       unsigned int n_perms;
    7254        39208 :       if (!vect_transform_slp_perm_load_1 (m_vinfo, node, tmp_perm, vNULL,
    7255              :                                            nullptr, vf, true, false, &n_perms))
    7256              :         {
    7257         2011 :           auto rep = SLP_TREE_REPRESENTATIVE (node);
    7258         2011 :           if (out_layout_i == 0)
    7259              :             {
    7260              :               /* Use the fallback cost if the load is an N-to-N permutation.
    7261              :                  Otherwise assume that the node will be rejected later
    7262              :                  and rebuilt from scalars.  */
    7263         1479 :               if (STMT_VINFO_GROUPED_ACCESS (rep)
    7264         2958 :                   && (DR_GROUP_SIZE (DR_GROUP_FIRST_ELEMENT (rep))
    7265         1479 :                       == SLP_TREE_LANES (node)))
    7266          671 :                 return fallback_cost;
    7267              :               return 0;
    7268              :             }
    7269              :           return -1;
    7270              :         }
    7271              : 
    7272              :       /* See the comment above the corresponding VEC_PERM_EXPR handling.  */
    7273        37197 :       return n_perms == 0 ? 0 : 1;
    7274        39208 :     }
    7275              : 
    7276              :   return 0;
    7277              : }
    7278              : 
    7279              : /* Decide which element layouts we should consider using.  Calculate the
    7280              :    weights associated with inserting layout changes on partition edges.
    7281              :    Also mark partitions that cannot change layout, by setting their
    7282              :    layout to zero.  */
    7283              : 
    7284              : void
    7285       721496 : vect_optimize_slp_pass::start_choosing_layouts ()
    7286              : {
    7287              :   /* Used to assign unique permutation indices.  */
    7288       721496 :   using perm_hash = unbounded_hashmap_traits<
    7289              :     vec_free_hash_base<int_hash_base<unsigned>>,
    7290              :     int_hash<int, -1, -2>
    7291              :   >;
    7292       721496 :   hash_map<vec<unsigned>, int, perm_hash> layout_ids;
    7293              : 
    7294              :   /* Layout 0 is "no change".  */
    7295       721496 :   m_perms.safe_push (vNULL);
    7296              : 
    7297              :   /* Create layouts from existing permutations.  */
    7298       721496 :   auto_load_permutation_t tmp_perm;
    7299      5860113 :   for (unsigned int node_i : m_partitioned_nodes)
    7300              :     {
    7301              :       /* Leafs also double as entries to the reverse graph.  Allow the
    7302              :          layout of those to be changed.  */
    7303      3695625 :       auto &vertex = m_vertices[node_i];
    7304      3695625 :       auto &partition = m_partitions[vertex.partition];
    7305      3695625 :       if (!m_slpg->vertices[node_i].succ)
    7306       946553 :         partition.layout = 0;
    7307              : 
    7308              :       /* Loads and VEC_PERM_EXPRs are the only things generating permutes.  */
    7309      3695625 :       slp_tree node = vertex.node;
    7310      3695625 :       stmt_vec_info dr_stmt = SLP_TREE_REPRESENTATIVE (node);
    7311      3695625 :       slp_tree child;
    7312      3695625 :       unsigned HOST_WIDE_INT imin, imax = 0;
    7313      3695625 :       bool any_permute = false;
    7314      3695625 :       tmp_perm.truncate (0);
    7315      3695625 :       if (SLP_TREE_LOAD_PERMUTATION (node).exists ())
    7316              :         {
    7317              :           /* If splitting out a SLP_TREE_LANE_PERMUTATION can make the node
    7318              :              unpermuted, record a layout that reverses this permutation.
    7319              : 
    7320              :              We would need more work to cope with loads that are internally
    7321              :              permuted and also have inputs (such as masks for
    7322              :              IFN_MASK_LOADs).  */
    7323       637968 :           gcc_assert (partition.layout == 0 && !m_slpg->vertices[node_i].succ);
    7324       637968 :           if (!STMT_VINFO_GROUPED_ACCESS (dr_stmt))
    7325              :             {
    7326       451148 :               partition.layout = -1;
    7327      3673367 :               continue;
    7328              :             }
    7329       186820 :           dr_stmt = DR_GROUP_FIRST_ELEMENT (dr_stmt);
    7330       186820 :           imin = DR_GROUP_SIZE (dr_stmt) + 1;
    7331       186820 :           tmp_perm.safe_splice (SLP_TREE_LOAD_PERMUTATION (node));
    7332              :         }
    7333      5995158 :       else if (SLP_TREE_PERMUTE_P (node)
    7334       139950 :                && SLP_TREE_CHILDREN (node).length () == 1
    7335       120156 :                && (child = SLP_TREE_CHILDREN (node)[0])
    7336      3197607 :                && (TYPE_VECTOR_SUBPARTS (SLP_TREE_VECTYPE (child))
    7337       120156 :                    .is_constant (&imin)))
    7338              :         {
    7339              :           /* If the child has the same vector size as this node,
    7340              :              reversing the permutation can make the permutation a no-op.
    7341              :              In other cases it can change a true permutation into a
    7342              :              full-vector extract.  */
    7343       120156 :           tmp_perm.reserve (SLP_TREE_LANES (node));
    7344       444876 :           for (unsigned j = 0; j < SLP_TREE_LANES (node); ++j)
    7345       204564 :             tmp_perm.quick_push (SLP_TREE_LANE_PERMUTATION (node)[j].second);
    7346              :         }
    7347              :       else
    7348      2937501 :         continue;
    7349              : 
    7350       822730 :       for (unsigned j = 0; j < SLP_TREE_LANES (node); ++j)
    7351              :         {
    7352       515754 :           unsigned idx = tmp_perm[j];
    7353       515754 :           imin = MIN (imin, idx);
    7354       515754 :           imax = MAX (imax, idx);
    7355       515754 :           if (idx - tmp_perm[0] != j)
    7356       164212 :             any_permute = true;
    7357              :         }
    7358              :       /* If the span doesn't match we'd disrupt VF computation, avoid
    7359              :          that for now.  */
    7360       306976 :       if (imax - imin + 1 != SLP_TREE_LANES (node))
    7361        91740 :         continue;
    7362              :       /* If there's no permute no need to split one out.  In this case
    7363              :          we can consider turning a load into a permuted load, if that
    7364              :          turns out to be cheaper than alternatives.  */
    7365       215236 :       if (!any_permute)
    7366              :         {
    7367       192822 :           partition.layout = -1;
    7368       192822 :           continue;
    7369              :         }
    7370              : 
    7371              :       /* For now only handle true permutes, like
    7372              :          vect_attempt_slp_rearrange_stmts did.  This allows us to be lazy
    7373              :          when permuting constants and invariants keeping the permute
    7374              :          bijective.  */
    7375        22414 :       auto_sbitmap load_index (SLP_TREE_LANES (node));
    7376        22414 :       bitmap_clear (load_index);
    7377       112521 :       for (unsigned j = 0; j < SLP_TREE_LANES (node); ++j)
    7378        67693 :         bitmap_set_bit (load_index, tmp_perm[j] - imin);
    7379              :       unsigned j;
    7380        89261 :       for (j = 0; j < SLP_TREE_LANES (node); ++j)
    7381        67003 :         if (!bitmap_bit_p (load_index, j))
    7382              :           break;
    7383        22414 :       if (j != SLP_TREE_LANES (node))
    7384          156 :         continue;
    7385              : 
    7386        22258 :       vec<unsigned> perm = vNULL;
    7387        22258 :       perm.safe_grow (SLP_TREE_LANES (node), true);
    7388       111238 :       for (unsigned j = 0; j < SLP_TREE_LANES (node); ++j)
    7389        66722 :         perm[j] = tmp_perm[j] - imin;
    7390              : 
    7391        44516 :       if (int (m_perms.length ()) >= param_vect_max_layout_candidates)
    7392              :         {
    7393              :           /* Continue to use existing layouts, but don't add any more.  */
    7394            0 :           int *entry = layout_ids.get (perm);
    7395            0 :           partition.layout = entry ? *entry : 0;
    7396            0 :           perm.release ();
    7397              :         }
    7398              :       else
    7399              :         {
    7400        22258 :           bool existed;
    7401        22258 :           int &layout_i = layout_ids.get_or_insert (perm, &existed);
    7402        22258 :           if (existed)
    7403         7891 :             perm.release ();
    7404              :           else
    7405              :             {
    7406        14367 :               layout_i = m_perms.length ();
    7407        14367 :               m_perms.safe_push (perm);
    7408              :             }
    7409        22258 :           partition.layout = layout_i;
    7410              :         }
    7411        22414 :     }
    7412              : 
    7413              :   /* Initially assume that every layout is possible and has zero cost
    7414              :      in every partition.  */
    7415       721496 :   m_partition_layout_costs.safe_grow_cleared (m_partitions.length ()
    7416      1442992 :                                               * m_perms.length ());
    7417              : 
    7418              :   /* We have to mark outgoing permutations facing non-associating-reduction
    7419              :      graph entries that are not represented as to be materialized.
    7420              :      slp_inst_kind_bb_reduc currently only covers associatable reductions.  */
    7421      3711106 :   for (slp_instance instance : m_vinfo->slp_instances)
    7422      1546618 :     if (SLP_INSTANCE_KIND (instance) == slp_inst_kind_ctor)
    7423              :       {
    7424         7293 :         unsigned int node_i = SLP_INSTANCE_TREE (instance)->vertex;
    7425         7293 :         m_partitions[m_vertices[node_i].partition].layout = 0;
    7426              :       }
    7427      1539325 :     else if (SLP_INSTANCE_KIND (instance) == slp_inst_kind_reduc_chain)
    7428              :       {
    7429         2351 :         stmt_vec_info stmt_info
    7430         2351 :           = SLP_TREE_REPRESENTATIVE (SLP_INSTANCE_TREE (instance));
    7431         2351 :         vect_reduc_info reduc_info
    7432         2351 :           = info_for_reduction (as_a <loop_vec_info> (m_vinfo),
    7433              :                                 SLP_INSTANCE_TREE (instance));
    7434         2351 :         if (needs_fold_left_reduction_p (TREE_TYPE
    7435              :                                            (gimple_get_lhs (stmt_info->stmt)),
    7436              :                                          VECT_REDUC_INFO_CODE (reduc_info)))
    7437              :           {
    7438          124 :             unsigned int node_i = SLP_INSTANCE_TREE (instance)->vertex;
    7439          124 :             m_partitions[m_vertices[node_i].partition].layout = 0;
    7440              :           }
    7441              :       }
    7442              : 
    7443              :   /* Check which layouts each node and partition can handle.  Calculate the
    7444              :      weights associated with inserting layout changes on edges.  */
    7445      5860113 :   for (unsigned int node_i : m_partitioned_nodes)
    7446              :     {
    7447      3695625 :       auto &vertex = m_vertices[node_i];
    7448      3695625 :       auto &partition = m_partitions[vertex.partition];
    7449      3695625 :       slp_tree node = vertex.node;
    7450              : 
    7451      3695625 :       vertex.weight = vect_slp_node_weight (m_vinfo, node);
    7452              : 
    7453      3695625 :       if (stmt_vec_info rep = SLP_TREE_REPRESENTATIVE (node))
    7454              :         {
    7455              :           /* We do not handle stores with a permutation, so all
    7456              :              incoming permutations must have been materialized.
    7457              : 
    7458              :              We also don't handle masked grouped loads, which lack a
    7459              :              permutation vector.  In this case the memory locations
    7460              :              form an implicit second input to the loads, on top of the
    7461              :              explicit mask input, and the memory input's layout cannot
    7462              :              be changed.
    7463              : 
    7464              :              On the other hand, we do support permuting gather loads and
    7465              :              masked gather loads, where each scalar load is independent
    7466              :              of the others.  This can be useful if the address/index input
    7467              :              benefits from permutation.  */
    7468      3552526 :           if (STMT_VINFO_DATA_REF (rep)
    7469      1710641 :               && STMT_VINFO_GROUPED_ACCESS (rep)
    7470      4559565 :               && !SLP_TREE_LOAD_PERMUTATION (node).exists ())
    7471       820219 :             partition.layout = 0;
    7472              : 
    7473              :           /* We cannot change the layout of an operation that is
    7474              :              not independent on lanes.  Note this is an explicit
    7475              :              negative list since that's much shorter than the respective
    7476              :              positive one but it's critical to keep maintaining it.  */
    7477      3552526 :           if (is_gimple_call (STMT_VINFO_STMT (rep)))
    7478        32990 :             switch (gimple_call_combined_fn (STMT_VINFO_STMT (rep)))
    7479              :               {
    7480         1098 :               case CFN_COMPLEX_ADD_ROT90:
    7481         1098 :               case CFN_COMPLEX_ADD_ROT270:
    7482         1098 :               case CFN_COMPLEX_MUL:
    7483         1098 :               case CFN_COMPLEX_MUL_CONJ:
    7484         1098 :               case CFN_VEC_ADDSUB:
    7485         1098 :               case CFN_VEC_FMADDSUB:
    7486         1098 :               case CFN_VEC_FMSUBADD:
    7487         1098 :                 partition.layout = 0;
    7488              :               default:;
    7489              :               }
    7490              :         }
    7491              : 
    7492      8347227 :       auto process_edge = [&](graph_edge *ud, unsigned int other_node_i)
    7493              :         {
    7494      4651602 :           auto &other_vertex = m_vertices[other_node_i];
    7495              : 
    7496              :           /* Count the number of edges from earlier partitions and the number
    7497              :              of edges to later partitions.  */
    7498      4651602 :           if (other_vertex.partition < vertex.partition)
    7499      2325801 :             partition.in_degree += 1;
    7500              :           else
    7501      2325801 :             partition.out_degree += 1;
    7502              : 
    7503              :           /* If the current node uses the result of OTHER_NODE_I, accumulate
    7504              :              the effects of that.  */
    7505      4651602 :           if (ud->src == int (node_i))
    7506              :             {
    7507      2325801 :               other_vertex.out_weight += vertex.weight;
    7508      2325801 :               other_vertex.out_degree += 1;
    7509              :             }
    7510      8347227 :         };
    7511      3695625 :       for_each_partition_edge (node_i, process_edge);
    7512              :     }
    7513       721496 : }
    7514              : 
    7515              : /* Return the incoming costs for node NODE_I, assuming that each input keeps
    7516              :    its current (provisional) choice of layout.  The inputs do not necessarily
    7517              :    have the same layout as each other.  */
    7518              : 
    7519              : slpg_layout_cost
    7520         4333 : vect_optimize_slp_pass::total_in_cost (unsigned int node_i)
    7521              : {
    7522         4333 :   auto &vertex = m_vertices[node_i];
    7523         4333 :   slpg_layout_cost cost;
    7524        14405 :   auto add_cost = [&](graph_edge *, unsigned int other_node_i)
    7525              :     {
    7526        10072 :       auto &other_vertex = m_vertices[other_node_i];
    7527        10072 :       if (other_vertex.partition < vertex.partition)
    7528              :         {
    7529         6726 :           auto &other_partition = m_partitions[other_vertex.partition];
    7530        13452 :           auto &other_costs = partition_layout_costs (other_vertex.partition,
    7531         6726 :                                                       other_partition.layout);
    7532         6726 :           slpg_layout_cost this_cost = other_costs.in_cost;
    7533         6726 :           this_cost.add_serial_cost (other_costs.internal_cost);
    7534         6726 :           this_cost.split (other_partition.out_degree);
    7535         6726 :           cost.add_parallel_cost (this_cost);
    7536              :         }
    7537        14405 :     };
    7538         4333 :   for_each_partition_edge (node_i, add_cost);
    7539         4333 :   return cost;
    7540              : }
    7541              : 
    7542              : /* Return the cost of switching between layout LAYOUT1_I (at node NODE1_I)
    7543              :    and layout LAYOUT2_I on cross-partition use-to-def edge UD.  Return
    7544              :    slpg_layout_cost::impossible () if the change isn't possible.  */
    7545              : 
    7546              : slpg_layout_cost
    7547       745918 : vect_optimize_slp_pass::
    7548              : edge_layout_cost (graph_edge *ud, unsigned int node1_i, unsigned int layout1_i,
    7549              :                   unsigned int layout2_i)
    7550              : {
    7551       745918 :   auto &def_vertex = m_vertices[ud->dest];
    7552       745918 :   auto &use_vertex = m_vertices[ud->src];
    7553       745918 :   auto def_layout_i = ud->dest == int (node1_i) ? layout1_i : layout2_i;
    7554       745918 :   auto use_layout_i = ud->dest == int (node1_i) ? layout2_i : layout1_i;
    7555       745918 :   auto factor = change_layout_cost (def_vertex.node, def_layout_i,
    7556              :                                     use_layout_i);
    7557       745918 :   if (factor < 0)
    7558         6078 :     return slpg_layout_cost::impossible ();
    7559              : 
    7560              :   /* We have a choice of putting the layout change at the site of the
    7561              :      definition or at the site of the use.  Prefer the former when
    7562              :      optimizing for size or when the execution frequency of the
    7563              :      definition is no greater than the combined execution frequencies of
    7564              :      the uses.  When putting the layout change at the site of the definition,
    7565              :      divvy up the cost among all consumers.  */
    7566       739840 :   if (m_optimize_size || def_vertex.weight <= def_vertex.out_weight)
    7567              :     {
    7568       697132 :       slpg_layout_cost cost = { def_vertex.weight * factor, m_optimize_size };
    7569       697132 :       cost.split (def_vertex.out_degree);
    7570       697132 :       return cost;
    7571              :     }
    7572        42708 :   return { use_vertex.weight * factor, m_optimize_size };
    7573              : }
    7574              : 
    7575              : /* UD represents a use-def link between FROM_NODE_I and a node in a later
    7576              :    partition; FROM_NODE_I could be the definition node or the use node.
    7577              :    The node at the other end of the link wants to use layout TO_LAYOUT_I.
    7578              :    Return the cost of any necessary fix-ups on edge UD, or return
    7579              :    slpg_layout_cost::impossible () if the change isn't possible.
    7580              : 
    7581              :    At this point, FROM_NODE_I's partition has chosen the cheapest
    7582              :    layout based on the information available so far, but this choice
    7583              :    is only provisional.  */
    7584              : 
    7585              : slpg_layout_cost
    7586       199250 : vect_optimize_slp_pass::forward_cost (graph_edge *ud, unsigned int from_node_i,
    7587              :                                       unsigned int to_layout_i)
    7588              : {
    7589       199250 :   auto &from_vertex = m_vertices[from_node_i];
    7590       199250 :   unsigned int from_partition_i = from_vertex.partition;
    7591       199250 :   slpg_partition_info &from_partition = m_partitions[from_partition_i];
    7592       199250 :   gcc_assert (from_partition.layout >= 0);
    7593              : 
    7594              :   /* First calculate the cost on the assumption that FROM_PARTITION sticks
    7595              :      with its current layout preference.  */
    7596       199250 :   slpg_layout_cost cost = slpg_layout_cost::impossible ();
    7597       199250 :   auto edge_cost = edge_layout_cost (ud, from_node_i,
    7598       199250 :                                      from_partition.layout, to_layout_i);
    7599       199250 :   if (edge_cost.is_possible ())
    7600              :     {
    7601       392084 :       auto &from_costs = partition_layout_costs (from_partition_i,
    7602       196042 :                                                  from_partition.layout);
    7603       196042 :       cost = from_costs.in_cost;
    7604       196042 :       cost.add_serial_cost (from_costs.internal_cost);
    7605       196042 :       cost.split (from_partition.out_degree);
    7606       196042 :       cost.add_serial_cost (edge_cost);
    7607              :     }
    7608         3208 :   else if (from_partition.layout == 0)
    7609              :     /* We must allow the source partition to have layout 0 as a fallback,
    7610              :        in case all other options turn out to be impossible.  */
    7611         3208 :     return cost;
    7612              : 
    7613              :   /* Take the minimum of that cost and the cost that applies if
    7614              :      FROM_PARTITION instead switches to TO_LAYOUT_I.  */
    7615       196042 :   auto &direct_layout_costs = partition_layout_costs (from_partition_i,
    7616              :                                                       to_layout_i);
    7617       196042 :   if (direct_layout_costs.is_possible ())
    7618              :     {
    7619       171997 :       slpg_layout_cost direct_cost = direct_layout_costs.in_cost;
    7620       171997 :       direct_cost.add_serial_cost (direct_layout_costs.internal_cost);
    7621       171997 :       direct_cost.split (from_partition.out_degree);
    7622       171997 :       if (!cost.is_possible ()
    7623       171997 :           || direct_cost.is_better_than (cost, m_optimize_size))
    7624        34133 :         cost = direct_cost;
    7625              :     }
    7626              : 
    7627       196042 :   return cost;
    7628              : }
    7629              : 
    7630              : /* UD represents a use-def link between TO_NODE_I and a node in an earlier
    7631              :    partition; TO_NODE_I could be the definition node or the use node.
    7632              :    The node at the other end of the link wants to use layout FROM_LAYOUT_I;
    7633              :    return the cost of any necessary fix-ups on edge UD, or
    7634              :    slpg_layout_cost::impossible () if the choice cannot be made.
    7635              : 
    7636              :    At this point, TO_NODE_I's partition has a fixed choice of layout.  */
    7637              : 
    7638              : slpg_layout_cost
    7639       178936 : vect_optimize_slp_pass::backward_cost (graph_edge *ud, unsigned int to_node_i,
    7640              :                                        unsigned int from_layout_i)
    7641              : {
    7642       178936 :   auto &to_vertex = m_vertices[to_node_i];
    7643       178936 :   unsigned int to_partition_i = to_vertex.partition;
    7644       178936 :   slpg_partition_info &to_partition = m_partitions[to_partition_i];
    7645       178936 :   gcc_assert (to_partition.layout >= 0);
    7646              : 
    7647              :   /* If TO_NODE_I is a VEC_PERM_EXPR consumer, see whether it can be
    7648              :      adjusted for this input having layout FROM_LAYOUT_I.  Assume that
    7649              :      any other inputs keep their current choice of layout.  */
    7650       178936 :   auto &to_costs = partition_layout_costs (to_partition_i,
    7651              :                                            to_partition.layout);
    7652       178936 :   if (ud->src == int (to_node_i)
    7653       178654 :       && SLP_TREE_PERMUTE_P (to_vertex.node))
    7654              :     {
    7655        11390 :       auto &from_partition = m_partitions[m_vertices[ud->dest].partition];
    7656        11390 :       auto old_layout = from_partition.layout;
    7657        11390 :       from_partition.layout = from_layout_i;
    7658        22780 :       int factor = internal_node_cost (to_vertex.node, -1,
    7659        11390 :                                        to_partition.layout);
    7660        11390 :       from_partition.layout = old_layout;
    7661        11390 :       if (factor >= 0)
    7662              :         {
    7663        10489 :           slpg_layout_cost cost = to_costs.out_cost;
    7664        10489 :           cost.add_serial_cost ({ to_vertex.weight * factor,
    7665              :                                   m_optimize_size });
    7666        10489 :           cost.split (to_partition.in_degree);
    7667        10489 :           return cost;
    7668              :         }
    7669              :     }
    7670              : 
    7671              :   /* Compute the cost if we insert any necessary layout change on edge UD.  */
    7672       168447 :   auto edge_cost = edge_layout_cost (ud, to_node_i,
    7673       168447 :                                      to_partition.layout, from_layout_i);
    7674       168447 :   if (edge_cost.is_possible ())
    7675              :     {
    7676       168447 :       slpg_layout_cost cost = to_costs.out_cost;
    7677       168447 :       cost.add_serial_cost (to_costs.internal_cost);
    7678       168447 :       cost.split (to_partition.in_degree);
    7679       168447 :       cost.add_serial_cost (edge_cost);
    7680       168447 :       return cost;
    7681              :     }
    7682              : 
    7683            0 :   return slpg_layout_cost::impossible ();
    7684              : }
    7685              : 
    7686              : /* Make a forward pass through the partitions, accumulating input costs.
    7687              :    Make a tentative (provisional) choice of layout for each partition,
    7688              :    ensuring that this choice still allows later partitions to keep
    7689              :    their original layout.  */
    7690              : 
    7691              : void
    7692         6578 : vect_optimize_slp_pass::forward_pass ()
    7693              : {
    7694       135507 :   for (unsigned int partition_i = 0; partition_i < m_partitions.length ();
    7695              :        ++partition_i)
    7696              :     {
    7697       128929 :       auto &partition = m_partitions[partition_i];
    7698              : 
    7699              :       /* If the partition consists of a single VEC_PERM_EXPR, precompute
    7700              :          the incoming cost that would apply if every predecessor partition
    7701              :          keeps its current layout.  This is used within the loop below.  */
    7702       128929 :       slpg_layout_cost in_cost;
    7703       128929 :       slp_tree single_node = nullptr;
    7704       128929 :       if (partition.node_end == partition.node_begin + 1)
    7705              :         {
    7706       122512 :           unsigned int node_i = m_partitioned_nodes[partition.node_begin];
    7707       122512 :           single_node = m_vertices[node_i].node;
    7708       122512 :           if (SLP_TREE_PERMUTE_P (single_node))
    7709         4333 :             in_cost = total_in_cost (node_i);
    7710              :         }
    7711              : 
    7712              :       /* Go through the possible layouts.  Decide which ones are valid
    7713              :          for this partition and record which of the valid layouts has
    7714              :          the lowest cost.  */
    7715       128929 :       unsigned int min_layout_i = 0;
    7716       128929 :       slpg_layout_cost min_layout_cost = slpg_layout_cost::impossible ();
    7717       397253 :       for (unsigned int layout_i = 0; layout_i < m_perms.length (); ++layout_i)
    7718              :         {
    7719       268324 :           auto &layout_costs = partition_layout_costs (partition_i, layout_i);
    7720       268324 :           if (!layout_costs.is_possible ())
    7721        69687 :             continue;
    7722              : 
    7723              :           /* If the recorded layout is already 0 then the layout cannot
    7724              :              change.  */
    7725       268324 :           if (partition.layout == 0 && layout_i != 0)
    7726              :             {
    7727        48225 :               layout_costs.mark_impossible ();
    7728        48225 :               continue;
    7729              :             }
    7730              : 
    7731       220099 :           bool is_possible = true;
    7732       448238 :           for (unsigned int order_i = partition.node_begin;
    7733       448238 :                order_i < partition.node_end; ++order_i)
    7734              :             {
    7735       246706 :               unsigned int node_i = m_partitioned_nodes[order_i];
    7736       246706 :               auto &vertex = m_vertices[node_i];
    7737              : 
    7738              :               /* Reject the layout if it is individually incompatible
    7739              :                  with any node in the partition.  */
    7740       246706 :               if (!is_compatible_layout (vertex.node, layout_i))
    7741              :                 {
    7742        17057 :                   is_possible = false;
    7743        18567 :                   break;
    7744              :                 }
    7745              : 
    7746       611561 :               auto add_cost = [&](graph_edge *ud, unsigned int other_node_i)
    7747              :                 {
    7748       381912 :                   auto &other_vertex = m_vertices[other_node_i];
    7749       381912 :                   if (other_vertex.partition < vertex.partition)
    7750              :                     {
    7751              :                       /* Accumulate the incoming costs from earlier
    7752              :                          partitions, plus the cost of any layout changes
    7753              :                          on UD itself.  */
    7754       199250 :                       auto cost = forward_cost (ud, other_node_i, layout_i);
    7755       199250 :                       if (!cost.is_possible ())
    7756         3208 :                         is_possible = false;
    7757              :                       else
    7758       196042 :                         layout_costs.in_cost.add_parallel_cost (cost);
    7759              :                     }
    7760              :                   else
    7761              :                     /* Reject the layout if it would make layout 0 impossible
    7762              :                        for later partitions.  This amounts to testing that the
    7763              :                        target supports reversing the layout change on edges
    7764              :                        to later partitions.
    7765              : 
    7766              :                        In principle, it might be possible to push a layout
    7767              :                        change all the way down a graph, so that it never
    7768              :                        needs to be reversed and so that the target doesn't
    7769              :                        need to support the reverse operation.  But it would
    7770              :                        be awkward to bail out if we hit a partition that
    7771              :                        does not support the new layout, especially since
    7772              :                        we are not dealing with a lattice.  */
    7773       182662 :                     is_possible &= edge_layout_cost (ud, other_node_i, 0,
    7774       182662 :                                                      layout_i).is_possible ();
    7775       611561 :                 };
    7776       229649 :               for_each_partition_edge (node_i, add_cost);
    7777              : 
    7778              :               /* Accumulate the cost of using LAYOUT_I within NODE,
    7779              :                  both for the inputs and the outputs.  */
    7780       229649 :               int factor = internal_node_cost (vertex.node, layout_i,
    7781              :                                                layout_i);
    7782       229649 :               if (factor < 0)
    7783              :                 {
    7784         1510 :                   is_possible = false;
    7785         1510 :                   break;
    7786              :                 }
    7787       228139 :               else if (factor)
    7788        36235 :                 layout_costs.internal_cost.add_serial_cost
    7789        36235 :                   ({ vertex.weight * factor, m_optimize_size });
    7790              :             }
    7791       220099 :           if (!is_possible)
    7792              :             {
    7793        21462 :               layout_costs.mark_impossible ();
    7794        21462 :               continue;
    7795              :             }
    7796              : 
    7797              :           /* Combine the incoming and partition-internal costs.  */
    7798       198637 :           slpg_layout_cost combined_cost = layout_costs.in_cost;
    7799       198637 :           combined_cost.add_serial_cost (layout_costs.internal_cost);
    7800              : 
    7801              :           /* If this partition consists of a single VEC_PERM_EXPR, see
    7802              :              if the VEC_PERM_EXPR can be changed to support output layout
    7803              :              LAYOUT_I while keeping all the provisional choices of input
    7804              :              layout.  */
    7805       198637 :           if (single_node && SLP_TREE_PERMUTE_P (single_node))
    7806              :             {
    7807         7519 :               int factor = internal_node_cost (single_node, -1, layout_i);
    7808         7519 :               if (factor >= 0)
    7809              :                 {
    7810         6799 :                   auto weight = m_vertices[single_node->vertex].weight;
    7811         6799 :                   slpg_layout_cost internal_cost
    7812         6799 :                     = { weight * factor, m_optimize_size };
    7813              : 
    7814         6799 :                   slpg_layout_cost alt_cost = in_cost;
    7815         6799 :                   alt_cost.add_serial_cost (internal_cost);
    7816         6799 :                   if (alt_cost.is_better_than (combined_cost, m_optimize_size))
    7817              :                     {
    7818         1636 :                       combined_cost = alt_cost;
    7819         1636 :                       layout_costs.in_cost = in_cost;
    7820         1636 :                       layout_costs.internal_cost = internal_cost;
    7821              :                     }
    7822              :                 }
    7823              :             }
    7824              : 
    7825              :           /* Record the layout with the lowest cost.  Prefer layout 0 in
    7826              :              the event of a tie between it and another layout.  */
    7827       198637 :           if (!min_layout_cost.is_possible ()
    7828        69708 :               || combined_cost.is_better_than (min_layout_cost,
    7829              :                                                m_optimize_size))
    7830              :             {
    7831       146391 :               min_layout_i = layout_i;
    7832       146391 :               min_layout_cost = combined_cost;
    7833              :             }
    7834              :         }
    7835              : 
    7836              :       /* This loop's handling of earlier partitions should ensure that
    7837              :          choosing the original layout for the current partition is no
    7838              :          less valid than it was in the original graph, even with the
    7839              :          provisional layout choices for those earlier partitions.  */
    7840       128929 :       gcc_assert (min_layout_cost.is_possible ());
    7841       128929 :       partition.layout = min_layout_i;
    7842              :     }
    7843         6578 : }
    7844              : 
    7845              : /* Make a backward pass through the partitions, accumulating output costs.
    7846              :    Make a final choice of layout for each partition.  */
    7847              : 
    7848              : void
    7849         6578 : vect_optimize_slp_pass::backward_pass ()
    7850              : {
    7851       142085 :   for (unsigned int partition_i = m_partitions.length (); partition_i-- > 0;)
    7852              :     {
    7853       128929 :       auto &partition = m_partitions[partition_i];
    7854              : 
    7855       128929 :       unsigned int min_layout_i = 0;
    7856       128929 :       slpg_layout_cost min_layout_cost = slpg_layout_cost::impossible ();
    7857       397253 :       for (unsigned int layout_i = 0; layout_i < m_perms.length (); ++layout_i)
    7858              :         {
    7859       268324 :           auto &layout_costs = partition_layout_costs (partition_i, layout_i);
    7860       268324 :           if (!layout_costs.is_possible ())
    7861        69687 :             continue;
    7862              : 
    7863              :           /* Accumulate the costs from successor partitions.  */
    7864       198637 :           bool is_possible = true;
    7865       423856 :           for (unsigned int order_i = partition.node_begin;
    7866       423856 :                order_i < partition.node_end; ++order_i)
    7867              :             {
    7868       225219 :               unsigned int node_i = m_partitioned_nodes[order_i];
    7869       225219 :               auto &vertex = m_vertices[node_i];
    7870       599714 :               auto add_cost = [&](graph_edge *ud, unsigned int other_node_i)
    7871              :                 {
    7872       374495 :                   auto &other_vertex = m_vertices[other_node_i];
    7873       374495 :                   auto &other_partition = m_partitions[other_vertex.partition];
    7874       374495 :                   if (other_vertex.partition > vertex.partition)
    7875              :                     {
    7876              :                       /* Accumulate the incoming costs from later
    7877              :                          partitions, plus the cost of any layout changes
    7878              :                          on UD itself.  */
    7879       178936 :                       auto cost = backward_cost (ud, other_node_i, layout_i);
    7880       178936 :                       if (!cost.is_possible ())
    7881            0 :                         is_possible = false;
    7882              :                       else
    7883       178936 :                         layout_costs.out_cost.add_parallel_cost (cost);
    7884              :                     }
    7885              :                   else
    7886              :                     /* Make sure that earlier partitions can (if necessary
    7887              :                        or beneficial) keep the layout that they chose in
    7888              :                        the forward pass.  This ensures that there is at
    7889              :                        least one valid choice of layout.  */
    7890       195559 :                     is_possible &= edge_layout_cost (ud, other_node_i,
    7891       195559 :                                                      other_partition.layout,
    7892       195559 :                                                      layout_i).is_possible ();
    7893       599714 :                 };
    7894       225219 :               for_each_partition_edge (node_i, add_cost);
    7895              :             }
    7896       198637 :           if (!is_possible)
    7897              :             {
    7898            0 :               layout_costs.mark_impossible ();
    7899            0 :               continue;
    7900              :             }
    7901              : 
    7902              :           /* Locally combine the costs from the forward and backward passes.
    7903              :              (This combined cost is not passed on, since that would lead
    7904              :              to double counting.)  */
    7905       198637 :           slpg_layout_cost combined_cost = layout_costs.in_cost;
    7906       198637 :           combined_cost.add_serial_cost (layout_costs.internal_cost);
    7907       198637 :           combined_cost.add_serial_cost (layout_costs.out_cost);
    7908              : 
    7909              :           /* Record the layout with the lowest cost.  Prefer layout 0 in
    7910              :              the event of a tie between it and another layout.  */
    7911       198637 :           if (!min_layout_cost.is_possible ()
    7912        69708 :               || combined_cost.is_better_than (min_layout_cost,
    7913              :                                                m_optimize_size))
    7914              :             {
    7915       140033 :               min_layout_i = layout_i;
    7916       140033 :               min_layout_cost = combined_cost;
    7917              :             }
    7918              :         }
    7919              : 
    7920       128929 :       gcc_assert (min_layout_cost.is_possible ());
    7921       128929 :       partition.layout = min_layout_i;
    7922              :     }
    7923         6578 : }
    7924              : 
    7925              : /* Return a node that applies layout TO_LAYOUT_I to the original form of NODE.
    7926              :    NODE already has the layout that was selected for its partition.  */
    7927              : 
    7928              : slp_tree
    7929       180717 : vect_optimize_slp_pass::get_result_with_layout (slp_tree node,
    7930              :                                                 unsigned int to_layout_i)
    7931              : {
    7932       180717 :   unsigned int result_i = node->vertex * m_perms.length () + to_layout_i;
    7933       180717 :   slp_tree result = m_node_layouts[result_i];
    7934       180717 :   if (result)
    7935              :     return result;
    7936              : 
    7937       179800 :   if (SLP_TREE_DEF_TYPE (node) == vect_constant_def
    7938       179800 :       || (SLP_TREE_DEF_TYPE (node) == vect_external_def
    7939              :           /* We can't permute vector defs in place.  */
    7940        22161 :           && SLP_TREE_VEC_DEFS (node).is_empty ()))
    7941              :     {
    7942              :       /* If the vector is uniform or unchanged, there's nothing to do.  */
    7943        47031 :       if (to_layout_i == 0 || vect_slp_tree_uniform_p (node))
    7944              :         result = node;
    7945              :       else
    7946              :         {
    7947         3681 :           auto scalar_ops = SLP_TREE_SCALAR_OPS (node).copy ();
    7948         3681 :           result = vect_create_new_slp_node (scalar_ops);
    7949         3681 :           vect_slp_permute (m_perms[to_layout_i], scalar_ops, true);
    7950              :         }
    7951              :     }
    7952              :   else
    7953              :     {
    7954       132769 :       unsigned int partition_i = m_vertices[node->vertex].partition;
    7955       132769 :       unsigned int from_layout_i = m_partitions[partition_i].layout;
    7956       132769 :       if (from_layout_i == to_layout_i)
    7957       131552 :         return node;
    7958              : 
    7959              :       /* If NODE is itself a VEC_PERM_EXPR, try to create a parallel
    7960              :          permutation instead of a serial one.  Leave the new permutation
    7961              :          in TMP_PERM on success.  */
    7962         1217 :       auto_lane_permutation_t tmp_perm;
    7963         1217 :       unsigned int num_inputs = 1;
    7964         1217 :       if (SLP_TREE_PERMUTE_P (node))
    7965              :         {
    7966          103 :           tmp_perm.safe_splice (SLP_TREE_LANE_PERMUTATION (node));
    7967          103 :           if (from_layout_i != 0)
    7968           43 :             vect_slp_permute (m_perms[from_layout_i], tmp_perm, false);
    7969          103 :           if (to_layout_i != 0)
    7970           64 :             vect_slp_permute (m_perms[to_layout_i], tmp_perm, true);
    7971          103 :           if (vectorizable_slp_permutation_1 (m_vinfo, nullptr, node,
    7972              :                                               tmp_perm,
    7973          103 :                                               SLP_TREE_CHILDREN (node),
    7974              :                                               false) >= 0)
    7975          103 :             num_inputs = SLP_TREE_CHILDREN (node).length ();
    7976              :           else
    7977            0 :             tmp_perm.truncate (0);
    7978              :         }
    7979              : 
    7980         1217 :       if (dump_enabled_p ())
    7981              :         {
    7982           71 :           if (tmp_perm.length () > 0)
    7983            6 :             dump_printf_loc (MSG_NOTE, vect_location,
    7984              :                              "duplicating permutation node %p with"
    7985              :                              " layout %d\n",
    7986              :                              (void *) node, to_layout_i);
    7987              :           else
    7988           65 :             dump_printf_loc (MSG_NOTE, vect_location,
    7989              :                              "inserting permutation node in place of %p\n",
    7990              :                              (void *) node);
    7991              :         }
    7992              : 
    7993         1217 :       unsigned int num_lanes = SLP_TREE_LANES (node);
    7994         1217 :       result = vect_create_new_slp_node (num_inputs, VEC_PERM_EXPR);
    7995         1217 :       if (SLP_TREE_SCALAR_STMTS (node).exists ())
    7996              :         {
    7997         1217 :           auto &stmts = SLP_TREE_SCALAR_STMTS (result);
    7998         1217 :           stmts.safe_splice (SLP_TREE_SCALAR_STMTS (node));
    7999         1217 :           if (from_layout_i != 0)
    8000          500 :             vect_slp_permute (m_perms[from_layout_i], stmts, false);
    8001         1217 :           if (to_layout_i != 0)
    8002          721 :             vect_slp_permute (m_perms[to_layout_i], stmts, true);
    8003              :         }
    8004         1217 :       SLP_TREE_LANES (result) = num_lanes;
    8005         1217 :       SLP_TREE_VECTYPE (result) = SLP_TREE_VECTYPE (node);
    8006         1217 :       result->vertex = -1;
    8007              : 
    8008         1217 :       auto &lane_perm = SLP_TREE_LANE_PERMUTATION (result);
    8009         1217 :       if (tmp_perm.length ())
    8010              :         {
    8011          103 :           lane_perm.safe_splice (tmp_perm);
    8012          103 :           SLP_TREE_CHILDREN (result).safe_splice (SLP_TREE_CHILDREN (node));
    8013              :         }
    8014              :       else
    8015              :         {
    8016         1114 :           lane_perm.create (num_lanes);
    8017         4538 :           for (unsigned j = 0; j < num_lanes; ++j)
    8018         2310 :             lane_perm.quick_push ({ 0, j });
    8019         1114 :           if (from_layout_i != 0)
    8020          457 :             vect_slp_permute (m_perms[from_layout_i], lane_perm, false);
    8021         1114 :           if (to_layout_i != 0)
    8022          657 :             vect_slp_permute (m_perms[to_layout_i], lane_perm, true);
    8023         1114 :           SLP_TREE_CHILDREN (result).safe_push (node);
    8024              :         }
    8025         4940 :       for (slp_tree child : SLP_TREE_CHILDREN (result))
    8026         1289 :         child->refcnt++;
    8027         1217 :     }
    8028        48248 :   m_node_layouts[result_i] = result;
    8029        48248 :   return result;
    8030              : }
    8031              : 
    8032              : /* Apply the chosen vector layouts to the SLP graph.  */
    8033              : 
    8034              : void
    8035        13799 : vect_optimize_slp_pass::materialize ()
    8036              : {
    8037              :   /* We no longer need the costs, so avoid having two O(N * P) arrays
    8038              :      live at the same time.  */
    8039        13799 :   m_partition_layout_costs.release ();
    8040        41397 :   m_node_layouts.safe_grow_cleared (m_vertices.length () * m_perms.length ());
    8041              : 
    8042        27598 :   auto_sbitmap fully_folded (m_vertices.length ());
    8043        13799 :   bitmap_clear (fully_folded);
    8044       200868 :   for (unsigned int node_i : m_partitioned_nodes)
    8045              :     {
    8046       159471 :       auto &vertex = m_vertices[node_i];
    8047       159471 :       slp_tree node = vertex.node;
    8048       159471 :       int layout_i = m_partitions[vertex.partition].layout;
    8049       159471 :       gcc_assert (layout_i >= 0);
    8050              : 
    8051              :       /* Rearrange the scalar statements to match the chosen layout.  */
    8052       159471 :       if (layout_i > 0)
    8053        26688 :         vect_slp_permute (m_perms[layout_i],
    8054        26688 :                           SLP_TREE_SCALAR_STMTS (node), true);
    8055              : 
    8056              :       /* Update load and lane permutations.  */
    8057       159471 :       if (SLP_TREE_PERMUTE_P (node))
    8058              :         {
    8059              :           /* First try to absorb the input vector layouts.  If that fails,
    8060              :              force the inputs to have layout LAYOUT_I too.  We checked that
    8061              :              that was possible before deciding to use nonzero output layouts.
    8062              :              (Note that at this stage we don't really have any guarantee that
    8063              :              the target supports the original VEC_PERM_EXPR.)  */
    8064         6532 :           auto &perm = SLP_TREE_LANE_PERMUTATION (node);
    8065         6532 :           auto_lane_permutation_t tmp_perm;
    8066         6532 :           tmp_perm.safe_splice (perm);
    8067         6532 :           change_vec_perm_layout (node, tmp_perm, -1, layout_i);
    8068         6532 :           if (vectorizable_slp_permutation_1 (m_vinfo, nullptr, node,
    8069              :                                               tmp_perm,
    8070         6532 :                                               SLP_TREE_CHILDREN (node),
    8071              :                                               false) >= 0)
    8072              :             {
    8073         5894 :               if (dump_enabled_p ()
    8074         6822 :                   && !std::equal (tmp_perm.begin (), tmp_perm.end (),
    8075              :                                   perm.begin ()))
    8076           58 :                 dump_printf_loc (MSG_NOTE, vect_location,
    8077              :                                  "absorbing input layouts into %p\n",
    8078              :                                  (void *) node);
    8079        33335 :               std::copy (tmp_perm.begin (), tmp_perm.end (), perm.begin ());
    8080         5894 :               bitmap_set_bit (fully_folded, node_i);
    8081              :             }
    8082              :           else
    8083              :             {
    8084              :               /* Not MSG_MISSED because it would make no sense to users.  */
    8085          638 :               if (dump_enabled_p ())
    8086           46 :                 dump_printf_loc (MSG_NOTE, vect_location,
    8087              :                                  "failed to absorb input layouts into %p\n",
    8088              :                                  (void *) node);
    8089          638 :               change_vec_perm_layout (nullptr, perm, layout_i, layout_i);
    8090              :             }
    8091         6532 :         }
    8092              :       else
    8093              :         {
    8094       152939 :           gcc_assert (!SLP_TREE_LANE_PERMUTATION (node).exists ());
    8095       152939 :           auto &load_perm = SLP_TREE_LOAD_PERMUTATION (node);
    8096       152939 :           if (layout_i > 0)
    8097              :             /* ???  When we handle non-bijective permutes the idea
    8098              :                is that we can force the load-permutation to be
    8099              :                { min, min + 1, min + 2, ... max }.  But then the
    8100              :                scalar defs might no longer match the lane content
    8101              :                which means wrong-code with live lane vectorization.
    8102              :                So we possibly have to have NULL entries for those.  */
    8103        25878 :             vect_slp_permute (m_perms[layout_i], load_perm, true);
    8104              :         }
    8105              :     }
    8106              : 
    8107              :   /* Do this before any nodes disappear, since it involves a walk
    8108              :      over the leaves.  */
    8109        13799 :   remove_redundant_permutations ();
    8110              : 
    8111              :   /* Replace each child with a correctly laid-out version.  */
    8112       200868 :   for (unsigned int node_i : m_partitioned_nodes)
    8113              :     {
    8114              :       /* Skip nodes that have already been handled above.  */
    8115       159471 :       if (bitmap_bit_p (fully_folded, node_i))
    8116         5894 :         continue;
    8117              : 
    8118       153577 :       auto &vertex = m_vertices[node_i];
    8119       153577 :       int in_layout_i = m_partitions[vertex.partition].layout;
    8120       153577 :       gcc_assert (in_layout_i >= 0);
    8121              : 
    8122              :       unsigned j;
    8123              :       slp_tree child;
    8124       457054 :       FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (vertex.node), j, child)
    8125              :         {
    8126       186767 :           if (!child)
    8127         6050 :             continue;
    8128              : 
    8129       180717 :           slp_tree new_child = get_result_with_layout (child, in_layout_i);
    8130       180717 :           if (new_child != child)
    8131              :             {
    8132         5482 :               vect_free_slp_tree (child);
    8133         5482 :               SLP_TREE_CHILDREN (vertex.node)[j] = new_child;
    8134         5482 :               new_child->refcnt += 1;
    8135              :             }
    8136              :         }
    8137              :     }
    8138        13799 : }
    8139              : 
    8140              : /* Elide load permutations that are not necessary.  Such permutations might
    8141              :    be pre-existing, rather than created by the layout optimizations.  */
    8142              : 
    8143              : void
    8144       721496 : vect_optimize_slp_pass::remove_redundant_permutations ()
    8145              : {
    8146      4778214 :   for (unsigned int node_i : m_leafs)
    8147              :     {
    8148      2613726 :       slp_tree node = m_vertices[node_i].node;
    8149      2613726 :       if (!SLP_TREE_LOAD_PERMUTATION (node).exists ())
    8150      1975758 :         continue;
    8151              : 
    8152              :       /* In basic block vectorization we allow any subchain of an interleaving
    8153              :          chain.
    8154              :          FORNOW: not in loop SLP because of realignment complications.  */
    8155       637968 :       if (is_a <bb_vec_info> (m_vinfo))
    8156              :         {
    8157       191723 :           bool subchain_p = true;
    8158              :           stmt_vec_info next_load_info = NULL;
    8159              :           stmt_vec_info load_info;
    8160              :           unsigned j;
    8161       191723 :           FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), j, load_info)
    8162              :             {
    8163       158222 :               if (j != 0
    8164       158222 :                   && (next_load_info != load_info
    8165        70240 :                       || ! load_info
    8166        70240 :                       || DR_GROUP_GAP (load_info) != 1))
    8167              :                 {
    8168              :                   subchain_p = false;
    8169              :                   break;
    8170              :                 }
    8171       126892 :               next_load_info = DR_GROUP_NEXT_ELEMENT (load_info);
    8172              :             }
    8173        64831 :           if (subchain_p)
    8174              :             {
    8175        33501 :               SLP_TREE_LOAD_PERMUTATION (node).release ();
    8176        33501 :               continue;
    8177              :             }
    8178              :         }
    8179              :       else
    8180              :         {
    8181       573137 :           loop_vec_info loop_vinfo = as_a<loop_vec_info> (m_vinfo);
    8182       573137 :           bool this_load_permuted = !vect_load_perm_consecutive_p (node, 0);
    8183              :           /* When this isn't a grouped access we know it's single element
    8184              :              and contiguous.  */
    8185       573137 :           if (!STMT_VINFO_GROUPED_ACCESS (SLP_TREE_SCALAR_STMTS (node)[0]))
    8186              :             {
    8187       451148 :               if (!this_load_permuted
    8188       451148 :                   && (known_eq (LOOP_VINFO_VECT_FACTOR (loop_vinfo), 1U)
    8189       450375 :                       || SLP_TREE_LANES (node) == 1))
    8190       450387 :                 SLP_TREE_LOAD_PERMUTATION (node).release ();
    8191       451148 :               continue;
    8192              :             }
    8193       121989 :           stmt_vec_info first_stmt_info
    8194       121989 :             = DR_GROUP_FIRST_ELEMENT (SLP_TREE_SCALAR_STMTS (node)[0]);
    8195       122522 :           if (!this_load_permuted
    8196              :               /* The load requires permutation when unrolling exposes
    8197              :                  a gap either because the group is larger than the SLP
    8198              :                  group-size or because there is a gap between the groups.  */
    8199       121989 :               && (known_eq (LOOP_VINFO_VECT_FACTOR (loop_vinfo), 1U)
    8200        99301 :                   || ((SLP_TREE_LANES (node) == DR_GROUP_SIZE (first_stmt_info))
    8201          147 :                       && DR_GROUP_GAP (first_stmt_info) == 0)))
    8202              :             {
    8203          533 :               SLP_TREE_LOAD_PERMUTATION (node).release ();
    8204          533 :               continue;
    8205              :             }
    8206              :         }
    8207              :     }
    8208       721496 : }
    8209              : 
    8210              : /* Print the partition graph and layout information to the dump file.  */
    8211              : 
    8212              : void
    8213          691 : vect_optimize_slp_pass::dump ()
    8214              : {
    8215          691 :   dump_printf_loc (MSG_NOTE, vect_location,
    8216              :                    "SLP optimize permutations:\n");
    8217         1395 :   for (unsigned int layout_i = 1; layout_i < m_perms.length (); ++layout_i)
    8218              :     {
    8219          704 :       dump_printf_loc (MSG_NOTE, vect_location, "  %d: { ", layout_i);
    8220          704 :       const char *sep = "";
    8221         5976 :       for (unsigned int idx : m_perms[layout_i])
    8222              :         {
    8223         3864 :           dump_printf (MSG_NOTE, "%s%d", sep, idx);
    8224         3864 :           sep = ", ";
    8225              :         }
    8226          704 :       dump_printf (MSG_NOTE, " }\n");
    8227              :     }
    8228          691 :   dump_printf_loc (MSG_NOTE, vect_location,
    8229              :                    "SLP optimize partitions:\n");
    8230         5996 :   for (unsigned int partition_i = 0; partition_i < m_partitions.length ();
    8231              :        ++partition_i)
    8232              :     {
    8233         5305 :       auto &partition = m_partitions[partition_i];
    8234         5305 :       dump_printf_loc (MSG_NOTE, vect_location,  "  -------------\n");
    8235         5305 :       dump_printf_loc (MSG_NOTE, vect_location,
    8236              :                        "  partition %d (layout %d):\n",
    8237              :                        partition_i, partition.layout);
    8238         5305 :       dump_printf_loc (MSG_NOTE, vect_location, "    nodes:\n");
    8239        10849 :       for (unsigned int order_i = partition.node_begin;
    8240        10849 :            order_i < partition.node_end; ++order_i)
    8241              :         {
    8242         5544 :           auto &vertex = m_vertices[m_partitioned_nodes[order_i]];
    8243        11088 :           dump_printf_loc (MSG_NOTE, vect_location, "      - %p:\n",
    8244         5544 :                            (void *) vertex.node);
    8245         5544 :           dump_printf_loc (MSG_NOTE, vect_location,
    8246              :                            "          weight: %f\n",
    8247              :                            vertex.weight.to_double ());
    8248         5544 :           if (vertex.out_degree)
    8249         4344 :             dump_printf_loc (MSG_NOTE, vect_location,
    8250              :                              "          out weight: %f (degree %d)\n",
    8251              :                              vertex.out_weight.to_double (),
    8252              :                              vertex.out_degree);
    8253         5544 :           if (SLP_TREE_PERMUTE_P (vertex.node))
    8254          510 :             dump_printf_loc (MSG_NOTE, vect_location,
    8255              :                              "          op: VEC_PERM_EXPR\n");
    8256         5034 :           else if (auto rep = SLP_TREE_REPRESENTATIVE (vertex.node))
    8257         5016 :             dump_printf_loc (MSG_NOTE, vect_location,
    8258              :                              "          op template: %G", rep->stmt);
    8259              :         }
    8260         5305 :       dump_printf_loc (MSG_NOTE, vect_location, "    edges:\n");
    8261        10849 :       for (unsigned int order_i = partition.node_begin;
    8262        10849 :            order_i < partition.node_end; ++order_i)
    8263              :         {
    8264         5544 :           unsigned int node_i = m_partitioned_nodes[order_i];
    8265         5544 :           auto &vertex = m_vertices[node_i];
    8266        16782 :           auto print_edge = [&](graph_edge *, unsigned int other_node_i)
    8267              :             {
    8268        11238 :               auto &other_vertex = m_vertices[other_node_i];
    8269        11238 :               if (other_vertex.partition < vertex.partition)
    8270         5619 :                 dump_printf_loc (MSG_NOTE, vect_location,
    8271              :                                  "      - %p [%d] --> %p\n",
    8272         5619 :                                  (void *) other_vertex.node,
    8273              :                                  other_vertex.partition,
    8274         5619 :                                  (void *) vertex.node);
    8275              :               else
    8276         5619 :                 dump_printf_loc (MSG_NOTE, vect_location,
    8277              :                                  "      - %p --> [%d] %p\n",
    8278         5619 :                                  (void *) vertex.node,
    8279              :                                  other_vertex.partition,
    8280         5619 :                                  (void *) other_vertex.node);
    8281        16782 :             };
    8282         5544 :           for_each_partition_edge (node_i, print_edge);
    8283              :         }
    8284              : 
    8285        16114 :       for (unsigned int layout_i = 0; layout_i < m_perms.length (); ++layout_i)
    8286              :         {
    8287        10809 :           auto &layout_costs = partition_layout_costs (partition_i, layout_i);
    8288        10809 :           if (layout_costs.is_possible ())
    8289              :             {
    8290         8952 :               dump_printf_loc (MSG_NOTE, vect_location,
    8291              :                                "    layout %d:%s\n", layout_i,
    8292         8952 :                                partition.layout == int (layout_i)
    8293              :                                ? " (*)" : "");
    8294         8952 :               slpg_layout_cost combined_cost = layout_costs.in_cost;
    8295         8952 :               combined_cost.add_serial_cost (layout_costs.internal_cost);
    8296         8952 :               combined_cost.add_serial_cost (layout_costs.out_cost);
    8297              : #define TEMPLATE "{depth: %f, total: %f}"
    8298         8952 :               dump_printf_loc (MSG_NOTE, vect_location,
    8299              :                                "        " TEMPLATE "\n",
    8300              :                                layout_costs.in_cost.depth.to_double (),
    8301              :                                layout_costs.in_cost.total.to_double ());
    8302         8952 :               dump_printf_loc (MSG_NOTE, vect_location,
    8303              :                                "      + " TEMPLATE "\n",
    8304              :                                layout_costs.internal_cost.depth.to_double (),
    8305              :                                layout_costs.internal_cost.total.to_double ());
    8306         8952 :               dump_printf_loc (MSG_NOTE, vect_location,
    8307              :                                "      + " TEMPLATE "\n",
    8308              :                                layout_costs.out_cost.depth.to_double (),
    8309              :                                layout_costs.out_cost.total.to_double ());
    8310         8952 :               dump_printf_loc (MSG_NOTE, vect_location,
    8311              :                                "      = " TEMPLATE "\n",
    8312              :                                combined_cost.depth.to_double (),
    8313              :                                combined_cost.total.to_double ());
    8314              : #undef TEMPLATE
    8315              :             }
    8316              :           else
    8317         1857 :             dump_printf_loc (MSG_NOTE, vect_location,
    8318              :                              "    layout %d: rejected\n", layout_i);
    8319              :         }
    8320              :     }
    8321          691 : }
    8322              : 
    8323              : /* Masked load lanes discovery.  */
    8324              : 
    8325              : void
    8326       721496 : vect_optimize_slp_pass::decide_masked_load_lanes ()
    8327              : {
    8328      7435589 :   for (auto v : m_vertices)
    8329              :     {
    8330      5271101 :       slp_tree node = v.node;
    8331      5271101 :       if (SLP_TREE_DEF_TYPE (node) != vect_internal_def
    8332      3693602 :           || SLP_TREE_PERMUTE_P (node))
    8333      1718575 :         continue;
    8334      3552526 :       stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node);
    8335      1710641 :       if (! STMT_VINFO_GROUPED_ACCESS (stmt_info)
    8336              :           /* The mask has to be uniform.  */
    8337      1007039 :           || STMT_VINFO_SLP_VECT_ONLY (stmt_info)
    8338      1006961 :           || ! is_a <gcall *> (STMT_VINFO_STMT (stmt_info))
    8339      3552611 :           || ! gimple_call_internal_p (STMT_VINFO_STMT (stmt_info),
    8340              :                                        IFN_MASK_LOAD))
    8341      3552493 :         continue;
    8342           33 :       stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
    8343           66 :       if (STMT_VINFO_STRIDED_P (stmt_info)
    8344           33 :           || compare_step_with_zero (m_vinfo, stmt_info) <= 0
    8345           63 :           || vect_load_lanes_supported (SLP_TREE_VECTYPE (node),
    8346           30 :                                         DR_GROUP_SIZE (stmt_info),
    8347              :                                         true) == IFN_LAST)
    8348           33 :         continue;
    8349              : 
    8350              :       /* Uniform masks need to be suitably represented.  */
    8351            0 :       slp_tree mask = SLP_TREE_CHILDREN (node)[0];
    8352            0 :       if (!SLP_TREE_PERMUTE_P (mask)
    8353            0 :           || SLP_TREE_CHILDREN (mask).length () != 1)
    8354            0 :         continue;
    8355            0 :       bool match = true;
    8356            0 :       for (auto perm : SLP_TREE_LANE_PERMUTATION (mask))
    8357            0 :         if (perm.first != 0 || perm.second != 0)
    8358              :           {
    8359              :             match = false;
    8360              :             break;
    8361              :           }
    8362            0 :       if (!match)
    8363            0 :         continue;
    8364              : 
    8365              :       /* Now see if the consumer side matches.  */
    8366            0 :       for (graph_edge *pred = m_slpg->vertices[node->vertex].pred;
    8367            0 :            pred; pred = pred->pred_next)
    8368              :         {
    8369            0 :           slp_tree pred_node = m_vertices[pred->src].node;
    8370              :           /* All consumers should be a permute with a single outgoing lane.  */
    8371            0 :           if (!SLP_TREE_PERMUTE_P (pred_node)
    8372            0 :               || SLP_TREE_LANES (pred_node) != 1)
    8373              :             {
    8374              :               match = false;
    8375              :               break;
    8376              :             }
    8377            0 :           gcc_assert (SLP_TREE_CHILDREN (pred_node).length () == 1);
    8378              :         }
    8379            0 :       if (!match)
    8380            0 :         continue;
    8381              :       /* Now we can mark the nodes as to use load lanes.  */
    8382            0 :       node->ldst_lanes = true;
    8383            0 :       for (graph_edge *pred = m_slpg->vertices[node->vertex].pred;
    8384            0 :            pred; pred = pred->pred_next)
    8385            0 :         m_vertices[pred->src].node->ldst_lanes = true;
    8386              :       /* The catch is we have to massage the mask.  We have arranged
    8387              :          analyzed uniform masks to be represented by a splat VEC_PERM
    8388              :          which we can now simply elide as we cannot easily re-do SLP
    8389              :          discovery here.  */
    8390            0 :       slp_tree new_mask = SLP_TREE_CHILDREN (mask)[0];
    8391            0 :       SLP_TREE_REF_COUNT (new_mask)++;
    8392            0 :       SLP_TREE_CHILDREN (node)[0] = new_mask;
    8393            0 :       vect_free_slp_tree (mask);
    8394              :     }
    8395       721496 : }
    8396              : 
    8397              : /* Perform legitimizing attempts.  This is intended to improve the
    8398              :    situation when layout 0 is not valid which is a situation the cost
    8399              :    based propagation does not handle well.
    8400              :    Return true if further layout optimization is possible, false if
    8401              :    the layout configuration should be considered final.  */
    8402              : 
    8403              : bool
    8404        13799 : vect_optimize_slp_pass::legitimize ()
    8405              : {
    8406              :   /* Perform a very simple legitimizing attempt by attempting to choose
    8407              :      a single layout for all partitions that will make all permutations
    8408              :      a noop.  That should also be the optimal layout choice in case
    8409              :      layout zero is legitimate.
    8410              :      ???  Disconnected components of the SLP graph could have distinct
    8411              :      single layouts.  */
    8412        13799 :   int single_layout_i = -1;
    8413        13799 :   unsigned deferred_up_to = -1U;
    8414        42650 :   for (unsigned partition_i = 0; partition_i < m_partitions.length ();
    8415              :        ++partition_i)
    8416              :     {
    8417        35412 :       auto &partition = m_partitions[partition_i];
    8418        35412 :       if (single_layout_i == -1)
    8419              :         {
    8420        17489 :           single_layout_i = partition.layout;
    8421        17489 :           deferred_up_to = partition_i;
    8422              :         }
    8423        17923 :       else if (partition.layout == single_layout_i || partition.layout == -1)
    8424              :         ;
    8425              :       else
    8426              :         single_layout_i = 0;
    8427        32188 :       if (single_layout_i == 0)
    8428              :         return true;
    8429              : 
    8430        28933 :       if (single_layout_i != -1
    8431        28933 :           && !is_compatible_layout (partition, single_layout_i))
    8432              :         return true;
    8433              :     }
    8434              : 
    8435         7238 :   if (single_layout_i <= 0)
    8436              :     return true;
    8437              : 
    8438         7827 :   for (unsigned partition_i = 0; partition_i < deferred_up_to; ++partition_i)
    8439          606 :     if (!is_compatible_layout (m_partitions[partition_i],
    8440              :                                single_layout_i))
    8441              :       return true;
    8442              : 
    8443        22192 :   for (unsigned partition_i = 0; partition_i < m_partitions.length ();
    8444              :        ++partition_i)
    8445              :     {
    8446        14971 :       auto &partition = m_partitions[partition_i];
    8447        14971 :       partition.layout = single_layout_i;
    8448              :     }
    8449              : 
    8450              :   return false;
    8451              : }
    8452              : 
    8453              : /* Main entry point for the SLP graph optimization pass.  */
    8454              : 
    8455              : void
    8456       721496 : vect_optimize_slp_pass::run ()
    8457              : {
    8458       721496 :   build_graph ();
    8459       721496 :   create_partitions ();
    8460       721496 :   start_choosing_layouts ();
    8461       721496 :   if (m_perms.length () > 1)
    8462              :     {
    8463        13799 :       if (legitimize ())
    8464              :         {
    8465         6578 :           forward_pass ();
    8466         6578 :           backward_pass ();
    8467              :         }
    8468        13799 :       if (dump_enabled_p ())
    8469          691 :         dump ();
    8470        13799 :       materialize ();
    8471        55764 :       while (!m_perms.is_empty ())
    8472        28166 :         m_perms.pop ().release ();
    8473              :     }
    8474              :   else
    8475       707697 :     remove_redundant_permutations ();
    8476       721496 :   free_graph (m_slpg);
    8477       721496 :   build_graph ();
    8478       721496 :   decide_masked_load_lanes ();
    8479       721496 :   free_graph (m_slpg);
    8480       721496 : }
    8481              : 
    8482              : /* Apply CSE to NODE and its children using BST_MAP.  */
    8483              : 
    8484              : static void
    8485      5691384 : vect_cse_slp_nodes (scalar_stmts_to_slp_tree_map_t *bst_map, slp_tree& node)
    8486              : {
    8487      5691384 :   bool put_p = false;
    8488      5691384 :   if (SLP_TREE_DEF_TYPE (node) == vect_internal_def
    8489              :       /* Besides some VEC_PERM_EXPR, two-operator nodes also
    8490              :          lack scalar stmts and thus CSE doesn't work via bst_map.  Ideally
    8491              :          we'd have sth that works for all internal and external nodes.  */
    8492      5691384 :       && !SLP_TREE_SCALAR_STMTS (node).is_empty ())
    8493              :     {
    8494      4085633 :       slp_tree *leader = bst_map->get (SLP_TREE_SCALAR_STMTS (node));
    8495      4085633 :       if (leader)
    8496              :         {
    8497              :           /* We've visited this node already.  */
    8498       423531 :           if (!*leader || *leader == node)
    8499              :             return;
    8500              : 
    8501         4363 :           if (dump_enabled_p ())
    8502          919 :             dump_printf_loc (MSG_NOTE, vect_location,
    8503              :                              "re-using SLP tree %p for %p\n",
    8504              :                              (void *)*leader, (void *)node);
    8505         4363 :           vect_free_slp_tree (node);
    8506         4363 :           (*leader)->refcnt += 1;
    8507         4363 :           node = *leader;
    8508         4363 :           return;
    8509              :         }
    8510              : 
    8511              :       /* Avoid creating a cycle by populating the map only after recursion.  */
    8512      3662102 :       bst_map->put (SLP_TREE_SCALAR_STMTS (node).copy (), nullptr);
    8513      3662102 :       node->refcnt += 1;
    8514      3662102 :       put_p = true;
    8515              :       /* And recurse.  */
    8516              :     }
    8517              : 
    8518     15736908 :   for (slp_tree &child : SLP_TREE_CHILDREN (node))
    8519      4607217 :     if (child)
    8520      4144766 :       vect_cse_slp_nodes (bst_map, child);
    8521              : 
    8522              :   /* Now record the node for CSE in other siblings.  */
    8523      5267853 :   if (put_p)
    8524      3662102 :     *bst_map->get (SLP_TREE_SCALAR_STMTS (node)) = node;
    8525              : }
    8526              : 
    8527              : /* Associate stmts with possible starts of a subset of lanes of NODE
    8528              :    in PART_STARTS.  */
    8529              : 
    8530              : static void
    8531      2159509 : vect_cse_gather_part_starts (hash_set<slp_tree> &visited,
    8532              :                              vec<vec<slp_tree>> part_starts, slp_tree node)
    8533              : {
    8534              :   /* CSEing external nodes complicates scheduling since we materialize
    8535              :      those at the latest position, so avoid that.  */
    8536      2159509 :   if (SLP_TREE_DEF_TYPE (node) != vect_internal_def
    8537      2159509 :       || visited.add (node))
    8538              :     return;
    8539              : 
    8540              :   /* Besides some VEC_PERM_EXPR, two-operator nodes also lack scalar stmts
    8541              :      and thus CSE doesn't work.  For now gather two-lane aligned starts
    8542              :      of nodes with a multiple of two number of lanes.  */
    8543      1160446 :   if (!SLP_TREE_SCALAR_STMTS (node).is_empty ()
    8544      1153038 :       && SLP_TREE_LANES (node) > 2
    8545       151575 :       && (SLP_TREE_LANES (node) & 1) == 0)
    8546              :     {
    8547       151575 :       auto_vec<unsigned, 8> uids;
    8548       629509 :       for (unsigned i = 0; i < SLP_TREE_LANES (node); i += 2)
    8549              :         {
    8550       477934 :           stmt_vec_info s = SLP_TREE_SCALAR_STMTS (node)[i];
    8551       477934 :           if (!s)
    8552            0 :             continue;
    8553       477934 :           unsigned uid = gimple_uid (s->stmt);
    8554       477934 :           if (!uids.contains (uid))
    8555              :             {
    8556       473920 :               uids.safe_push (uid);
    8557       473920 :               part_starts[uid].safe_push (node);
    8558              :             }
    8559              :         }
    8560       151575 :     }
    8561              : 
    8562      4516328 :   for (slp_tree &child : SLP_TREE_CHILDREN (node))
    8563      1325088 :     if (child)
    8564      1325088 :       vect_cse_gather_part_starts (visited, part_starts, child);
    8565              : }
    8566              : 
    8567              : /* Apply CSE to NODE and its children using lowparts of nodes in BST_MAP.  */
    8568              : 
    8569              : static void
    8570      2155842 : vect_cse_slp_node_parts (hash_set<slp_tree> &visited,
    8571              :                          const vec<vec<slp_tree>> part_starts,
    8572              :                          vec<slp_tree> &drops, slp_tree node)
    8573              : {
    8574      2155842 :   if (SLP_TREE_DEF_TYPE (node) != vect_internal_def
    8575      2155842 :       || visited.add (node))
    8576              :     return;
    8577              : 
    8578              :   /* Besides some VEC_PERM_EXPR, two-operator nodes also
    8579              :      lack scalar stmts and thus CSE doesn't work.  */
    8580      1158762 :   unsigned HOST_WIDE_INT c;
    8581      1158762 :   if (!SLP_TREE_SCALAR_STMTS (node).is_empty ()
    8582      1151358 :       && SLP_TREE_SCALAR_STMTS (node)[0]
    8583              :       /* Avoid touching loads which need care with load permutations
    8584              :          and specialities like load-lane representations.  */
    8585      1151358 :       && (SLP_TREE_PERMUTE_P (node)
    8586      1143807 :           || !STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (node))))
    8587        37495 :     for (slp_tree cand
    8588       433895 :          : part_starts[gimple_uid (SLP_TREE_SCALAR_STMTS (node)[0]->stmt)])
    8589              :       /* ???  There is a possible ordering/optimality problem in that
    8590              :          the CSE then can keep a wider feeding live even though it itself
    8591              :          becomes dead by means of CSE.  Which might be solvable by doing
    8592              :          the CSE in a wide-to-narrow order.  */
    8593        37960 :       if (SLP_TREE_LANES (cand) > SLP_TREE_LANES (node)
    8594              :           /* We can do high/lo extracts and full vector copies.  */
    8595              :           && constant_multiple_p
    8596         4617 :                (TYPE_VECTOR_SUBPARTS (SLP_TREE_VECTYPE (cand)),
    8597        38452 :                 TYPE_VECTOR_SUBPARTS (SLP_TREE_VECTYPE (node)), &c)
    8598        42577 :           && c <= 2)
    8599              :         {
    8600         4125 :           unsigned HOST_WIDE_INT s;
    8601         4125 :           bool const_p
    8602         4125 :             = TYPE_VECTOR_SUBPARTS (SLP_TREE_VECTYPE (node)).is_constant (&s);
    8603         4125 :           unsigned i;
    8604        14817 :           for (i = 0; i <= SLP_TREE_LANES (cand) - SLP_TREE_LANES (node);)
    8605              :             {
    8606              :               unsigned j;
    8607        15780 :               for (j = 0; j < SLP_TREE_LANES (node); ++j)
    8608        15315 :                 if (!SLP_TREE_SCALAR_STMTS (node)[j]
    8609        15315 :                     || (SLP_TREE_SCALAR_STMTS (cand)[i+j]
    8610        15315 :                         != SLP_TREE_SCALAR_STMTS (node)[j]))
    8611              :                   break;
    8612        11157 :               if (j == SLP_TREE_LANES (node))
    8613              :                 break;
    8614        10692 :               if (!const_p)
    8615              :                 {
    8616              :                   i = SLP_TREE_LANES (cand);
    8617              :                   break;
    8618              :                 }
    8619              :               /* We can extract only aligned on node vector type boundary.  */
    8620        10692 :               i += s;
    8621              :             }
    8622         4125 :           if (i > SLP_TREE_LANES (cand) - SLP_TREE_LANES (node))
    8623         3660 :             continue;
    8624              :           /* Found node within cand at i.  Put a permute in place
    8625              :              of it, selecting the subset from cand.  */
    8626          465 :           if (dump_enabled_p ())
    8627           41 :             dump_printf (MSG_NOTE, "CSEd node %p as %spart of node %p\n",
    8628              :                          (void *)node, i == 0 ? "low" : "high", (void *)cand);
    8629         2290 :           for (slp_tree child : SLP_TREE_CHILDREN (node))
    8630              :             /* Delay SLP tree release since we might still reference a node
    8631              :                from the part_starts map.  */
    8632          895 :             drops.safe_push (child);
    8633          465 :           SLP_TREE_CHILDREN (node).truncate (1);
    8634          465 :           SLP_TREE_REF_COUNT (cand)++;
    8635          465 :           SLP_TREE_CHILDREN (node)[0] = cand;
    8636          465 :           SLP_TREE_CODE (node) = VEC_PERM_EXPR;
    8637          465 :           SLP_TREE_REPRESENTATIVE (node) = NULL;
    8638          465 :           SLP_TREE_LANE_PERMUTATION (node).create (SLP_TREE_LANES (node));
    8639         1992 :           for (unsigned j = i; j < i + SLP_TREE_LANES (node); ++j)
    8640         1062 :             SLP_TREE_LANE_PERMUTATION (node).quick_push (std::make_pair (0, j));
    8641      2155842 :           return;
    8642              :         }
    8643              : 
    8644      4506780 :   for (slp_tree &child : SLP_TREE_CHILDREN (node))
    8645      1321421 :     if (child)
    8646      1321421 :       vect_cse_slp_node_parts (visited, part_starts, drops, child);
    8647              : }
    8648              : 
    8649              : /* Optimize the SLP graph of VINFO.  */
    8650              : 
    8651              : void
    8652      1117270 : vect_optimize_slp (vec_info *vinfo)
    8653              : {
    8654      1117270 :   if (vinfo->slp_instances.is_empty ())
    8655       834156 :     return;
    8656       721496 :   vect_optimize_slp_pass (vinfo).run ();
    8657              : 
    8658              :   /* Apply CSE again to nodes after permute optimization.  */
    8659       721496 :   scalar_stmts_to_slp_tree_map_t *bst_map
    8660       721496 :     = new scalar_stmts_to_slp_tree_map_t ();
    8661              : 
    8662      3711106 :   for (auto inst : vinfo->slp_instances)
    8663      1546618 :     vect_cse_slp_nodes (bst_map, SLP_INSTANCE_TREE (inst));
    8664              : 
    8665       721496 :   release_scalar_stmts_to_slp_tree_map (bst_map);
    8666              : 
    8667       721496 :   if (!is_a <bb_vec_info> (vinfo))
    8668              :     return;
    8669              : 
    8670              :   /* Attempt to merge SLP sub-graphs that intersect in low or highparts of
    8671              :      each other.  Build the reverse mapping from stmt to SLP node for
    8672              :      lanes starting at the low or high part.
    8673              :      ???  In the future we can extend this to do a two-step permute
    8674              :      and extract or extract and permute to put the high/low part in
    8675              :      place on the original vector or permute the hogh/low part to
    8676              :      match up the target lane order.  */
    8677       283114 :   hash_set<slp_tree> visited;
    8678       283114 :   vec<vec<slp_tree>> start_for_part;
    8679       566228 :   start_for_part.create (vinfo->stmt_vec_infos.length () + 1);
    8680       566228 :   start_for_part.quick_grow_cleared (vinfo->stmt_vec_infos.length () + 1);
    8681      1683763 :   for (auto inst : vinfo->slp_instances)
    8682       834421 :     vect_cse_gather_part_starts (visited,
    8683              :                                  start_for_part, SLP_INSTANCE_TREE (inst));
    8684              : 
    8685              :   /* Now replace low/highpart copies with extracting permutes.  */
    8686       283114 :   auto_vec<slp_tree> drops;
    8687       283114 :   visited.empty ();
    8688      1683763 :   for (auto inst : vinfo->slp_instances)
    8689       834421 :     vect_cse_slp_node_parts (visited, start_for_part, drops,
    8690              :                              SLP_INSTANCE_TREE (inst));
    8691              : 
    8692              :   /* Now perform delayed releases of nodes.  */
    8693       284499 :   for (slp_tree node : drops)
    8694          895 :     vect_free_slp_tree (node);
    8695              : 
    8696     24404581 :   for (auto v : start_for_part)
    8697     23555239 :     v.release ();
    8698       283114 :   start_for_part.release ();
    8699       283114 : }
    8700              : 
    8701              : /* Gather loads reachable from the individual SLP graph entries.  */
    8702              : 
    8703              : void
    8704      1117270 : vect_gather_slp_loads (vec_info *vinfo)
    8705              : {
    8706      1117270 :   unsigned i;
    8707      1117270 :   slp_instance instance;
    8708      2663888 :   FOR_EACH_VEC_ELT (vinfo->slp_instances, i, instance)
    8709              :     {
    8710      1546618 :       hash_set<slp_tree> visited;
    8711      1546618 :       vect_gather_slp_loads (SLP_INSTANCE_LOADS (instance),
    8712              :                              SLP_INSTANCE_TREE (instance), visited);
    8713      1546618 :     }
    8714      1117270 : }
    8715              : 
    8716              : /* For NODE update VF based on the number of lanes and the vector types
    8717              :    used.  */
    8718              : 
    8719              : static void
    8720      4525353 : vect_update_slp_vf_for_node (slp_tree node, poly_uint64 &vf,
    8721              :                              hash_set<slp_tree> &visited)
    8722              : {
    8723      4525353 :   if (!node || SLP_TREE_DEF_TYPE (node) != vect_internal_def)
    8724      1640294 :     return;
    8725      3262619 :   if (visited.add (node))
    8726              :     return;
    8727              : 
    8728     10978813 :   for (slp_tree child : SLP_TREE_CHILDREN (node))
    8729      3718226 :     vect_update_slp_vf_for_node (child, vf, visited);
    8730              : 
    8731              :   /* We do not visit SLP nodes for constants or externals - those neither
    8732              :      have a vector type set yet (vectorizable_* does this).
    8733              :      Note that when we stop using fixed size vectors externs and constants
    8734              :      shouldn't influence the (minimum) vectorization factor, instead
    8735              :      vectorizable_* should honor the vectorization factor when trying to
    8736              :      assign vector types to constants and externals and cause iteration
    8737              :      to a higher vectorization factor when required.  */
    8738      2885079 :   tree vectype = SLP_TREE_VECTYPE (node);
    8739      2885079 :   if (!vectype)
    8740              :     /* OMP SIMD calls w/o LHS have no SLP_TREE_VECTYPE set.  */
    8741              :     return;
    8742      2885059 :   poly_uint64 node_vf
    8743      2885059 :     = calculate_unrolling_factor (TYPE_VECTOR_SUBPARTS (vectype),
    8744              :                                   SLP_TREE_LANES (node));
    8745      2885059 :   vf = force_common_multiple (vf, node_vf);
    8746              : 
    8747              :   /* For permute nodes that are fed from externs or constants we have to
    8748              :      consider their number of lanes as well.  Likewise for store-lanes.  */
    8749      2885059 :   if (SLP_TREE_PERMUTE_P (node) || node->ldst_lanes)
    8750       717405 :     for (slp_tree child : SLP_TREE_CHILDREN (node))
    8751       193362 :       if (SLP_TREE_DEF_TYPE (child) != vect_internal_def)
    8752              :         {
    8753         3680 :           poly_uint64 child_vf
    8754         3680 :             = calculate_unrolling_factor (TYPE_VECTOR_SUBPARTS (vectype),
    8755              :                                           SLP_TREE_LANES (child));
    8756         3680 :           vf = force_common_multiple (vf, child_vf);
    8757              :         }
    8758              : }
    8759              : 
    8760              : /* For each possible SLP instance decide whether to SLP it and calculate overall
    8761              :    unrolling factor needed to SLP the loop.  Return TRUE if decided to SLP at
    8762              :    least one instance.  */
    8763              : 
    8764              : bool
    8765       505784 : vect_make_slp_decision (loop_vec_info loop_vinfo)
    8766              : {
    8767       505784 :   unsigned int i;
    8768       505784 :   poly_uint64 unrolling_factor = 1;
    8769       505784 :   const vec<slp_instance> &slp_instances
    8770              :     = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
    8771       505784 :   slp_instance instance;
    8772       505784 :   int decided_to_slp = 0;
    8773              : 
    8774       505784 :   DUMP_VECT_SCOPE ("vect_make_slp_decision");
    8775              : 
    8776       505784 :   hash_set<slp_tree> visited;
    8777      1818695 :   FOR_EACH_VEC_ELT (slp_instances, i, instance)
    8778              :     {
    8779       807127 :       slp_tree root = SLP_INSTANCE_TREE (instance);
    8780              : 
    8781              :       /* All unroll factors have the form:
    8782              : 
    8783              :            GET_MODE_SIZE (vinfo->vector_mode) * X
    8784              : 
    8785              :          for some rational X, so they must have a common multiple.  */
    8786       807127 :       vect_update_slp_vf_for_node (root, unrolling_factor, visited);
    8787              : 
    8788              :       /* If all instances ended up with vector(1) T roots make sure to
    8789              :          not vectorize.  RVV for example relies on loop vectorization
    8790              :          when some instances are essentially kept scalar.  See PR121048.  */
    8791       807127 :       if (SLP_TREE_VECTYPE (root)
    8792       807127 :           && known_gt (TYPE_VECTOR_SUBPARTS (SLP_TREE_VECTYPE (root)), 1U))
    8793       654644 :         decided_to_slp++;
    8794              :     }
    8795              : 
    8796       505784 :   LOOP_VINFO_VECT_FACTOR (loop_vinfo) = unrolling_factor;
    8797              : 
    8798       505784 :   if (decided_to_slp && dump_enabled_p ())
    8799              :     {
    8800        20403 :       dump_printf_loc (MSG_NOTE, vect_location,
    8801              :                        "Decided to SLP %d instances. Unrolling factor ",
    8802              :                        decided_to_slp);
    8803        20403 :       dump_dec (MSG_NOTE, unrolling_factor);
    8804        20403 :       dump_printf (MSG_NOTE, "\n");
    8805              :     }
    8806              : 
    8807       505784 :   return (decided_to_slp > 0);
    8808       505784 : }
    8809              : 
    8810              : /* Initialize a bb_vec_info struct for the statements in BBS basic blocks.  */
    8811              : 
    8812      2349498 : _bb_vec_info::_bb_vec_info (vec<basic_block> _bbs, vec_info_shared *shared)
    8813              :   : vec_info (vec_info::bb, shared),
    8814      2349498 :     roots (vNULL)
    8815              : {
    8816              :   /* The region we are operating on.  bbs[0] is the entry, excluding
    8817              :      its PHI nodes.  In the future we might want to track an explicit
    8818              :      entry edge to cover bbs[0] PHI nodes and have a region entry
    8819              :      insert location.  */
    8820      2349498 :   bbs = _bbs.address ();
    8821      2349498 :   nbbs = _bbs.length ();
    8822              : 
    8823     18748341 :   for (unsigned i = 0; i < nbbs; ++i)
    8824              :     {
    8825     16398843 :       if (i != 0)
    8826     21304247 :         for (gphi_iterator si = gsi_start_phis (bbs[i]); !gsi_end_p (si);
    8827      7254902 :              gsi_next (&si))
    8828              :           {
    8829      7254902 :             gphi *phi = si.phi ();
    8830      7254902 :             gimple_set_uid (phi, 0);
    8831      7254902 :             add_stmt (phi);
    8832              :           }
    8833     32797686 :       for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]);
    8834    152524186 :            !gsi_end_p (gsi); gsi_next (&gsi))
    8835              :         {
    8836    136125343 :           gimple *stmt = gsi_stmt (gsi);
    8837    136125343 :           gimple_set_uid (stmt, 0);
    8838    136125343 :           if (is_gimple_debug (stmt) || is_a <glabel *> (stmt))
    8839     88685003 :             continue;
    8840     47440340 :           add_stmt (stmt);
    8841              :         }
    8842              :     }
    8843      2349498 : }
    8844              : 
    8845              : 
    8846              : /* Free BB_VINFO struct, as well as all the stmt_vec_info structs of all the
    8847              :    stmts in the basic block.  */
    8848              : 
    8849      2349498 : _bb_vec_info::~_bb_vec_info ()
    8850              : {
    8851              :   /* Reset region marker.  */
    8852     18748341 :   for (unsigned i = 0; i < nbbs; ++i)
    8853              :     {
    8854     16398843 :       if (i != 0)
    8855     21318364 :         for (gphi_iterator si = gsi_start_phis (bbs[i]); !gsi_end_p (si);
    8856      7269019 :              gsi_next (&si))
    8857              :           {
    8858      7269019 :             gphi *phi = si.phi ();
    8859      7269019 :             gimple_set_uid (phi, -1);
    8860              :           }
    8861     32797686 :       for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]);
    8862    152396513 :            !gsi_end_p (gsi); gsi_next (&gsi))
    8863              :         {
    8864    135997670 :           gimple *stmt = gsi_stmt (gsi);
    8865    135997670 :           gimple_set_uid (stmt, -1);
    8866              :         }
    8867              :     }
    8868              : 
    8869      3722324 :   for (unsigned i = 0; i < roots.length (); ++i)
    8870              :     {
    8871      1372826 :       roots[i].stmts.release ();
    8872      1372826 :       roots[i].roots.release ();
    8873      1372826 :       roots[i].remain.release ();
    8874              :     }
    8875      2349498 :   roots.release ();
    8876      2349498 : }
    8877              : 
    8878              : /* Subroutine of vect_slp_analyze_node_operations.  Handle the root of NODE,
    8879              :    given then that child nodes have already been processed, and that
    8880              :    their def types currently match their SLP node's def type.  */
    8881              : 
    8882              : static bool
    8883      2743751 : vect_slp_analyze_node_operations_1 (vec_info *vinfo, slp_tree node,
    8884              :                                     slp_instance node_instance,
    8885              :                                     stmt_vector_for_cost *cost_vec)
    8886              : {
    8887              :   /* Handle purely internal nodes.  */
    8888      2743751 :   if (SLP_TREE_PERMUTE_P (node))
    8889              :     {
    8890        82924 :       gcc_checking_assert (!SLP_TREE_REPRESENTATIVE (node));
    8891        82924 :       if (!vectorizable_slp_permutation (vinfo, NULL, node, cost_vec))
    8892              :         return false;
    8893              : 
    8894              :       stmt_vec_info slp_stmt_info;
    8895              :       unsigned int i;
    8896       204201 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, slp_stmt_info)
    8897              :         {
    8898       122869 :           if (slp_stmt_info
    8899       117167 :               && STMT_VINFO_LIVE_P (slp_stmt_info)
    8900       122869 :               && !vectorizable_live_operation (vinfo, slp_stmt_info, node,
    8901              :                                                node_instance, i,
    8902              :                                                false, cost_vec))
    8903              :             return false;
    8904              :         }
    8905        81332 :       SLP_TREE_TYPE (node) = permute_info_type;
    8906        81332 :       return true;
    8907              :     }
    8908              : 
    8909      2660827 :   return vect_analyze_stmt (vinfo, node, node_instance, cost_vec);
    8910              : }
    8911              : 
    8912              : static int
    8913       912283 : sort_ints (const void *a_, const void *b_)
    8914              : {
    8915       912283 :   int a = *(const int *)a_;
    8916       912283 :   int b = *(const int *)b_;
    8917       912283 :   return a - b;
    8918              : }
    8919              : 
    8920              : /* Verify if we can externalize a set of internal defs.  */
    8921              : 
    8922              : static bool
    8923       411208 : vect_slp_can_convert_to_external (const vec<stmt_vec_info> &stmts)
    8924              : {
    8925              :   /* Constant generation uses get_later_stmt which can only handle
    8926              :      defs from the same BB or a set of defs that can be ordered
    8927              :      with a dominance query.  */
    8928       411208 :   basic_block bb = NULL;
    8929       411208 :   bool all_same = true;
    8930       411208 :   auto_vec<int> bbs;
    8931       822416 :   bbs.reserve_exact (stmts.length ());
    8932      2168634 :   for (stmt_vec_info stmt : stmts)
    8933              :     {
    8934       935010 :       if (!stmt)
    8935              :         return false;
    8936       935010 :       else if (!bb)
    8937       411208 :         bb = gimple_bb (stmt->stmt);
    8938       523802 :       else if (gimple_bb (stmt->stmt) != bb)
    8939       157117 :         all_same = false;
    8940       935010 :       bbs.quick_push (gimple_bb (stmt->stmt)->index);
    8941              :     }
    8942       411208 :   if (all_same)
    8943              :     return true;
    8944              : 
    8945              :   /* Produce a vector of unique BB indexes for the defs.  */
    8946       140194 :   bbs.qsort (sort_ints);
    8947       140194 :   unsigned i, j;
    8948       303536 :   for (i = 1, j = 1; i < bbs.length (); ++i)
    8949       163342 :     if (bbs[i] != bbs[j-1])
    8950       144097 :       bbs[j++] = bbs[i];
    8951       140194 :   gcc_assert (j >= 2);
    8952       140194 :   bbs.truncate (j);
    8953              : 
    8954       280388 :   if (bbs.length () == 2)
    8955       138502 :     return (dominated_by_p (CDI_DOMINATORS,
    8956       138502 :                             BASIC_BLOCK_FOR_FN (cfun, bbs[0]),
    8957       138502 :                             BASIC_BLOCK_FOR_FN (cfun, bbs[1]))
    8958       270580 :             || dominated_by_p (CDI_DOMINATORS,
    8959       132078 :                                BASIC_BLOCK_FOR_FN (cfun, bbs[1]),
    8960       132078 :                                BASIC_BLOCK_FOR_FN (cfun, bbs[0])));
    8961              : 
    8962              :   /* ???  For more than two BBs we can sort the vector and verify the
    8963              :      result is a total order.  But we can't use vec::qsort with a
    8964              :      compare function using a dominance query since there's no way to
    8965              :      signal failure and any fallback for an unordered pair would
    8966              :      fail qsort_chk later.
    8967              :      For now simply hope that ordering after BB index provides the
    8968              :      best candidate total order.  If required we can implement our
    8969              :      own mergesort or export an entry without checking.  */
    8970       418437 :   for (unsigned i = 1; i < bbs.length (); ++i)
    8971         5571 :     if (!dominated_by_p (CDI_DOMINATORS,
    8972         5571 :                          BASIC_BLOCK_FOR_FN (cfun, bbs[i]),
    8973         5571 :                          BASIC_BLOCK_FOR_FN (cfun, bbs[i-1])))
    8974              :       return false;
    8975              : 
    8976              :   return true;
    8977       411208 : }
    8978              : 
    8979              : /* Try to build NODE from scalars, returning true on success.
    8980              :    NODE_INSTANCE is the SLP instance that contains NODE.  */
    8981              : 
    8982              : static bool
    8983       645966 : vect_slp_convert_to_external (vec_info *vinfo, slp_tree node,
    8984              :                               slp_instance node_instance)
    8985              : {
    8986       645966 :   stmt_vec_info stmt_info;
    8987       645966 :   unsigned int i;
    8988              : 
    8989       645966 :   if (!is_a <bb_vec_info> (vinfo)
    8990        90174 :       || node == SLP_INSTANCE_TREE (node_instance)
    8991        30243 :       || !SLP_TREE_SCALAR_STMTS (node).exists ()
    8992        30202 :       || vect_contains_pattern_stmt_p (SLP_TREE_SCALAR_STMTS (node))
    8993              :       /* Force the mask use to be built from scalars instead.  */
    8994        22731 :       || VECTOR_BOOLEAN_TYPE_P (SLP_TREE_VECTYPE (node))
    8995       668438 :       || !vect_slp_can_convert_to_external (SLP_TREE_SCALAR_STMTS (node)))
    8996              :     return false;
    8997              : 
    8998        22472 :   if (dump_enabled_p ())
    8999           84 :     dump_printf_loc (MSG_NOTE, vect_location,
    9000              :                      "Building vector operands of %p from scalars instead\n",
    9001              :                      (void *) node);
    9002              : 
    9003              :   /* Don't remove and free the child nodes here, since they could be
    9004              :      referenced by other structures.  The analysis and scheduling phases
    9005              :      (need to) ignore child nodes of anything that isn't vect_internal_def.  */
    9006        22472 :   unsigned int group_size = SLP_TREE_LANES (node);
    9007        22472 :   SLP_TREE_DEF_TYPE (node) = vect_external_def;
    9008              :   /* Invariants get their vector type from the uses.  */
    9009        22472 :   SLP_TREE_VECTYPE (node) = NULL_TREE;
    9010        22472 :   SLP_TREE_SCALAR_OPS (node).safe_grow (group_size, true);
    9011        22472 :   SLP_TREE_LOAD_PERMUTATION (node).release ();
    9012       101984 :   FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
    9013              :     {
    9014        57040 :       tree lhs = gimple_get_lhs (vect_orig_stmt (stmt_info)->stmt);
    9015        57040 :       SLP_TREE_SCALAR_OPS (node)[i] = lhs;
    9016              :     }
    9017              :   return true;
    9018              : }
    9019              : 
    9020              : /* Return true if all elements of the slice are the same.  */
    9021              : bool
    9022       451629 : vect_scalar_ops_slice::all_same_p () const
    9023              : {
    9024       503553 :   for (unsigned int i = 1; i < length; ++i)
    9025       416167 :     if (!operand_equal_p (op (0), op (i)))
    9026              :       return false;
    9027              :   return true;
    9028              : }
    9029              : 
    9030              : hashval_t
    9031       426730 : vect_scalar_ops_slice_hash::hash (const value_type &s)
    9032              : {
    9033       426730 :   hashval_t hash = 0;
    9034      1631983 :   for (unsigned i = 0; i < s.length; ++i)
    9035      1205253 :     hash = iterative_hash_expr (s.op (i), hash);
    9036       426730 :   return hash;
    9037              : }
    9038              : 
    9039              : bool
    9040       232721 : vect_scalar_ops_slice_hash::equal (const value_type &s1,
    9041              :                                    const compare_type &s2)
    9042              : {
    9043       232721 :   if (s1.length != s2.length)
    9044              :     return false;
    9045       400790 :   for (unsigned i = 0; i < s1.length; ++i)
    9046       349798 :     if (!operand_equal_p (s1.op (i), s2.op (i)))
    9047              :       return false;
    9048              :   return true;
    9049              : }
    9050              : 
    9051              : /* Like vect_get_num_copies but N copies of the vector might have
    9052              :    excess elements in the last vector.  Stores the number of excess
    9053              :    elements in the last vector in *EXCESS_ELTS.
    9054              :    Returns false if *NVECTORS or *EXCESS_ELTS cannot be computed.  */
    9055              : 
    9056              : bool
    9057      1605472 : vect_get_num_copies_for_invariant (vec_info *vinfo, slp_tree node,
    9058              :                                    unsigned *nvectors,
    9059              :                                    unsigned *excess_elts)
    9060              : {
    9061      1605472 :   poly_uint64 vf;
    9062              : 
    9063      1605472 :   if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
    9064       382351 :     vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
    9065              :   else
    9066      1223121 :     vf = 1;
    9067      1605472 :   vf *= SLP_TREE_LANES (node);
    9068              : 
    9069      1605472 :   tree vectype = SLP_TREE_VECTYPE (node);
    9070      1605472 :   uint64_t rem;
    9071      1605472 :   if (can_div_away_from_zero_p (vf, TYPE_VECTOR_SUBPARTS (vectype),
    9072              :                                 nvectors)
    9073      1605472 :       && (TYPE_VECTOR_SUBPARTS (vectype) * *nvectors - vf) .is_constant (&rem))
    9074              :     {
    9075      1605472 :       *excess_elts = rem;
    9076      1605472 :       return true;
    9077              :     }
    9078              :   return false;
    9079              : }
    9080              : 
    9081              : /* Compute the prologue cost for invariant or constant operands represented
    9082              :    by NODE.  */
    9083              : 
    9084              : static void
    9085      1100533 : vect_prologue_cost_for_slp (slp_tree node, unsigned nvectors,
    9086              :                             stmt_vector_for_cost *cost_vec)
    9087              : {
    9088              :   /* There's a special case of an existing vector, that costs nothing.  */
    9089      1100533 :   if (SLP_TREE_SCALAR_OPS (node).length () == 0
    9090      1100533 :       && !SLP_TREE_VEC_DEFS (node).is_empty ())
    9091         2255 :     return;
    9092              :   /* Without looking at the actual initializer a vector of
    9093              :      constants can be implemented as load from the constant pool.
    9094              :      When all elements are the same we can use a splat.  */
    9095      1098278 :   tree vectype = SLP_TREE_VECTYPE (node);
    9096      1098278 :   unsigned group_size = SLP_TREE_LANES (node);
    9097      1098278 :   unsigned HOST_WIDE_INT const_nunits;
    9098      1098278 :   unsigned nelt_limit;
    9099      1098278 :   auto ops = &SLP_TREE_SCALAR_OPS (node);
    9100      1098278 :   auto_vec<unsigned int> starts (nvectors);
    9101      1098278 :   if (TYPE_VECTOR_SUBPARTS (vectype).is_constant (&const_nunits)
    9102      1098278 :       && ! multiple_p (const_nunits, group_size))
    9103              :     {
    9104        67810 :       nelt_limit = const_nunits;
    9105        67810 :       hash_set<vect_scalar_ops_slice_hash> vector_ops;
    9106       347875 :       for (unsigned int i = 0; i < nvectors; ++i)
    9107       212255 :         if (!vector_ops.add ({ ops, i * nelt_limit, nelt_limit }))
    9108       161263 :           starts.quick_push (i * nelt_limit);
    9109        67810 :     }
    9110              :   else
    9111              :     {
    9112              :       /* If either the vector has variable length or the vectors
    9113              :          are composed of repeated whole groups we only need to
    9114              :          cost construction once.  All vectors will be the same.  */
    9115      1030468 :       nelt_limit = group_size;
    9116      1030468 :       starts.quick_push (0);
    9117              :     }
    9118              :   /* ???  We're just tracking whether vectors in a single node are the same.
    9119              :      Ideally we'd do something more global.  */
    9120      4486565 :   for (unsigned int start : starts)
    9121              :     {
    9122      1191731 :       vect_cost_for_stmt kind;
    9123      1191731 :       if (SLP_TREE_DEF_TYPE (node) == vect_constant_def)
    9124              :         kind = vector_load;
    9125       451629 :       else if (vect_scalar_ops_slice { ops, start, nelt_limit }.all_same_p ())
    9126              :         kind = scalar_to_vec;
    9127              :       else
    9128       364243 :         kind = vec_construct;
    9129      1191731 :       record_stmt_cost (cost_vec, 1, kind, nullptr, node,
    9130              :                         vectype, 0, vect_prologue);
    9131              :     }
    9132      1098278 : }
    9133              : 
    9134              : /* Analyze statements contained in SLP tree NODE after recursively analyzing
    9135              :    the subtree.  NODE_INSTANCE contains NODE and VINFO contains INSTANCE.
    9136              : 
    9137              :    Return true if the operations are supported.  */
    9138              : 
    9139              : static bool
    9140      5094170 : vect_slp_analyze_node_operations (vec_info *vinfo, slp_tree node,
    9141              :                                   slp_instance node_instance,
    9142              :                                   hash_set<slp_tree> &visited_set,
    9143              :                                   vec<slp_tree> &visited_vec,
    9144              :                                   stmt_vector_for_cost *cost_vec)
    9145              : {
    9146      5094170 :   int i, j;
    9147      5094170 :   slp_tree child;
    9148              : 
    9149              :   /* Costing and analysis of invariants is delayed.  */
    9150      5094170 :   if (!node
    9151      4695690 :       || SLP_TREE_DEF_TYPE (node) == vect_constant_def
    9152      3898139 :       || SLP_TREE_DEF_TYPE (node) == vect_external_def)
    9153              :     return true;
    9154              : 
    9155      3411732 :   if (SLP_TREE_DEF_TYPE (node) == vect_uninitialized_def)
    9156              :     {
    9157            5 :       if (dump_enabled_p ())
    9158            0 :         dump_printf_loc (MSG_NOTE, vect_location,
    9159              :                          "Failed cyclic SLP reference in %p\n", (void *) node);
    9160              :       return false;
    9161              :     }
    9162      3411727 :   gcc_assert (SLP_TREE_DEF_TYPE (node) == vect_internal_def);
    9163              : 
    9164              :   /* If we already analyzed the exact same set of scalar stmts we're done.
    9165              :      We share the generated vector stmts for those.  */
    9166      3411727 :   if (visited_set.add (node))
    9167              :     return true;
    9168      3108717 :   visited_vec.safe_push (node);
    9169              : 
    9170      3108717 :   bool res = true;
    9171      3108717 :   unsigned visited_rec_start = visited_vec.length ();
    9172      3108717 :   unsigned cost_vec_rec_start = cost_vec->length ();
    9173      3108717 :   bool seen_non_constant_child = false;
    9174      8999530 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    9175              :     {
    9176      3715754 :       res = vect_slp_analyze_node_operations (vinfo, child, node_instance,
    9177              :                                               visited_set, visited_vec,
    9178              :                                               cost_vec);
    9179      3715754 :       if (!res)
    9180              :         break;
    9181      3351006 :       if (child && SLP_TREE_DEF_TYPE (child) != vect_constant_def)
    9182      3351006 :         seen_non_constant_child = true;
    9183              :     }
    9184              :   /* We're having difficulties scheduling nodes with just constant
    9185              :      operands and no scalar stmts since we then cannot compute a stmt
    9186              :      insertion place.  */
    9187      3108717 :   if (res
    9188      3108717 :       && !seen_non_constant_child
    9189      3108717 :       && SLP_TREE_SCALAR_STMTS (node).is_empty ())
    9190              :     {
    9191          218 :       if (dump_enabled_p ())
    9192            6 :         dump_printf_loc (MSG_NOTE, vect_location,
    9193              :                          "Cannot vectorize all-constant op node %p\n",
    9194              :                          (void *) node);
    9195              :       res = false;
    9196              :     }
    9197              : 
    9198      3108505 :   if (res)
    9199      2743751 :     res = vect_slp_analyze_node_operations_1 (vinfo, node, node_instance,
    9200              :                                               cost_vec);
    9201              :   /* If analysis failed we have to pop all recursive visited nodes
    9202              :      plus ourselves.  */
    9203      3108717 :   if (!res)
    9204              :     {
    9205      3184622 :       while (visited_vec.length () >= visited_rec_start)
    9206       946345 :         visited_set.remove (visited_vec.pop ());
    9207       645966 :       cost_vec->truncate (cost_vec_rec_start);
    9208              :     }
    9209              : 
    9210              :   /* When the node can be vectorized cost invariant nodes it references.
    9211              :      This is not done in DFS order to allow the referring node
    9212              :      vectorizable_* calls to nail down the invariant nodes vector type
    9213              :      and possibly unshare it if it needs a different vector type than
    9214              :      other referrers.  */
    9215      3108717 :   if (res)
    9216      9468339 :     FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
    9217      2994784 :       if (child
    9218      2670223 :           && (SLP_TREE_DEF_TYPE (child) == vect_constant_def
    9219      2670223 :               || SLP_TREE_DEF_TYPE (child) == vect_external_def)
    9220              :           /* Perform usual caching, note code-generation still
    9221              :              code-gens these nodes multiple times but we expect
    9222              :              to CSE them later.  */
    9223      4137356 :           && !visited_set.add (child))
    9224              :         {
    9225      1139533 :           visited_vec.safe_push (child);
    9226              :           /* ???  After auditing more code paths make a "default"
    9227              :              and push the vector type from NODE to all children
    9228              :              if it is not already set.  */
    9229              :           /* Compute the number of vectors to be generated.  */
    9230      1139533 :           tree vector_type = SLP_TREE_VECTYPE (child);
    9231      1139533 :           if (!vector_type)
    9232              :             {
    9233              :               /* Masked loads can have an undefined (default SSA definition)
    9234              :                  else operand.  We do not need to cost it.  */
    9235        39000 :               vec<tree> ops = SLP_TREE_SCALAR_OPS (child);
    9236        40431 :               if (SLP_TREE_TYPE (node) == load_vec_info_type
    9237        40431 :                   && ((ops.length ()
    9238         1431 :                        && TREE_CODE (ops[0]) == SSA_NAME
    9239            0 :                        && SSA_NAME_IS_DEFAULT_DEF (ops[0])
    9240            0 :                        && VAR_P (SSA_NAME_VAR (ops[0])))
    9241         1431 :                       || SLP_TREE_DEF_TYPE (child) == vect_constant_def))
    9242         1431 :                 continue;
    9243              : 
    9244              :               /* For shifts with a scalar argument we don't need
    9245              :                  to cost or code-generate anything.
    9246              :                  ???  Represent this more explicitly.  */
    9247        37569 :               gcc_assert (SLP_TREE_TYPE (node) == shift_vec_info_type
    9248              :                           && j == 1);
    9249        37569 :               continue;
    9250        37569 :             }
    9251              : 
    9252              :           /* Make sure we can generate them and then cost them.  */
    9253      1100533 :           unsigned nvectors, excess_elts;
    9254      1100533 :           if (!vect_get_num_copies_for_invariant (vinfo, child, &nvectors,
    9255              :                                                   &excess_elts))
    9256            0 :             return false;
    9257      1100533 :           vect_prologue_cost_for_slp (child, nvectors, cost_vec);
    9258              :         }
    9259              : 
    9260              :   /* If this node or any of its children can't be vectorized, try pruning
    9261              :      the tree here rather than felling the whole thing.  */
    9262       645966 :   if (!res && vect_slp_convert_to_external (vinfo, node, node_instance))
    9263              :     {
    9264              :       /* We'll need to revisit this for invariant costing and number
    9265              :          of vectorized stmt setting.   */
    9266              :       res = true;
    9267              :     }
    9268              : 
    9269              :   return res;
    9270              : }
    9271              : 
    9272              : /* Mark lanes of NODE that are live outside of the basic-block vectorized
    9273              :    region and that can be vectorized using vectorizable_live_operation
    9274              :    with STMT_VINFO_LIVE_P.  Not handled live operations will cause the
    9275              :    scalar code computing it to be retained.  */
    9276              : 
    9277              : static void
    9278      1002841 : vect_bb_slp_mark_live_stmts (bb_vec_info bb_vinfo, slp_tree node,
    9279              :                              slp_instance instance,
    9280              :                              stmt_vector_for_cost *cost_vec,
    9281              :                              hash_set<stmt_vec_info> &svisited,
    9282              :                              hash_set<slp_tree> &visited)
    9283              : {
    9284      1002841 :   if (visited.add (node))
    9285        58615 :     return;
    9286              : 
    9287              :   unsigned i;
    9288              :   stmt_vec_info stmt_info;
    9289              :   gimple *last_stmt = NULL;
    9290      3390104 :   FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
    9291              :     {
    9292      2445878 :       if (!stmt_info || svisited.contains (stmt_info))
    9293        95054 :         continue;
    9294      2410857 :       stmt_vec_info orig_stmt_info = vect_orig_stmt (stmt_info);
    9295      2410857 :       if (STMT_VINFO_IN_PATTERN_P (orig_stmt_info)
    9296        36987 :           && STMT_VINFO_RELATED_STMT (orig_stmt_info) != stmt_info)
    9297              :         /* Only the pattern root stmt computes the original scalar value.  */
    9298        30417 :         continue;
    9299      2380440 :       if (!PURE_SLP_STMT (orig_stmt_info))
    9300              :         /* Iff the stmt is not part of the vector coverage because it or
    9301              :            uses of it are used by SLP graph leafs as extern input there is
    9302              :            no point in trying to live code-generate from a vector stmt as
    9303              :            the scalar stmt will survive anyway.  */
    9304        29616 :         continue;
    9305      2350824 :       bool mark_visited = true;
    9306      2350824 :       gimple *orig_stmt = orig_stmt_info->stmt;
    9307      2350824 :       ssa_op_iter op_iter;
    9308      2350824 :       def_operand_p def_p;
    9309      5272872 :       FOR_EACH_PHI_OR_STMT_DEF (def_p, orig_stmt, op_iter, SSA_OP_DEF)
    9310              :         {
    9311              :           /* We have to verify whether we can insert the lane extract
    9312              :              before all uses.  The following is a conservative approximation.
    9313              :              We cannot put this into vectorizable_live_operation because
    9314              :              iterating over all use stmts from inside a FOR_EACH_IMM_USE_STMT
    9315              :              doesn't work.
    9316              :              Note that while the fact that we emit code for loads at the
    9317              :              first load should make this a non-problem leafs we construct
    9318              :              from scalars are vectorized after the last scalar def.
    9319              :              ???  If we'd actually compute the insert location during
    9320              :              analysis we could use sth less conservative than the last
    9321              :              scalar stmt in the node for the dominance check.  */
    9322              :           /* ???  What remains is "live" uses in vector CTORs in the same
    9323              :              SLP graph which is where those uses can end up code-generated
    9324              :              right after their definition instead of close to their original
    9325              :              use.  But that would restrict us to code-generate lane-extracts
    9326              :              from the latest stmt in a node.  So we compensate for this
    9327              :              during code-generation, simply not replacing uses for those
    9328              :              hopefully rare cases.  */
    9329       571224 :           imm_use_iterator use_iter;
    9330              : 
    9331       571224 :           bool live_p = false;
    9332       571224 :           bool can_insert = true;
    9333       571224 :           use_operand_p use_p;
    9334      1714342 :           FOR_EACH_IMM_USE_FAST (use_p, use_iter, DEF_FROM_PTR (def_p))
    9335              :             {
    9336      1151194 :               gimple *use_stmt = USE_STMT (use_p);
    9337      1151194 :               stmt_vec_info use_stmt_info;
    9338      1151194 :               if (!(!is_gimple_debug (use_stmt)
    9339       886616 :                     && (!(use_stmt_info = bb_vinfo->lookup_stmt (use_stmt))
    9340       875920 :                         || !PURE_SLP_STMT (use_stmt_info))))
    9341       938892 :                 continue;
    9342       212302 :               live_p = true;
    9343       212302 :               if (!last_stmt)
    9344        65740 :                 last_stmt
    9345        66002 :                   = (node->si ? node->si
    9346          262 :                      : vect_find_last_scalar_stmt_in_slp (node)->stmt);
    9347       212302 :               if (is_a <gphi *> (use_stmt))
    9348              :                 {
    9349        72594 :                   if (!dominated_by_p (CDI_DOMINATORS,
    9350        36297 :                                        phi_arg_edge_from_use (use_p)->src,
    9351        36297 :                                        gimple_bb (last_stmt)))
    9352              :                     can_insert = false;
    9353              :                 }
    9354              :               /* As we instert after last_stmt it may not be the use_stmt
    9355              :                  itself.  */
    9356       176005 :               else if (last_stmt == use_stmt
    9357       176005 :                        || !vect_stmt_dominates_stmt_p (last_stmt, use_stmt))
    9358              :                 can_insert = false;
    9359              :               if (!can_insert)
    9360              :                 {
    9361         8076 :                   if (dump_enabled_p ())
    9362           82 :                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    9363              :                                      "Cannot determine insertion place for "
    9364              :                                      "lane extract of %T at node %p\n",
    9365              :                                      DEF_FROM_PTR (def_p), (void *)node);
    9366              :                   can_insert = false;
    9367              :                   break;
    9368              :                 }
    9369       571224 :             }
    9370       571224 :           if (live_p && can_insert)
    9371              :             {
    9372              :               /* Only record a live stmt when we can replace all uses.  We
    9373              :                  record from which SLP tree we vectorize the uses, so we'll
    9374              :                  cost once and can deal with the case that not all SLP nodes
    9375              :                  may be suitable for code-generation of all live uses.
    9376              :                  ???  But we never split up the work between multiple SLP
    9377              :                  nodes.  */
    9378       106268 :               STMT_VINFO_LIVE_P (stmt_info) = true;
    9379       106268 :               if (!vectorizable_live_operation (bb_vinfo, stmt_info, node,
    9380              :                                                 instance, i, false, cost_vec))
    9381              :                 {
    9382            0 :                   STMT_VINFO_LIVE_P (stmt_info) = false;
    9383            0 :                   mark_visited = false;
    9384              :                 }
    9385              :             }
    9386              :         }
    9387      2350824 :       if (mark_visited)
    9388      2350824 :         svisited.add (stmt_info);
    9389              :     }
    9390              : 
    9391              :   slp_tree child;
    9392      2759844 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    9393       985891 :     if (child && SLP_TREE_DEF_TYPE (child) == vect_internal_def)
    9394       282109 :       vect_bb_slp_mark_live_stmts (bb_vinfo, child, instance, cost_vec,
    9395              :                                    svisited, visited);
    9396              : }
    9397              : 
    9398              : /* Traverse all slp instances of BB_VINFO, and mark lanes of every node that
    9399              :    are live outside of the basic-block vectorized region and that can be
    9400              :    vectorized using vectorizable_live_operation with STMT_VINFO_LIVE_P.  */
    9401              : 
    9402              : static void
    9403       248621 : vect_bb_slp_mark_live_stmts (bb_vec_info bb_vinfo)
    9404              : {
    9405       248621 :   if (bb_vinfo->slp_instances.is_empty ())
    9406            0 :     return;
    9407              : 
    9408       248621 :   hash_set<slp_tree> visited;
    9409       248621 :   hash_set<stmt_vec_info> svisited;
    9410      1466595 :   for (slp_instance instance : bb_vinfo->slp_instances)
    9411              :     {
    9412       720732 :       if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ())
    9413        52685 :         STMT_VINFO_LIVE_P (SLP_INSTANCE_ROOT_STMTS (instance)[0]) = true;
    9414       720732 :       vect_location = instance->location ();
    9415       720732 :       vect_bb_slp_mark_live_stmts (bb_vinfo, SLP_INSTANCE_TREE (instance),
    9416              :                                    instance, &instance->cost_vec,
    9417              :                                    svisited, visited);
    9418              :     }
    9419       248621 : }
    9420              : 
    9421              : /* Determine whether we can vectorize the reduction epilogue for INSTANCE.  */
    9422              : 
    9423              : static bool
    9424        90929 : vectorizable_bb_reduc_epilogue (slp_instance instance,
    9425              :                                 stmt_vector_for_cost *cost_vec)
    9426              : {
    9427        90929 :   gassign *stmt = as_a <gassign *> (instance->root_stmts[0]->stmt);
    9428        90929 :   enum tree_code reduc_code = gimple_assign_rhs_code (stmt);
    9429        90929 :   if (reduc_code == MINUS_EXPR)
    9430            0 :     reduc_code = PLUS_EXPR;
    9431        90929 :   internal_fn reduc_fn;
    9432        90929 :   tree vectype = SLP_TREE_VECTYPE (SLP_INSTANCE_TREE (instance));
    9433        90929 :   if (!vectype
    9434        90917 :       || !useless_type_conversion_p (TREE_TYPE (gimple_assign_lhs (stmt)),
    9435        90917 :                                      TREE_TYPE (vectype))
    9436        53835 :       || (maybe_ne (TYPE_VECTOR_SUBPARTS (vectype), 2u)
    9437          975 :           && (!reduction_fn_for_scalar_code (reduc_code, &reduc_fn)
    9438          975 :               || reduc_fn == IFN_LAST
    9439          975 :               || !direct_internal_fn_supported_p (reduc_fn, vectype,
    9440              :                                                   OPTIMIZE_FOR_BOTH)))
    9441              :       /* Two-element reductions do not need special-handling for fold-left,
    9442              :          other cases are not yet implemented.  remain_defs also have to
    9443              :          be included here.  */
    9444       181894 :       || (needs_fold_left_reduction_p (TREE_TYPE (vectype), reduc_code)
    9445         5959 :           && (!instance->remain_defs.is_empty ()
    9446         1887 :               || SLP_TREE_LANES (SLP_INSTANCE_TREE (instance)) != 2)))
    9447              :     {
    9448        39180 :       if (dump_enabled_p ())
    9449           60 :         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
    9450              :                          "not vectorized: basic block reduction epilogue "
    9451              :                          "operation unsupported.\n");
    9452              :       return false;
    9453              :     }
    9454              : 
    9455              :   /* There's no way to cost a horizontal vector reduction via REDUC_FN so
    9456              :      cost log2 vector operations plus shuffles and one extraction.  */
    9457        51749 :   unsigned steps = floor_log2 (vect_nunits_for_cost (vectype));
    9458        51749 :   record_stmt_cost (cost_vec, steps, vector_stmt, instance->root_stmts[0],
    9459              :                     vectype, 0, vect_body);
    9460        51749 :   record_stmt_cost (cost_vec, steps, vec_perm, instance->root_stmts[0],
    9461              :                     vectype, 0, vect_body);
    9462        51749 :   record_stmt_cost (cost_vec, 1, vec_to_scalar, instance->root_stmts[0],
    9463              :                     vectype, 0, vect_body);
    9464              : 
    9465              :   /* Since we replace all stmts of a possibly longer scalar reduction
    9466              :      chain account for the extra scalar stmts for that.  */
    9467        51749 :   if (!instance->remain_defs.is_empty ())
    9468        32648 :     record_stmt_cost (cost_vec, instance->remain_defs.length (), scalar_stmt,
    9469        16324 :                       instance->root_stmts[0], 0, vect_body);
    9470              :   return true;
    9471              : }
    9472              : 
    9473              : /* Prune from ROOTS all stmts that are computed as part of lanes of NODE
    9474              :    and recurse to children.  */
    9475              : 
    9476              : static void
    9477       364513 : vect_slp_prune_covered_roots (slp_tree node, hash_set<stmt_vec_info> &roots,
    9478              :                               hash_set<slp_tree> &visited)
    9479              : {
    9480       364513 :   if (SLP_TREE_DEF_TYPE (node) != vect_internal_def
    9481       364513 :       || visited.add (node))
    9482              :     return;
    9483              : 
    9484      1025182 :   for (auto stmt : SLP_TREE_SCALAR_STMTS (node))
    9485       455914 :     if (stmt)
    9486       488583 :       roots.remove (vect_orig_stmt (stmt));
    9487              : 
    9488       771396 :   for (auto child : SLP_TREE_CHILDREN (node))
    9489       257130 :     if (child)
    9490       255680 :       vect_slp_prune_covered_roots (child, roots, visited);
    9491              : }
    9492              : 
    9493              : /* Hand over COST_VEC to the target COSTS grouped by SLP node.  */
    9494              : 
    9495              : static void
    9496      1038341 : add_slp_costs (vector_costs *costs, stmt_vector_for_cost& cost_vec)
    9497              : {
    9498      3858490 :   for (unsigned start = 0; start < cost_vec.length ();)
    9499              :     {
    9500      2820149 :       unsigned end = start + 1;
    9501      3544512 :       while (end < cost_vec.length ()
    9502      6060221 :              && cost_vec[start].node == cost_vec[end].node)
    9503       724363 :         end++;
    9504      2820149 :       if (cost_vec[start].node)
    9505      2777353 :         costs->add_slp_cost (cost_vec[start].node,
    9506      2777353 :                              array_slice<stmt_info_for_cost>
    9507      2777353 :                                (cost_vec.begin () + start, end - start));
    9508              :       else
    9509        42796 :         costs->vector_costs::add_slp_cost (cost_vec[start].node,
    9510        42796 :                              array_slice<stmt_info_for_cost>
    9511        42796 :                                (cost_vec.begin () + start, end - start));
    9512      2820149 :       start = end;
    9513              :     }
    9514      1038341 : }
    9515              : 
    9516              : /* Analyze statements in SLP instances of VINFO.  Return true if the
    9517              :    operations are supported. */
    9518              : 
    9519              : bool
    9520       701474 : vect_slp_analyze_operations (vec_info *vinfo)
    9521              : {
    9522       701474 :   slp_instance instance;
    9523       701474 :   int i;
    9524              : 
    9525       701474 :   DUMP_VECT_SCOPE ("vect_slp_analyze_operations");
    9526              : 
    9527       701474 :   hash_set<slp_tree> visited;
    9528      2518770 :   for (i = 0; vinfo->slp_instances.iterate (i, &instance); )
    9529              :     {
    9530      1378416 :       auto_vec<slp_tree> visited_vec;
    9531      1378416 :       stmt_vector_for_cost cost_vec;
    9532      1378416 :       cost_vec.create (2);
    9533      1378416 :       if (is_a <bb_vec_info> (vinfo))
    9534       825436 :         vect_location = instance->location ();
    9535      1378416 :       if (!vect_slp_analyze_node_operations (vinfo,
    9536              :                                              SLP_INSTANCE_TREE (instance),
    9537              :                                              instance, visited, visited_vec,
    9538              :                                              &cost_vec)
    9539              :           /* CTOR instances require vectorized defs for the SLP tree root.  */
    9540      1119665 :           || (SLP_INSTANCE_KIND (instance) == slp_inst_kind_ctor
    9541         6521 :               && (SLP_TREE_DEF_TYPE (SLP_INSTANCE_TREE (instance))
    9542              :                   != vect_internal_def
    9543              :                   /* Make sure we vectorized with the expected type.  */
    9544         6521 :                   || !useless_type_conversion_p
    9545         6521 :                         (TREE_TYPE (TREE_TYPE (gimple_assign_rhs1
    9546              :                                               (instance->root_stmts[0]->stmt))),
    9547         6521 :                          TREE_TYPE (SLP_TREE_VECTYPE
    9548              :                                             (SLP_INSTANCE_TREE (instance))))))
    9549              :           /* Check we can vectorize the reduction.  */
    9550      1119650 :           || (SLP_INSTANCE_KIND (instance) == slp_inst_kind_bb_reduc
    9551        90929 :               && !vectorizable_bb_reduc_epilogue (instance, &cost_vec))
    9552              :           /* Check we can vectorize the gcond.  */
    9553      2458886 :           || (SLP_INSTANCE_KIND (instance) == slp_inst_kind_gcond
    9554        66418 :               && !vectorizable_early_exit (as_a <loop_vec_info> (vinfo),
    9555        66418 :                                            SLP_INSTANCE_ROOT_STMTS (instance)[0],
    9556              :                                            NULL,
    9557              :                                            SLP_INSTANCE_TREE (instance),
    9558              :                                            &cost_vec)))
    9559              :         {
    9560       361720 :           cost_vec.release ();
    9561       361720 :           slp_tree node = SLP_INSTANCE_TREE (instance);
    9562       361720 :           stmt_vec_info stmt_info;
    9563       361720 :           if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ())
    9564       270834 :             stmt_info = SLP_INSTANCE_ROOT_STMTS (instance)[0];
    9565        90886 :           else if (!SLP_TREE_SCALAR_STMTS (node).is_empty ()
    9566        90886 :                    && SLP_TREE_SCALAR_STMTS (node)[0])
    9567              :             stmt_info = SLP_TREE_SCALAR_STMTS (node)[0];
    9568              :           else
    9569            3 :             stmt_info = SLP_TREE_REPRESENTATIVE (node);
    9570       361720 :           if (is_a <loop_vec_info> (vinfo))
    9571              :             {
    9572       262594 :               if (dump_enabled_p ())
    9573         7365 :                 dump_printf_loc (MSG_NOTE, vect_location,
    9574              :                                  "unsupported SLP instance starting from: %G",
    9575              :                                  stmt_info->stmt);
    9576       262594 :               return false;
    9577              :             }
    9578        99126 :           if (dump_enabled_p ())
    9579          120 :             dump_printf_loc (MSG_NOTE, vect_location,
    9580              :                              "removing SLP instance operations starting from: %G",
    9581              :                              stmt_info->stmt);
    9582       236571 :           while (!visited_vec.is_empty ())
    9583              :             {
    9584       137445 :               slp_tree node = visited_vec.pop ();
    9585       137445 :               SLP_TREE_TYPE (node) = undef_vec_info_type;
    9586       137445 :               if (node->data)
    9587              :                 {
    9588         8604 :                   delete node->data;
    9589         8604 :                   node->data = nullptr;
    9590              :                 }
    9591       137445 :               visited.remove (node);
    9592              :             }
    9593        99126 :           vect_free_slp_instance (instance);
    9594        99126 :           vinfo->slp_instances.ordered_remove (i);
    9595              :         }
    9596              :       else
    9597              :         {
    9598      1016696 :           i++;
    9599      1016696 :           if (loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (vinfo))
    9600              :             {
    9601       290386 :               add_slp_costs (loop_vinfo->vector_costs, cost_vec);
    9602       290386 :               cost_vec.release ();
    9603              :             }
    9604              :           else
    9605              :             /* For BB vectorization remember the SLP graph entry
    9606              :                cost for later.  */
    9607       726310 :             instance->cost_vec = cost_vec;
    9608              :         }
    9609      1378416 :     }
    9610              : 
    9611              :   /* Now look for SLP instances with a root that are covered by other
    9612              :      instances and remove them.  */
    9613       438880 :   hash_set<stmt_vec_info> roots;
    9614      1820871 :   for (i = 0; vinfo->slp_instances.iterate (i, &instance); ++i)
    9615      1003998 :     if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ())
    9616        60887 :       roots.add (SLP_INSTANCE_ROOT_STMTS (instance)[0]);
    9617       438880 :   if (!roots.is_empty ())
    9618              :     {
    9619        24850 :       visited.empty ();
    9620       133683 :       for (i = 0; vinfo->slp_instances.iterate (i, &instance); ++i)
    9621       108833 :         vect_slp_prune_covered_roots (SLP_INSTANCE_TREE (instance), roots,
    9622              :                                       visited);
    9623       133683 :       for (i = 0; vinfo->slp_instances.iterate (i, &instance); )
    9624       108833 :         if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ()
    9625        60887 :             && !roots.contains (SLP_INSTANCE_ROOT_STMTS (instance)[0]))
    9626              :           {
    9627         5540 :             stmt_vec_info root = SLP_INSTANCE_ROOT_STMTS (instance)[0];
    9628         5540 :             if (dump_enabled_p ())
    9629          287 :               dump_printf_loc (MSG_NOTE, vect_location,
    9630              :                                "removing SLP instance operations starting "
    9631              :                                "from: %G", root->stmt);
    9632         5540 :             vect_free_slp_instance (instance);
    9633         5540 :             vinfo->slp_instances.ordered_remove (i);
    9634              :           }
    9635              :         else
    9636       103293 :           ++i;
    9637              :     }
    9638              : 
    9639       877760 :   return !vinfo->slp_instances.is_empty ();
    9640      1140354 : }
    9641              : 
    9642              : /* Get the SLP instance leader from INSTANCE_LEADER thereby transitively
    9643              :    closing the eventual chain.  */
    9644              : 
    9645              : static slp_instance
    9646       811669 : get_ultimate_leader (slp_instance instance,
    9647              :                      hash_map<slp_instance, slp_instance> &instance_leader)
    9648              : {
    9649       811669 :   auto_vec<slp_instance *, 8> chain;
    9650       811669 :   slp_instance *tem;
    9651       922670 :   while (*(tem = instance_leader.get (instance)) != instance)
    9652              :     {
    9653       111001 :       chain.safe_push (tem);
    9654       111001 :       instance = *tem;
    9655              :     }
    9656       922670 :   while (!chain.is_empty ())
    9657       111001 :     *chain.pop () = instance;
    9658       811669 :   return instance;
    9659       811669 : }
    9660              : 
    9661              : namespace {
    9662              : /* Subroutine of vect_bb_partition_graph_r.  Map KEY to INSTANCE in
    9663              :    KEY_TO_INSTANCE, making INSTANCE the leader of any previous mapping
    9664              :    for KEY.  Return true if KEY was already in KEY_TO_INSTANCE.
    9665              : 
    9666              :    INSTANCE_LEADER is as for get_ultimate_leader.  */
    9667              : 
    9668              : template<typename T>
    9669              : bool
    9670      3587079 : vect_map_to_instance (slp_instance instance, T key,
    9671              :                       hash_map<T, slp_instance> &key_to_instance,
    9672              :                       hash_map<slp_instance, slp_instance> &instance_leader)
    9673              : {
    9674              :   bool existed_p;
    9675      3587079 :   slp_instance &key_instance = key_to_instance.get_or_insert (key, &existed_p);
    9676      3587079 :   if (!existed_p)
    9677              :     ;
    9678       245149 :   else if (key_instance != instance)
    9679              :     {
    9680              :       /* If we're running into a previously marked key make us the
    9681              :          leader of the current ultimate leader.  This keeps the
    9682              :          leader chain acyclic and works even when the current instance
    9683              :          connects two previously independent graph parts.  */
    9684        90937 :       slp_instance key_leader
    9685        90937 :         = get_ultimate_leader (key_instance, instance_leader);
    9686        90937 :       if (key_leader != instance)
    9687        27239 :         instance_leader.put (key_leader, instance);
    9688              :     }
    9689      3587079 :   key_instance = instance;
    9690      3587079 :   return existed_p;
    9691              : }
    9692              : }
    9693              : 
    9694              : /* Worker of vect_bb_partition_graph, recurse on NODE.  */
    9695              : 
    9696              : static void
    9697      1002841 : vect_bb_partition_graph_r (bb_vec_info bb_vinfo,
    9698              :                            slp_instance instance, slp_tree node,
    9699              :                            hash_map<stmt_vec_info, slp_instance> &stmt_to_instance,
    9700              :                            hash_map<slp_tree, slp_instance> &node_to_instance,
    9701              :                            hash_map<slp_instance, slp_instance> &instance_leader)
    9702              : {
    9703      5581609 :   for (auto stmt_info : SLP_TREE_SCALAR_STMTS (node))
    9704      2584238 :     if (stmt_info)
    9705      2584238 :       vect_map_to_instance (instance, stmt_info, stmt_to_instance,
    9706              :                             instance_leader);
    9707              : 
    9708      1002841 :   if (vect_map_to_instance (instance, node, node_to_instance,
    9709              :                             instance_leader))
    9710              :     return;
    9711              : 
    9712      3589571 :   for (auto child : SLP_TREE_CHILDREN (node))
    9713       985891 :     if (child && SLP_TREE_DEF_TYPE (child) == vect_internal_def)
    9714       282109 :       vect_bb_partition_graph_r (bb_vinfo, instance, child, stmt_to_instance,
    9715              :                                  node_to_instance, instance_leader);
    9716              : }
    9717              : 
    9718              : /* Partition the SLP graph into pieces that can be costed independently.  */
    9719              : 
    9720              : static void
    9721       248621 : vect_bb_partition_graph (bb_vec_info bb_vinfo)
    9722              : {
    9723       248621 :   DUMP_VECT_SCOPE ("vect_bb_partition_graph");
    9724              : 
    9725              :   /* First walk the SLP graph assigning each involved scalar stmt a
    9726              :      corresponding SLP graph entry and upon visiting a previously
    9727              :      marked stmt, make the stmts leader the current SLP graph entry.  */
    9728       248621 :   hash_map<stmt_vec_info, slp_instance> stmt_to_instance;
    9729       248621 :   hash_map<slp_tree, slp_instance> node_to_instance;
    9730       248621 :   hash_map<slp_instance, slp_instance> instance_leader;
    9731       248621 :   slp_instance instance;
    9732      1217974 :   for (unsigned i = 0; bb_vinfo->slp_instances.iterate (i, &instance); ++i)
    9733              :     {
    9734       720732 :       instance_leader.put (instance, instance);
    9735       720732 :       vect_bb_partition_graph_r (bb_vinfo,
    9736              :                                  instance, SLP_INSTANCE_TREE (instance),
    9737              :                                  stmt_to_instance, node_to_instance,
    9738              :                                  instance_leader);
    9739              :     }
    9740              : 
    9741              :   /* Then collect entries to each independent subgraph.  */
    9742      1217974 :   for (unsigned i = 0; bb_vinfo->slp_instances.iterate (i, &instance); ++i)
    9743              :     {
    9744       720732 :       slp_instance leader = get_ultimate_leader (instance, instance_leader);
    9745       720732 :       leader->subgraph_entries.safe_push (instance);
    9746       720732 :       if (dump_enabled_p ()
    9747       720732 :           && leader != instance)
    9748          102 :         dump_printf_loc (MSG_NOTE, vect_location,
    9749              :                          "instance %p is leader of %p\n",
    9750              :                          (void *) leader, (void *) instance);
    9751              :     }
    9752       248621 : }
    9753              : 
    9754              : /* Compute the scalar cost of the SLP node NODE and its children
    9755              :    and return it.  Do not account defs that are marked in LIFE and
    9756              :    update LIFE according to uses of NODE.  */
    9757              : 
    9758              : static void
    9759       716525 : vect_bb_slp_scalar_cost (bb_vec_info vinfo,
    9760              :                          vec<stmt_vec_info> &worklist,
    9761              :                          stmt_vector_for_cost *cost_vec,
    9762              :                          hash_set<stmt_vec_info> &visited)
    9763              : {
    9764      3341023 :   while (!worklist.is_empty ())
    9765              :     {
    9766      2624498 :       stmt_vec_info stmt = worklist.pop ();
    9767      2950340 :       if (!PURE_SLP_STMT (stmt))
    9768       334448 :         continue;
    9769              : 
    9770              :       /* When the stmt is live but not actually vectorized we have
    9771              :          to keep the feeding scalar defs.  */
    9772      2304853 :       if (!STMT_VINFO_LIVE_P (vect_stmt_to_vectorize (stmt)))
    9773              :         {
    9774      2194759 :           bool live_p = false;
    9775      2194759 :           ssa_op_iter op_iter;
    9776      2194759 :           def_operand_p def_p;
    9777      4828011 :           FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt->stmt, op_iter, SSA_OP_DEF)
    9778              :             {
    9779       438493 :               imm_use_iterator use_iter;
    9780       438493 :               gimple *use_stmt;
    9781      1123671 :               FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, DEF_FROM_PTR (def_p))
    9782       685178 :                 if (!is_gimple_debug (use_stmt))
    9783              :                   {
    9784       515961 :                     stmt_vec_info use_stmt_info = vinfo->lookup_stmt (use_stmt);
    9785       515961 :                     if (!use_stmt_info || !PURE_SLP_STMT (use_stmt_info))
    9786              :                       {
    9787        15803 :                         if (dump_enabled_p ())
    9788              :                           {
    9789           92 :                             dump_printf_loc (MSG_NOTE, vect_location,
    9790              :                                              "stmt considered live: %G",
    9791              :                                              stmt->stmt);
    9792           92 :                             dump_printf_loc (MSG_NOTE, vect_location,
    9793              :                                              "because of use in: %G",
    9794              :                                              use_stmt);
    9795              :                           }
    9796              :                         live_p = true;
    9797              :                       }
    9798       438493 :                   }
    9799              :             }
    9800      2194759 :           if (live_p)
    9801         8606 :             continue;
    9802              :         }
    9803              : 
    9804              :       /* The following assert verifies that vect_bb_partition_graph
    9805              :          partitions the SLP graph in a way that each scalar stmt of
    9806              :          the coverage of the SLP graph belongs to exactly one subgraph.
    9807              :          ???  This is currently not guaranteed since the function
    9808              :          works purely on SLP_TREE_SCALAR_STMTS, resulting in the assert
    9809              :          tripping or scalar stmts costed multiple times, making vectorization
    9810              :          more profitable than it really is.  */
    9811              :       /* gcc_checking_assert (!gimple_visited_p (stmt->stmt)); */
    9812              : 
    9813      2290050 :       if (vect_nop_conversion_p (stmt))
    9814              :         ;
    9815              :       /* For single-argument PHIs assume coalescing which means zero
    9816              :          cost for the scalar and the vector PHIs.  This avoids
    9817              :          artificially favoring the vector path (but may pessimize it
    9818              :          in some cases).  */
    9819      2258698 :       else if (is_a <gphi *> (stmt->stmt)
    9820      2258698 :                && gimple_phi_num_args (as_a <gphi *> (stmt->stmt)) == 1)
    9821              :         ;
    9822              :       else
    9823              :         {
    9824      2248168 :           vect_cost_for_stmt kind;
    9825      2248168 :           if (STMT_VINFO_DATA_REF (stmt))
    9826              :             {
    9827      2021471 :               data_reference_p dr = STMT_VINFO_DATA_REF (stmt);
    9828      2021471 :               tree base = get_base_address (DR_REF (dr));
    9829              :               /* When the scalar access is to a non-global not
    9830              :                  address-taken decl that is not BLKmode assume we can
    9831              :                  access it with a single non-load/store instruction.  */
    9832      2021471 :               if (DECL_P (base)
    9833      1550496 :                   && !is_global_var (base)
    9834      1471743 :                   && !TREE_ADDRESSABLE (base)
    9835      2580180 :                   && DECL_MODE (base) != BLKmode)
    9836              :                 kind = scalar_stmt;
    9837      1877097 :               else if (DR_IS_READ (STMT_VINFO_DATA_REF (stmt)))
    9838              :                 kind = scalar_load;
    9839              :               else
    9840      1628830 :                 kind = scalar_store;
    9841              :             }
    9842              :           else
    9843              :             kind = scalar_stmt;
    9844              :           /* Cost each scalar stmt only once.  */
    9845      2248168 :           gimple_set_visited (stmt->stmt, true);
    9846      2248168 :           record_stmt_cost (cost_vec, 1, kind, stmt, NULL_TREE, 0, vect_body);
    9847              :         }
    9848              : 
    9849              :       /* Now walk relevant parts of the SSA use-def graph.  */
    9850      2290050 :       slp_oprnds child_ops (stmt);
    9851      7128330 :       for (unsigned i = 0; i < child_ops.num_slp_children; ++i)
    9852              :         {
    9853      2548230 :           tree op = child_ops.get_op_for_slp_child (stmt, i);
    9854      2548230 :           stmt_vec_info def = vinfo->lookup_def (op);
    9855      2548230 :           if (def && !visited.add (def))
    9856       765469 :             worklist.safe_push (def);
    9857              :         }
    9858              :     }
    9859       716525 : }
    9860              : 
    9861              : 
    9862              : /* Comparator for the loop-index sorted cost vectors.  */
    9863              : 
    9864              : static int
    9865     20187638 : li_cost_vec_cmp (const void *a_, const void *b_, void *)
    9866              : {
    9867     20187638 :   auto *a = (const std::pair<unsigned, stmt_info_for_cost *> *)a_;
    9868     20187638 :   auto *b = (const std::pair<unsigned, stmt_info_for_cost *> *)b_;
    9869     20187638 :   if (a->first < b->first)
    9870              :     return -1;
    9871     18740510 :   else if (a->first == b->first)
    9872     17585797 :     return 0;
    9873              :   return 1;
    9874              : }
    9875              : 
    9876              : /* Check if vectorization of the basic block is profitable for the
    9877              :    subgraph denoted by SLP_INSTANCES.  */
    9878              : 
    9879              : static bool
    9880       689490 : vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo,
    9881              :                                     vec<slp_instance> slp_instances,
    9882              :                                     loop_p orig_loop)
    9883              : {
    9884       689490 :   slp_instance instance;
    9885       689490 :   int i;
    9886       689490 :   unsigned int vec_inside_cost = 0, vec_outside_cost = 0, scalar_cost = 0;
    9887       689490 :   unsigned int vec_prologue_cost = 0, vec_epilogue_cost = 0;
    9888              : 
    9889       689490 :   if (dump_enabled_p ())
    9890              :     {
    9891          125 :       dump_printf_loc (MSG_NOTE, vect_location, "Costing subgraph:\n");
    9892          260 :       FOR_EACH_VEC_ELT (slp_instances, i, instance)
    9893          135 :         dump_printf_loc (MSG_NOTE, vect_location, "   entry instance %p -> "
    9894              :                          "node %p\n", (void *)instance,
    9895          135 :                          (void *)SLP_INSTANCE_TREE (instance));
    9896          125 :       hash_set<slp_tree> visited;
    9897          510 :       FOR_EACH_VEC_ELT (slp_instances, i, instance)
    9898          135 :         vect_print_slp_graph (MSG_NOTE, vect_location,
    9899              :                               SLP_INSTANCE_TREE (instance), visited);
    9900          125 :     }
    9901              : 
    9902              :   /* Then DFS walk scalar stmts, performing costing and handling
    9903              :      still live scalar stmts via the previously computed vector coverage.  */
    9904       689490 :   stmt_vector_for_cost scalar_costs = vNULL;
    9905       689490 :   stmt_vector_for_cost vector_costs = vNULL;
    9906       689490 :   hash_set<slp_tree> visited;
    9907       689490 :   hash_set<stmt_vec_info> svisited;
    9908      2095505 :   FOR_EACH_VEC_ELT (slp_instances, i, instance)
    9909              :     {
    9910       716525 :       auto_vec<stmt_vec_info> worklist;
    9911       716525 :       if (SLP_INSTANCE_ROOT_STMTS (instance).exists ())
    9912       103790 :         record_stmt_cost (&scalar_costs,
    9913        51895 :                           SLP_INSTANCE_ROOT_STMTS (instance).length (),
    9914              :                           scalar_stmt,
    9915        51895 :                           SLP_INSTANCE_ROOT_STMTS (instance)[0], 0, vect_body);
    9916      4024039 :       for (auto stmt : SLP_TREE_SCALAR_STMTS (SLP_INSTANCE_TREE (instance)))
    9917              :         {
    9918      1874464 :           stmt = vect_orig_stmt (stmt);
    9919      1874464 :           if (!svisited.add (stmt))
    9920      1859029 :             worklist.safe_push (stmt);
    9921              :         }
    9922       716525 :       vect_bb_slp_scalar_cost (bb_vinfo, worklist, &scalar_costs, svisited);
    9923       716525 :       vector_costs.safe_splice (instance->cost_vec);
    9924       716525 :       instance->cost_vec.release ();
    9925       716525 :     }
    9926              : 
    9927       689490 :   if (dump_enabled_p ())
    9928          125 :     dump_printf_loc (MSG_NOTE, vect_location, "Cost model analysis: \n");
    9929              : 
    9930              :   /* When costing non-loop vectorization we need to consider each covered
    9931              :      loop independently and make sure vectorization is profitable.  For
    9932              :      now we assume a loop may be not entered or executed an arbitrary
    9933              :      number of iterations (???  static information can provide more
    9934              :      precise info here) which means we can simply cost each containing
    9935              :      loops stmts separately.  */
    9936              : 
    9937              :   /* First produce cost vectors sorted by loop index.  */
    9938       689490 :   auto_vec<std::pair<unsigned, stmt_info_for_cost *> >
    9939      1378980 :     li_scalar_costs (scalar_costs.length ());
    9940       689490 :   auto_vec<std::pair<unsigned, stmt_info_for_cost *> >
    9941      1378967 :     li_vector_costs (vector_costs.length ());
    9942       689490 :   stmt_info_for_cost *cost;
    9943      3679043 :   FOR_EACH_VEC_ELT (scalar_costs, i, cost)
    9944              :     {
    9945      2300063 :       unsigned l = gimple_bb (cost->stmt_info->stmt)->loop_father->num;
    9946      2300063 :       li_scalar_costs.quick_push (std::make_pair (l, cost));
    9947              :     }
    9948              :   /* Use a random used loop as fallback in case the first vector_costs
    9949              :      entry does not have a location associated with it.  */
    9950       689490 :   unsigned l = li_scalar_costs[0].first;
    9951      2650475 :   FOR_EACH_VEC_ELT (vector_costs, i, cost)
    9952              :     {
    9953              :       /* Use SLP node placement according to the computed schedule.  */
    9954      1960985 :       if (cost->node && cost->node->si)
    9955      1221515 :         l = gimple_bb (cost->node->si)->loop_father->num;
    9956              :       /* For schedules at region boundary use the region entry loop.  */
    9957       739470 :       else if (cost->node)
    9958       588907 :         l = bb_vinfo->bbs[0]->loop_father->num;
    9959              :       /* SLP instance root stmts do not have an associated SLP node.  */
    9960       150563 :       else if (cost->stmt_info)
    9961       150563 :         l = gimple_bb (cost->stmt_info->stmt)->loop_father->num;
    9962              :       /* And since vect_prologue_cost_for_slp can end up costing with
    9963              :          neither, inherit from the previous node.  */
    9964      1960985 :       li_vector_costs.quick_push (std::make_pair (l, cost));
    9965              :     }
    9966       689490 :   li_scalar_costs.stablesort (li_cost_vec_cmp, NULL);
    9967       689490 :   li_vector_costs.stablesort (li_cost_vec_cmp, NULL);
    9968              : 
    9969       689490 :   unsigned total_vec_outside_cost = 0;
    9970       689490 :   unsigned total_vec_inside_cost = 0;
    9971       689490 :   unsigned total_scalar_cost = 0;
    9972              : 
    9973              :   /* Now cost the portions individually.  */
    9974       689490 :   unsigned vi = 0;
    9975       689490 :   unsigned si = 0;
    9976       689490 :   bool profitable = true;
    9977      1380311 :   while (si < li_scalar_costs.length ()
    9978      2130097 :          || vi < li_vector_costs.length ())
    9979              :     {
    9980       749799 :       unsigned sl
    9981      1498267 :         = si < li_scalar_costs.length () ? li_scalar_costs[si].first : -1U;
    9982       749799 :       unsigned vl
    9983      1499514 :         = vi < li_vector_costs.length () ? li_vector_costs[vi].first : -1U;
    9984              : 
    9985       749799 :       class vector_costs *scalar_target_cost_data = nullptr;
    9986       749799 :       scalar_cost = 0;
    9987       749799 :       if (sl <= vl)
    9988              :         {
    9989       704857 :           if (dump_enabled_p ())
    9990          147 :             dump_printf_loc (MSG_NOTE, vect_location,
    9991              :                              "Scalar cost for part in loop %d\n", sl);
    9992       704857 :           scalar_target_cost_data = init_cost (bb_vinfo, true);
    9993      2300063 :           do
    9994              :             {
    9995      2300063 :               add_stmt_cost (scalar_target_cost_data,
    9996      2300063 :                              li_scalar_costs[si].second);
    9997      2300063 :               si++;
    9998              :             }
    9999      2300063 :           while (si < li_scalar_costs.length ()
   10000      4615493 :                  && li_scalar_costs[si].first == sl);
   10001       704857 :           scalar_target_cost_data->finish_cost (nullptr);
   10002       704857 :           scalar_cost = scalar_target_cost_data->body_cost ();
   10003       704857 :           total_scalar_cost += scalar_cost;
   10004       704857 :           if (sl < vl)
   10005              :             {
   10006         1844 :               if (dump_enabled_p ())
   10007            2 :                 dump_printf_loc (MSG_NOTE, vect_location,
   10008              :                                  "Scalar %d loop part does not "
   10009              :                                  "have corresponding vector part\n", sl);
   10010         1844 :               delete scalar_target_cost_data;
   10011       650053 :               continue;
   10012              :             }
   10013              :         }
   10014              : 
   10015              :       /* Complete the target-specific vector cost calculation.  */
   10016       747955 :       if (dump_enabled_p ())
   10017          149 :         dump_printf_loc (MSG_NOTE, vect_location,
   10018              :                          "Vector cost for part in loop %d\n", vl);
   10019       747955 :       class vector_costs *vect_target_cost_data = init_cost (bb_vinfo, false);
   10020       747955 :       auto_vec<stmt_info_for_cost> tem;
   10021      1960985 :       do
   10022              :         {
   10023      1960985 :           tem.safe_push (*li_vector_costs[vi].second);
   10024      1960985 :           vi++;
   10025              :         }
   10026      1960985 :       while (vi < li_vector_costs.length ()
   10027      3980448 :              && li_vector_costs[vi].first == vl);
   10028       747955 :       add_slp_costs (vect_target_cost_data, tem);
   10029       747955 :       vect_target_cost_data->finish_cost (scalar_target_cost_data);
   10030       747955 :       vec_prologue_cost = vect_target_cost_data->prologue_cost ();
   10031       747955 :       vec_inside_cost = vect_target_cost_data->body_cost ();
   10032       747955 :       vec_epilogue_cost = vect_target_cost_data->epilogue_cost ();
   10033       747955 :       if (scalar_target_cost_data)
   10034       703013 :         delete scalar_target_cost_data;
   10035       747955 :       delete vect_target_cost_data;
   10036              : 
   10037       747955 :       vec_outside_cost = vec_prologue_cost + vec_epilogue_cost;
   10038              : 
   10039       747955 :       total_vec_outside_cost += vec_outside_cost;
   10040       747955 :       total_vec_inside_cost += vec_inside_cost;
   10041              : 
   10042       747955 :       if (sl > vl && dump_enabled_p ())
   10043            4 :         dump_printf_loc (MSG_NOTE, vect_location,
   10044              :                          "Vector %d loop part does not "
   10045              :                          "have corresponding scalar part\n", vl);
   10046              : 
   10047              :       /* When this is vector costs for the region entry delay costing
   10048              :          and instead only require the total costs to be profitable.  */
   10049       747955 :       if (vl == (unsigned) bb_vinfo->bbs[0]->loop_father->num)
   10050       648209 :         continue;
   10051              : 
   10052        99746 :       if (dump_enabled_p ())
   10053              :         {
   10054           52 :           dump_printf_loc (MSG_NOTE, vect_location,
   10055              :                            "Cost model analysis for part in loop %d:\n",
   10056           52 :                            std::min (sl, vl));
   10057           52 :           dump_printf (MSG_NOTE, "  Vector cost: %d\n",
   10058              :                        vec_inside_cost + vec_outside_cost);
   10059           52 :           dump_printf (MSG_NOTE, "  Scalar cost: %d\n", scalar_cost);
   10060              :         }
   10061              : 
   10062              :       /* Vectorization is profitable if its cost is more than the cost of scalar
   10063              :          version.  Note that we err on the vector side for equal cost because
   10064              :          the cost estimate is otherwise quite pessimistic (constant uses are
   10065              :          free on the scalar side but cost a load on the vector side for
   10066              :          example).  */
   10067        99746 :       if (vec_outside_cost + vec_inside_cost > scalar_cost)
   10068        46549 :         profitable = false;
   10069       747955 :     }
   10070              : 
   10071       689490 :   if (dump_enabled_p ())
   10072              :     {
   10073          125 :       dump_printf_loc (MSG_NOTE, vect_location,
   10074              :                        "Cost model analysis for whole subgraph:\n");
   10075          125 :       dump_printf (MSG_NOTE, "  Vector cost: %d\n",
   10076              :                    total_vec_inside_cost + total_vec_outside_cost);
   10077          125 :       dump_printf (MSG_NOTE, "  Scalar cost: %d\n", total_scalar_cost);
   10078              :     }
   10079              : 
   10080              :   /* For the case where the outermost region had no scalar cost require
   10081              :      overall profitability.  */
   10082       689490 :   if (total_vec_outside_cost + total_vec_inside_cost > total_scalar_cost)
   10083       211817 :     profitable = false;
   10084              : 
   10085              :   /* Unset visited flag.  This is delayed when the subgraph is profitable
   10086              :      and we process the loop for remaining unvectorized if-converted code.  */
   10087       689490 :   if (!orig_loop || !profitable)
   10088      2987501 :     FOR_EACH_VEC_ELT (scalar_costs, i, cost)
   10089      2298136 :       gimple_set_visited  (cost->stmt_info->stmt, false);
   10090              : 
   10091       689490 :   scalar_costs.release ();
   10092       689490 :   vector_costs.release ();
   10093              : 
   10094       689490 :   return profitable;
   10095       689490 : }
   10096              : 
   10097              : /* qsort comparator for lane defs.  */
   10098              : 
   10099              : static int
   10100          128 : vld_cmp (const void *a_, const void *b_)
   10101              : {
   10102          128 :   auto *a = (const std::pair<unsigned, tree> *)a_;
   10103          128 :   auto *b = (const std::pair<unsigned, tree> *)b_;
   10104          128 :   return a->first - b->first;
   10105              : }
   10106              : 
   10107              : /* Return true if USE_STMT is a vector lane insert into VEC and set
   10108              :    *THIS_LANE to the lane number that is set.  */
   10109              : 
   10110              : static bool
   10111          295 : vect_slp_is_lane_insert (gimple *use_stmt, tree vec, unsigned *this_lane)
   10112              : {
   10113          295 :   gassign *use_ass = dyn_cast <gassign *> (use_stmt);
   10114          110 :   if (!use_ass
   10115          110 :       || gimple_assign_rhs_code (use_ass) != BIT_INSERT_EXPR
   10116           35 :       || (vec
   10117           35 :           ? gimple_assign_rhs1 (use_ass) != vec
   10118           26 :           : ((vec = gimple_assign_rhs1 (use_ass)), false))
   10119           61 :       || !useless_type_conversion_p (TREE_TYPE (TREE_TYPE (vec)),
   10120           61 :                                      TREE_TYPE (gimple_assign_rhs2 (use_ass)))
   10121           61 :       || !constant_multiple_p
   10122           61 :             (tree_to_poly_uint64 (gimple_assign_rhs3 (use_ass)),
   10123          356 :              tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (TREE_TYPE (vec)))),
   10124              :              this_lane))
   10125              :     return false;
   10126              :   return true;
   10127              : }
   10128              : 
   10129              : /* Find any vectorizable constructors and add them to the grouped_store
   10130              :    array.  */
   10131              : 
   10132              : static void
   10133      2349498 : vect_slp_check_for_roots (bb_vec_info bb_vinfo)
   10134              : {
   10135     18748341 :   for (unsigned i = 0; i < bb_vinfo->nbbs; ++i)
   10136     32797686 :     for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[i]);
   10137    152524186 :          !gsi_end_p (gsi); gsi_next (&gsi))
   10138              :     {
   10139    136125343 :       gassign *assign = dyn_cast<gassign *> (gsi_stmt (gsi));
   10140              :       /* This can be used to start SLP discovery for early breaks for BB early breaks
   10141              :          when we get that far.  */
   10142    136125343 :       if (!assign)
   10143    104858507 :         continue;
   10144              : 
   10145     33451706 :       tree rhs = gimple_assign_rhs1 (assign);
   10146     33451706 :       enum tree_code code = gimple_assign_rhs_code (assign);
   10147     33451706 :       use_operand_p use_p;
   10148     33451706 :       gimple *use_stmt;
   10149     33451706 :       if (code == CONSTRUCTOR)
   10150              :         {
   10151      1799600 :           if (!VECTOR_TYPE_P (TREE_TYPE (rhs))
   10152      1846837 :               || maybe_ne (TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)),
   10153       103121 :                            CONSTRUCTOR_NELTS (rhs))
   10154        47237 :               || VECTOR_TYPE_P (TREE_TYPE (CONSTRUCTOR_ELT (rhs, 0)->value))
   10155      1846817 :               || uniform_vector_p (rhs))
   10156      1784275 :             continue;
   10157              : 
   10158              :           unsigned j;
   10159              :           tree val;
   10160        76477 :           FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), j, val)
   10161        61152 :             if (TREE_CODE (val) != SSA_NAME
   10162        61152 :                 || !bb_vinfo->lookup_def (val))
   10163              :               break;
   10164        37824 :           if (j != CONSTRUCTOR_NELTS (rhs))
   10165         3587 :             continue;
   10166              : 
   10167        15325 :           vec<stmt_vec_info> roots = vNULL;
   10168        15325 :           roots.safe_push (bb_vinfo->lookup_stmt (assign));
   10169        15325 :           vec<stmt_vec_info> stmts;
   10170        15325 :           stmts.create (CONSTRUCTOR_NELTS (rhs));
   10171        86160 :           FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), j, val)
   10172        55510 :             stmts.quick_push
   10173        55510 :               (vect_stmt_to_vectorize (bb_vinfo->lookup_def (val)));
   10174        15325 :           bb_vinfo->roots.safe_push (slp_root (slp_inst_kind_ctor,
   10175        15325 :                                                stmts, roots));
   10176              :         }
   10177     31652106 :       else if (code == BIT_INSERT_EXPR
   10178         1022 :                && VECTOR_TYPE_P (TREE_TYPE (rhs))
   10179          721 :                && TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)).is_constant ()
   10180          721 :                && TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)).to_constant () > 1
   10181          718 :                && integer_zerop (gimple_assign_rhs3 (assign))
   10182          392 :                && useless_type_conversion_p
   10183          392 :                     (TREE_TYPE (TREE_TYPE (rhs)),
   10184          392 :                      TREE_TYPE (gimple_assign_rhs2 (assign)))
   10185     31652830 :                && bb_vinfo->lookup_def (gimple_assign_rhs2 (assign)))
   10186              :         {
   10187              :           /* We start to match on insert to lane zero but since the
   10188              :              inserts need not be ordered we'd have to search both
   10189              :              the def and the use chains.  */
   10190          257 :           tree vectype = TREE_TYPE (rhs);
   10191          257 :           unsigned nlanes = TYPE_VECTOR_SUBPARTS (vectype).to_constant ();
   10192          257 :           auto_vec<std::pair<unsigned, tree> > lane_defs (nlanes);
   10193          257 :           auto_sbitmap lanes (nlanes);
   10194          257 :           bitmap_clear (lanes);
   10195          257 :           bitmap_set_bit (lanes, 0);
   10196          257 :           tree def = gimple_assign_lhs (assign);
   10197          257 :           lane_defs.quick_push
   10198          257 :                       (std::make_pair (0, gimple_assign_rhs2 (assign)));
   10199          257 :           unsigned lanes_found = 1;
   10200              :           /* Start with the use chains, the last stmt will be the root.  */
   10201          257 :           stmt_vec_info last = bb_vinfo->lookup_stmt (assign);
   10202          257 :           vec<stmt_vec_info> roots = vNULL;
   10203          257 :           roots.safe_push (last);
   10204          268 :           do
   10205              :             {
   10206          268 :               use_operand_p use_p;
   10207          268 :               gimple *use_stmt;
   10208          268 :               if (!single_imm_use (def, &use_p, &use_stmt))
   10209              :                 break;
   10210          256 :               unsigned this_lane;
   10211          256 :               if (!bb_vinfo->lookup_stmt (use_stmt)
   10212          256 :                   || !vect_slp_is_lane_insert (use_stmt, def, &this_lane)
   10213          291 :                   || !bb_vinfo->lookup_def (gimple_assign_rhs2 (use_stmt)))
   10214              :                 break;
   10215           35 :               if (bitmap_bit_p (lanes, this_lane))
   10216              :                 break;
   10217           15 :               lanes_found++;
   10218           15 :               bitmap_set_bit (lanes, this_lane);
   10219           15 :               gassign *use_ass = as_a <gassign *> (use_stmt);
   10220           15 :               lane_defs.quick_push (std::make_pair
   10221           15 :                                      (this_lane, gimple_assign_rhs2 (use_ass)));
   10222           15 :               last = bb_vinfo->lookup_stmt (use_ass);
   10223           15 :               roots.safe_push (last);
   10224           15 :               def = gimple_assign_lhs (use_ass);
   10225              :             }
   10226           15 :           while (lanes_found < nlanes);
   10227          257 :           if (roots.length () > 1)
   10228            7 :             std::swap(roots[0], roots[roots.length () - 1]);
   10229          257 :           if (lanes_found < nlanes)
   10230              :             {
   10231              :               /* Now search the def chain.  */
   10232          253 :               def = gimple_assign_rhs1 (assign);
   10233          255 :               do
   10234              :                 {
   10235          255 :                   if (TREE_CODE (def) != SSA_NAME
   10236          255 :                       || !has_single_use (def))
   10237              :                     break;
   10238           59 :                   gimple *def_stmt = SSA_NAME_DEF_STMT (def);
   10239           59 :                   unsigned this_lane;
   10240           59 :                   if (!bb_vinfo->lookup_stmt (def_stmt)
   10241           39 :                       || !vect_slp_is_lane_insert (def_stmt,
   10242              :                                                    NULL_TREE, &this_lane)
   10243           85 :                       || !bb_vinfo->lookup_def (gimple_assign_rhs2 (def_stmt)))
   10244              :                     break;
   10245           26 :                   if (bitmap_bit_p (lanes, this_lane))
   10246              :                     break;
   10247            6 :                   lanes_found++;
   10248            6 :                   bitmap_set_bit (lanes, this_lane);
   10249           12 :                   lane_defs.quick_push (std::make_pair
   10250            6 :                                           (this_lane,
   10251            6 :                                            gimple_assign_rhs2 (def_stmt)));
   10252            6 :                   roots.safe_push (bb_vinfo->lookup_stmt (def_stmt));
   10253            6 :                   def = gimple_assign_rhs1 (def_stmt);
   10254              :                 }
   10255            6 :               while (lanes_found < nlanes);
   10256              :             }
   10257          257 :           if (lanes_found == nlanes)
   10258              :             {
   10259              :               /* Sort lane_defs after the lane index and register the root.  */
   10260            8 :               lane_defs.qsort (vld_cmp);
   10261            8 :               vec<stmt_vec_info> stmts;
   10262            8 :               stmts.create (nlanes);
   10263           44 :               for (unsigned i = 0; i < nlanes; ++i)
   10264           28 :                 stmts.quick_push (bb_vinfo->lookup_def (lane_defs[i].second));
   10265            8 :               bb_vinfo->roots.safe_push (slp_root (slp_inst_kind_ctor,
   10266            8 :                                                    stmts, roots));
   10267              :             }
   10268              :           else
   10269          249 :             roots.release ();
   10270          257 :         }
   10271     31651849 :       else if (!VECTOR_TYPE_P (TREE_TYPE (rhs))
   10272     30579180 :                && (associative_tree_code (code) || code == MINUS_EXPR)
   10273              :                /* Ops with constants at the tail can be stripped here.  */
   10274      6730933 :                && TREE_CODE (rhs) == SSA_NAME
   10275      6667390 :                && TREE_CODE (gimple_assign_rhs2 (assign)) == SSA_NAME
   10276              :                /* Should be the chain end.  */
   10277     34549495 :                && (!single_imm_use (gimple_assign_lhs (assign),
   10278              :                                     &use_p, &use_stmt)
   10279      2335058 :                    || !is_gimple_assign (use_stmt)
   10280      1733335 :                    || (gimple_assign_rhs_code (use_stmt) != code
   10281      1164810 :                        && ((code != PLUS_EXPR && code != MINUS_EXPR)
   10282       674807 :                            || (gimple_assign_rhs_code (use_stmt)
   10283       674807 :                                != (code == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR))))))
   10284              :         {
   10285              :           /* We start the match at the end of a possible association
   10286              :              chain.  */
   10287      2211911 :           auto_vec<chain_op_t> chain;
   10288      2211911 :           auto_vec<std::pair<tree_code, gimple *> > worklist;
   10289      2211911 :           auto_vec<gimple *> chain_stmts;
   10290      2211911 :           gimple *code_stmt = NULL, *alt_code_stmt = NULL;
   10291      2211911 :           if (code == MINUS_EXPR)
   10292       369074 :             code = PLUS_EXPR;
   10293      2211911 :           internal_fn reduc_fn;
   10294      2612506 :           if (!reduction_fn_for_scalar_code (code, &reduc_fn)
   10295      2211911 :               || reduc_fn == IFN_LAST)
   10296       400595 :             continue;
   10297      1811316 :           vect_slp_linearize_chain (bb_vinfo, worklist, chain, code, assign,
   10298              :                                     /* ??? */
   10299              :                                     code_stmt, alt_code_stmt, &chain_stmts,
   10300              :                                     false);
   10301      3622632 :           if (chain.length () > 1)
   10302              :             {
   10303              :               /* Sort the chain according to def_type and operation.  */
   10304      1811316 :               chain.sort (dt_sort_cmp, bb_vinfo);
   10305              :               /* ???  Now we'd want to strip externals and constants
   10306              :                  but record those to be handled in the epilogue.  */
   10307              :               /* ???  For now do not allow mixing ops or externs/constants.  */
   10308      1811316 :               bool invalid = false;
   10309      1811316 :               unsigned remain_cnt = 0;
   10310      7469127 :               for (unsigned i = 0; i < chain.length (); ++i)
   10311              :                 {
   10312      4215569 :                   if (chain[i].code != code)
   10313              :                     {
   10314              :                       invalid = true;
   10315              :                       break;
   10316              :                     }
   10317      3846495 :                   if (chain[i].dt != vect_internal_def
   10318              :                       /* Avoid stmts where the def is not the LHS, like
   10319              :                          ASMs.  */
   10320      7320902 :                       || (gimple_get_lhs (bb_vinfo->lookup_def
   10321      3474407 :                                                       (chain[i].op)->stmt)
   10322      3474407 :                           != chain[i].op))
   10323       375184 :                     remain_cnt++;
   10324              :                 }
   10325      1811316 :               if (!invalid && chain.length () - remain_cnt > 1)
   10326              :                 {
   10327      1357493 :                   vec<stmt_vec_info> stmts;
   10328      1357493 :                   vec<tree> remain = vNULL;
   10329      1357493 :                   stmts.create (chain.length ());
   10330      1357493 :                   if (remain_cnt > 0)
   10331        52313 :                     remain.create (remain_cnt);
   10332      4526416 :                   for (unsigned i = 0; i < chain.length (); ++i)
   10333              :                     {
   10334      3168923 :                       stmt_vec_info stmt_info;
   10335      3168923 :                       if (chain[i].dt == vect_internal_def
   10336      3168923 :                           && ((stmt_info = bb_vinfo->lookup_def (chain[i].op)),
   10337      3062255 :                               gimple_get_lhs (stmt_info->stmt) == chain[i].op))
   10338      3062039 :                         stmts.quick_push (stmt_info);
   10339              :                       else
   10340       106884 :                         remain.quick_push (chain[i].op);
   10341              :                     }
   10342      1357493 :                   vec<stmt_vec_info> roots;
   10343      1357493 :                   roots.create (chain_stmts.length ());
   10344      4526416 :                   for (unsigned i = 0; i < chain_stmts.length (); ++i)
   10345      1811430 :                     roots.quick_push (bb_vinfo->lookup_stmt (chain_stmts[i]));
   10346      1357493 :                   bb_vinfo->roots.safe_push (slp_root (slp_inst_kind_bb_reduc,
   10347      1357493 :                                                        stmts, roots, remain));
   10348              :                 }
   10349              :             }
   10350      2211911 :         }
   10351              :     }
   10352      2349498 : }
   10353              : 
   10354              : /* Walk the grouped store chains and replace entries with their
   10355              :    pattern variant if any.  */
   10356              : 
   10357              : static void
   10358       678888 : vect_fixup_store_groups_with_patterns (vec_info *vinfo)
   10359              : {
   10360       678888 :   stmt_vec_info first_element;
   10361       678888 :   unsigned i;
   10362              : 
   10363      1597431 :   FOR_EACH_VEC_ELT (vinfo->grouped_stores, i, first_element)
   10364              :     {
   10365              :       /* We also have CTORs in this array.  */
   10366       918543 :       if (!STMT_VINFO_GROUPED_ACCESS (first_element))
   10367            0 :         continue;
   10368       918543 :       if (STMT_VINFO_IN_PATTERN_P (first_element))
   10369              :         {
   10370          255 :           stmt_vec_info orig = first_element;
   10371          255 :           first_element = STMT_VINFO_RELATED_STMT (first_element);
   10372          255 :           DR_GROUP_FIRST_ELEMENT (first_element) = first_element;
   10373          255 :           DR_GROUP_SIZE (first_element) = DR_GROUP_SIZE (orig);
   10374          255 :           DR_GROUP_GAP (first_element) = DR_GROUP_GAP (orig);
   10375          255 :           DR_GROUP_NEXT_ELEMENT (first_element) = DR_GROUP_NEXT_ELEMENT (orig);
   10376          255 :           vinfo->grouped_stores[i] = first_element;
   10377              :         }
   10378       918543 :       stmt_vec_info prev = first_element;
   10379      2582831 :       while (DR_GROUP_NEXT_ELEMENT (prev))
   10380              :         {
   10381      1664288 :           stmt_vec_info elt = DR_GROUP_NEXT_ELEMENT (prev);
   10382      1664288 :           if (STMT_VINFO_IN_PATTERN_P (elt))
   10383              :             {
   10384          870 :               stmt_vec_info orig = elt;
   10385          870 :               elt = STMT_VINFO_RELATED_STMT (elt);
   10386          870 :               DR_GROUP_NEXT_ELEMENT (prev) = elt;
   10387          870 :               DR_GROUP_GAP (elt) = DR_GROUP_GAP (orig);
   10388          870 :               DR_GROUP_NEXT_ELEMENT (elt) = DR_GROUP_NEXT_ELEMENT (orig);
   10389              :             }
   10390      1664288 :           DR_GROUP_FIRST_ELEMENT (elt) = first_element;
   10391      1664288 :           prev = elt;
   10392              :         }
   10393              :     }
   10394       678888 : }
   10395              : 
   10396              : /* Check if the region described by BB_VINFO can be vectorized, returning
   10397              :    true if so.  When returning false, set FATAL to true if the same failure
   10398              :    would prevent vectorization at other vector sizes, false if it is still
   10399              :    worth trying other sizes.  N_STMTS is the number of statements in the
   10400              :    region.  */
   10401              : 
   10402              : static bool
   10403      2349498 : vect_slp_analyze_bb_1 (bb_vec_info bb_vinfo, int n_stmts, bool &fatal,
   10404              :                        vec<int> *dataref_groups)
   10405              : {
   10406      2349498 :   DUMP_VECT_SCOPE ("vect_slp_analyze_bb");
   10407              : 
   10408      2349498 :   slp_instance instance;
   10409      2349498 :   int i;
   10410              : 
   10411              :   /* The first group of checks is independent of the vector size.  */
   10412      2349498 :   fatal = true;
   10413              : 
   10414              :   /* Analyze the data references.  */
   10415              : 
   10416      2349498 :   if (!vect_analyze_data_refs (bb_vinfo, NULL))
   10417              :     {
   10418            0 :       if (dump_enabled_p ())
   10419            0 :         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10420              :                          "not vectorized: unhandled data-ref in basic "
   10421              :                          "block.\n");
   10422              :       return false;
   10423              :     }
   10424              : 
   10425      2349498 :   if (!vect_analyze_data_ref_accesses (bb_vinfo, dataref_groups))
   10426              :     {
   10427            0 :      if (dump_enabled_p ())
   10428            0 :        dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10429              :                         "not vectorized: unhandled data access in "
   10430              :                         "basic block.\n");
   10431              :       return false;
   10432              :     }
   10433              : 
   10434      2349498 :   vect_slp_check_for_roots (bb_vinfo);
   10435              : 
   10436              :   /* If there are no grouped stores and no constructors in the region
   10437              :      there is no need to continue with pattern recog as vect_analyze_slp
   10438              :      will fail anyway.  */
   10439      2349498 :   if (bb_vinfo->grouped_stores.is_empty ()
   10440      1994518 :       && bb_vinfo->roots.is_empty ())
   10441              :     {
   10442      1670610 :       if (dump_enabled_p ())
   10443         1033 :         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10444              :                          "not vectorized: no grouped stores in "
   10445              :                          "basic block.\n");
   10446              :       return false;
   10447              :     }
   10448              : 
   10449              :   /* While the rest of the analysis below depends on it in some way.  */
   10450       678888 :   fatal = false;
   10451              : 
   10452       678888 :   vect_pattern_recog (bb_vinfo);
   10453              : 
   10454              :   /* Update store groups from pattern processing.  */
   10455       678888 :   vect_fixup_store_groups_with_patterns (bb_vinfo);
   10456              : 
   10457              :   /* Check the SLP opportunities in the basic block, analyze and build SLP
   10458              :      trees.  */
   10459       678888 :   if (!vect_analyze_slp (bb_vinfo, n_stmts, false))
   10460              :     {
   10461            0 :       if (dump_enabled_p ())
   10462              :         {
   10463            0 :           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10464              :                            "Failed to SLP the basic block.\n");
   10465            0 :           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10466              :                            "not vectorized: failed to find SLP opportunities "
   10467              :                            "in basic block.\n");
   10468              :         }
   10469              :       return false;
   10470              :     }
   10471              : 
   10472              :   /* Optimize permutations.  */
   10473       678888 :   vect_optimize_slp (bb_vinfo);
   10474              : 
   10475              :   /* Gather the loads reachable from the SLP graph entries.  */
   10476       678888 :   vect_gather_slp_loads (bb_vinfo);
   10477              : 
   10478       678888 :   vect_record_base_alignments (bb_vinfo);
   10479              : 
   10480              :   /* Analyze and verify the alignment of data references and the
   10481              :      dependence in the SLP instances.  */
   10482      2192197 :   for (i = 0; BB_VINFO_SLP_INSTANCES (bb_vinfo).iterate (i, &instance); )
   10483              :     {
   10484       834421 :       vect_location = instance->location ();
   10485       834421 :       if (! vect_slp_analyze_instance_alignment (bb_vinfo, instance)
   10486       834421 :           || ! vect_slp_analyze_instance_dependence (bb_vinfo, instance))
   10487              :         {
   10488         8985 :           slp_tree node = SLP_INSTANCE_TREE (instance);
   10489         8985 :           stmt_vec_info stmt_info = SLP_TREE_SCALAR_STMTS (node)[0];
   10490         8985 :           if (dump_enabled_p ())
   10491            4 :             dump_printf_loc (MSG_NOTE, vect_location,
   10492              :                              "removing SLP instance operations starting from: %G",
   10493              :                              stmt_info->stmt);
   10494         8985 :           vect_free_slp_instance (instance);
   10495         8985 :           BB_VINFO_SLP_INSTANCES (bb_vinfo).ordered_remove (i);
   10496         8985 :           continue;
   10497         8985 :         }
   10498              : 
   10499              :       /* Mark all the statements that we want to vectorize as relevant.  */
   10500       825436 :       vect_mark_slp_stmts_relevant (SLP_INSTANCE_TREE (instance));
   10501              : 
   10502       825436 :       i++;
   10503              :     }
   10504      2630606 :   if (! BB_VINFO_SLP_INSTANCES (bb_vinfo).length ())
   10505              :     return false;
   10506              : 
   10507       281108 :   if (!vect_slp_analyze_operations (bb_vinfo))
   10508              :     {
   10509        32487 :       if (dump_enabled_p ())
   10510           73 :         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10511              :                          "not vectorized: bad operation in basic block.\n");
   10512              :       return false;
   10513              :     }
   10514              : 
   10515              :   /* Compute vector stmt placement.  */
   10516       248621 :   if (!vect_schedule_slp (bb_vinfo, BB_VINFO_SLP_INSTANCES (bb_vinfo), true))
   10517              :     {
   10518            0 :       if (dump_enabled_p ())
   10519            0 :         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10520              :                          "not vectorized: cannot schedule SLP graph\n");
   10521              :       return false;
   10522              :     }
   10523              : 
   10524              :   /* Mark all the statements that we vectorize.  */
   10525       248621 :   vect_bb_slp_mark_stmts_vectorized (bb_vinfo);
   10526              : 
   10527              :   /* Compute vectorizable live stmts.  */
   10528       248621 :   vect_bb_slp_mark_live_stmts (bb_vinfo);
   10529              : 
   10530       248621 :   vect_bb_partition_graph (bb_vinfo);
   10531              : 
   10532       248621 :   return true;
   10533              : }
   10534              : 
   10535              : /* Subroutine of vect_slp_bb.  Try to vectorize the statements for all
   10536              :    basic blocks in BBS, returning true on success.
   10537              :    The region has N_STMTS statements and has the datarefs given by DATAREFS.  */
   10538              : 
   10539              : static bool
   10540      1981444 : vect_slp_region (vec<basic_block> bbs, vec<data_reference_p> datarefs,
   10541              :                  vec<int> *dataref_groups, unsigned int n_stmts,
   10542              :                  loop_p orig_loop)
   10543              : {
   10544      1981444 :   bb_vec_info bb_vinfo;
   10545      1981444 :   auto_vector_modes vector_modes;
   10546              : 
   10547              :   /* Autodetect first vector size we try.  */
   10548      1981444 :   machine_mode next_vector_mode = VOIDmode;
   10549      1981444 :   targetm.vectorize.autovectorize_vector_modes (&vector_modes, false);
   10550      1981444 :   unsigned int mode_i = 0;
   10551              : 
   10552      1981444 :   vec_info_shared shared;
   10553              : 
   10554      1981444 :   machine_mode autodetected_vector_mode = VOIDmode;
   10555      2717552 :   while (1)
   10556              :     {
   10557      2349498 :       bool vectorized = false;
   10558      2349498 :       bool fatal = false;
   10559      2349498 :       bb_vinfo = new _bb_vec_info (bbs, &shared);
   10560              : 
   10561      2349498 :       bool first_time_p = shared.datarefs.is_empty ();
   10562      2349498 :       BB_VINFO_DATAREFS (bb_vinfo) = datarefs;
   10563      2349498 :       if (first_time_p)
   10564      2006247 :         bb_vinfo->shared->save_datarefs ();
   10565              :       else
   10566       343251 :         bb_vinfo->shared->check_datarefs ();
   10567      2349498 :       bb_vinfo->vector_mode = next_vector_mode;
   10568              : 
   10569      2349498 :       if (vect_slp_analyze_bb_1 (bb_vinfo, n_stmts, fatal, dataref_groups))
   10570              :         {
   10571       248621 :           if (dump_enabled_p ())
   10572              :             {
   10573         1668 :               dump_printf_loc (MSG_NOTE, vect_location,
   10574              :                                "***** Analysis succeeded with vector mode"
   10575          834 :                                " %s\n", GET_MODE_NAME (bb_vinfo->vector_mode));
   10576          834 :               dump_printf_loc (MSG_NOTE, vect_location, "SLPing BB part\n");
   10577              :             }
   10578              : 
   10579       248621 :           bb_vinfo->shared->check_datarefs ();
   10580              : 
   10581       248621 :           bool force_clear = false;
   10582       248621 :           auto_vec<slp_instance> profitable_subgraphs;
   10583      1466595 :           for (slp_instance instance : BB_VINFO_SLP_INSTANCES (bb_vinfo))
   10584              :             {
   10585       720732 :               if (instance->subgraph_entries.is_empty ())
   10586       239384 :                 continue;
   10587              : 
   10588       693493 :               dump_user_location_t saved_vect_location = vect_location;
   10589       693493 :               vect_location = instance->location ();
   10590       693493 :               if (!unlimited_cost_model (NULL)
   10591       689499 :                   && !param_vect_allow_possibly_not_worthwhile_vectorizations
   10592      1382983 :                   && !vect_bb_vectorization_profitable_p
   10593       689490 :                         (bb_vinfo, instance->subgraph_entries, orig_loop))
   10594              :                 {
   10595       212145 :                   if (dump_enabled_p ())
   10596           51 :                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10597              :                                      "not vectorized: vectorization is not "
   10598              :                                      "profitable.\n");
   10599       212145 :                   vect_location = saved_vect_location;
   10600       212145 :                   continue;
   10601              :                 }
   10602              : 
   10603       481348 :               vect_location = saved_vect_location;
   10604       481348 :               if (!dbg_cnt (vect_slp))
   10605              :                 {
   10606            0 :                   force_clear = true;
   10607            0 :                   continue;
   10608              :                 }
   10609              : 
   10610       481348 :               profitable_subgraphs.safe_push (instance);
   10611              :             }
   10612              : 
   10613              :           /* When we're vectorizing an if-converted loop body make sure
   10614              :              we vectorized all if-converted code.  */
   10615       406293 :           if ((!profitable_subgraphs.is_empty () || force_clear) && orig_loop)
   10616              :             {
   10617          126 :               gcc_assert (bb_vinfo->nbbs == 1);
   10618          252 :               for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[0]);
   10619         5753 :                    !gsi_end_p (gsi); gsi_next (&gsi))
   10620              :                 {
   10621              :                   /* The costing above left us with DCEable vectorized scalar
   10622              :                      stmts having the visited flag set on profitable
   10623              :                      subgraphs.  Do the delayed clearing of the flag here.  */
   10624         5627 :                   if (gimple_visited_p (gsi_stmt (gsi)))
   10625              :                     {
   10626         1816 :                       gimple_set_visited (gsi_stmt (gsi), false);
   10627         1816 :                       continue;
   10628              :                     }
   10629         3811 :                   if (flag_vect_cost_model == VECT_COST_MODEL_UNLIMITED)
   10630          813 :                     continue;
   10631              : 
   10632         8370 :                   if (gassign *ass = dyn_cast <gassign *> (gsi_stmt (gsi)))
   10633         3456 :                     if (gimple_assign_rhs_code (ass) == COND_EXPR)
   10634              :                       {
   10635          151 :                         if (!profitable_subgraphs.is_empty ()
   10636           66 :                             && dump_enabled_p ())
   10637            0 :                           dump_printf_loc (MSG_NOTE, vect_location,
   10638              :                                            "not profitable because of "
   10639              :                                            "unprofitable if-converted scalar "
   10640              :                                            "code\n");
   10641           85 :                         profitable_subgraphs.truncate (0);
   10642              :                       }
   10643              :                 }
   10644              :             }
   10645              : 
   10646              :           /* Finally schedule the profitable subgraphs.  */
   10647      1045230 :           for (slp_instance instance : profitable_subgraphs)
   10648              :             {
   10649       481265 :               if (!vectorized && dump_enabled_p ())
   10650          795 :                 dump_printf_loc (MSG_NOTE, vect_location,
   10651              :                                  "Basic block will be vectorized "
   10652              :                                  "using SLP\n");
   10653       481265 :               vectorized = true;
   10654              : 
   10655              :               /* Dump before scheduling as store vectorization will remove
   10656              :                  the original stores and mess with the instance tree
   10657              :                  so querying its location will eventually ICE.  */
   10658       481265 :               if (flag_checking)
   10659      1936317 :                 for (slp_instance sub : instance->subgraph_entries)
   10660       492522 :                   gcc_assert (SLP_TREE_VECTYPE (SLP_INSTANCE_TREE (sub)));
   10661       481265 :               unsigned HOST_WIDE_INT bytes;
   10662       481265 :               if (dump_enabled_p ())
   10663         3863 :                 for (slp_instance sub : instance->subgraph_entries)
   10664              :                   {
   10665         1040 :                     tree vtype = SLP_TREE_VECTYPE (SLP_INSTANCE_TREE (sub));
   10666         2080 :                     if (GET_MODE_SIZE (TYPE_MODE (vtype)).is_constant (&bytes))
   10667         1040 :                       dump_printf_loc (MSG_OPTIMIZED_LOCATIONS,
   10668         1040 :                                        sub->location (),
   10669              :                                        "basic block part vectorized using %wu "
   10670              :                                        "byte vectors\n", bytes);
   10671              :                     else
   10672              :                       dump_printf_loc (MSG_OPTIMIZED_LOCATIONS,
   10673              :                                        sub->location (),
   10674              :                                        "basic block part vectorized using "
   10675              :                                        "variable length vectors\n");
   10676              :                   }
   10677              : 
   10678       481265 :               dump_user_location_t saved_vect_location = vect_location;
   10679       481265 :               vect_location = instance->location ();
   10680              : 
   10681       481265 :               vect_schedule_slp (bb_vinfo, instance->subgraph_entries, false);
   10682              : 
   10683       481265 :               vect_location = saved_vect_location;
   10684              :             }
   10685              : 
   10686              :           /* Generate the invariant statements.  */
   10687       248621 :           if (!gimple_seq_empty_p (bb_vinfo->inv_pattern_def_seq))
   10688              :             {
   10689           23 :               if (dump_enabled_p ())
   10690            0 :                 dump_printf_loc (MSG_NOTE, vect_location,
   10691              :                          "------>generating invariant statements\n");
   10692              : 
   10693           23 :               bb_vinfo->insert_seq_on_entry (NULL,
   10694              :                                              bb_vinfo->inv_pattern_def_seq);
   10695              :             }
   10696       248621 :         }
   10697              :       else
   10698              :         {
   10699      2100877 :           if (dump_enabled_p ())
   10700         1355 :             dump_printf_loc (MSG_NOTE, vect_location,
   10701              :                              "***** Analysis failed with vector mode %s\n",
   10702         1355 :                              GET_MODE_NAME (bb_vinfo->vector_mode));
   10703              :         }
   10704              : 
   10705      2349498 :       if (mode_i == 0)
   10706      1981444 :         autodetected_vector_mode = bb_vinfo->vector_mode;
   10707              : 
   10708      2349498 :       if (!fatal)
   10709      3386355 :         while (mode_i < vector_modes.length ()
   10710      1920442 :                && vect_chooses_same_modes_p (bb_vinfo, vector_modes[mode_i]))
   10711              :           {
   10712       357969 :             if (dump_enabled_p ())
   10713         1818 :               dump_printf_loc (MSG_NOTE, vect_location,
   10714              :                                "***** The result for vector mode %s would"
   10715              :                                " be the same\n",
   10716          909 :                                GET_MODE_NAME (vector_modes[mode_i]));
   10717       357969 :             mode_i += 1;
   10718              :           }
   10719              : 
   10720      2349498 :       delete bb_vinfo;
   10721              : 
   10722      2349498 :       if (mode_i < vector_modes.length ()
   10723      2147676 :           && VECTOR_MODE_P (autodetected_vector_mode)
   10724      2120578 :           && (related_vector_mode (vector_modes[mode_i],
   10725              :                                    GET_MODE_INNER (autodetected_vector_mode))
   10726      1060289 :               == autodetected_vector_mode)
   10727      4497174 :           && (related_vector_mode (autodetected_vector_mode,
   10728       534527 :                                    GET_MODE_INNER (vector_modes[mode_i]))
   10729      1069054 :               == vector_modes[mode_i]))
   10730              :         {
   10731       534527 :           if (dump_enabled_p ())
   10732          214 :             dump_printf_loc (MSG_NOTE, vect_location,
   10733              :                              "***** Skipping vector mode %s, which would"
   10734              :                              " repeat the analysis for %s\n",
   10735          214 :                              GET_MODE_NAME (vector_modes[mode_i]),
   10736          214 :                              GET_MODE_NAME (autodetected_vector_mode));
   10737       534527 :           mode_i += 1;
   10738              :         }
   10739              : 
   10740      2349498 :       if (vectorized
   10741      2191892 :           || mode_i == vector_modes.length ()
   10742      1990114 :           || autodetected_vector_mode == VOIDmode
   10743              :           /* If vect_slp_analyze_bb_1 signaled that analysis for all
   10744              :              vector sizes will fail do not bother iterating.  */
   10745      3252225 :           || fatal)
   10746      3962888 :         return vectorized;
   10747              : 
   10748              :       /* Try the next biggest vector size.  */
   10749       368054 :       next_vector_mode = vector_modes[mode_i++];
   10750       368054 :       if (dump_enabled_p ())
   10751          249 :         dump_printf_loc (MSG_NOTE, vect_location,
   10752              :                          "***** Re-trying analysis with vector mode %s\n",
   10753          249 :                          GET_MODE_NAME (next_vector_mode));
   10754       368054 :     }
   10755      1981444 : }
   10756              : 
   10757              : 
   10758              : /* Main entry for the BB vectorizer.  Analyze and transform BBS, returns
   10759              :    true if anything in the basic-block was vectorized.  */
   10760              : 
   10761              : static bool
   10762      1981444 : vect_slp_bbs (const vec<basic_block> &bbs, loop_p orig_loop)
   10763              : {
   10764      1981444 :   vec<data_reference_p> datarefs = vNULL;
   10765      1981444 :   auto_vec<int> dataref_groups;
   10766      1981444 :   int insns = 0;
   10767      1981444 :   int current_group = 0;
   10768              : 
   10769     13057665 :   for (unsigned i = 0; i < bbs.length (); i++)
   10770              :     {
   10771     11076221 :       basic_block bb = bbs[i];
   10772     97426602 :       for (gimple_stmt_iterator gsi = gsi_after_labels (bb); !gsi_end_p (gsi);
   10773     86350381 :            gsi_next (&gsi))
   10774              :         {
   10775     86350381 :           gimple *stmt = gsi_stmt (gsi);
   10776     86350381 :           if (is_gimple_debug (stmt))
   10777     55252149 :             continue;
   10778              : 
   10779     31098232 :           insns++;
   10780              : 
   10781     31098232 :           if (gimple_location (stmt) != UNKNOWN_LOCATION)
   10782     27884561 :             vect_location = stmt;
   10783              : 
   10784     31098232 :           if (!vect_find_stmt_data_reference (NULL, stmt, &datarefs,
   10785              :                                               &dataref_groups, current_group))
   10786      5332846 :             ++current_group;
   10787              :         }
   10788              :       /* New BBs always start a new DR group.  */
   10789     11076221 :       ++current_group;
   10790              :     }
   10791              : 
   10792      1981444 :   return vect_slp_region (bbs, datarefs, &dataref_groups, insns, orig_loop);
   10793      1981444 : }
   10794              : 
   10795              : /* Special entry for the BB vectorizer.  Analyze and transform a single
   10796              :    if-converted BB with ORIG_LOOPs body being the not if-converted
   10797              :    representation.  Returns true if anything in the basic-block was
   10798              :    vectorized.  */
   10799              : 
   10800              : bool
   10801        16796 : vect_slp_if_converted_bb (basic_block bb, loop_p orig_loop)
   10802              : {
   10803        16796 :   auto_vec<basic_block> bbs;
   10804        16796 :   bbs.safe_push (bb);
   10805        16796 :   return vect_slp_bbs (bbs, orig_loop);
   10806        16796 : }
   10807              : 
   10808              : /* Main entry for the BB vectorizer.  Analyze and transform BB, returns
   10809              :    true if anything in the basic-block was vectorized.  */
   10810              : 
   10811              : bool
   10812       932281 : vect_slp_function (function *fun)
   10813              : {
   10814       932281 :   bool r = false;
   10815       932281 :   int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
   10816       932281 :   auto_bitmap exit_bbs;
   10817       932281 :   bitmap_set_bit (exit_bbs, EXIT_BLOCK);
   10818       932281 :   edge entry = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (fun));
   10819       932281 :   unsigned n = rev_post_order_and_mark_dfs_back_seme (fun, entry, exit_bbs,
   10820       932281 :                                                       true, rpo, NULL);
   10821              : 
   10822              :   /* For the moment split the function into pieces to avoid making
   10823              :      the iteration on the vector mode moot.  Split at points we know
   10824              :      to not handle well which is CFG merges (SLP discovery doesn't
   10825              :      handle non-loop-header PHIs) and loop exits.  Since pattern
   10826              :      recog requires reverse iteration to visit uses before defs
   10827              :      simply chop RPO into pieces.  */
   10828       932281 :   auto_vec<basic_block> bbs;
   10829     12018123 :   for (unsigned i = 0; i < n; i++)
   10830              :     {
   10831     11085842 :       basic_block bb = BASIC_BLOCK_FOR_FN (fun, rpo[i]);
   10832     11085842 :       bool split = false;
   10833              : 
   10834              :       /* Split when a BB is not dominated by the first block.  */
   10835     20916328 :       if (!bbs.is_empty ()
   10836      9830486 :           && !dominated_by_p (CDI_DOMINATORS, bb, bbs[0]))
   10837              :         {
   10838       725651 :           if (dump_enabled_p ())
   10839          146 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10840              :                              "splitting region at dominance boundary bb%d\n",
   10841              :                              bb->index);
   10842              :           split = true;
   10843              :         }
   10844              :       /* Split when the loop determined by the first block
   10845              :          is exited.  This is because we eventually insert
   10846              :          invariants at region begin.  */
   10847     19465026 :       else if (!bbs.is_empty ()
   10848      9104835 :                && bbs[0]->loop_father != bb->loop_father
   10849      2366736 :                && !flow_loop_nested_p (bbs[0]->loop_father, bb->loop_father))
   10850              :         {
   10851         3868 :           if (dump_enabled_p ())
   10852            3 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10853              :                              "splitting region at loop %d exit at bb%d\n",
   10854            3 :                              bbs[0]->loop_father->num, bb->index);
   10855              :           split = true;
   10856              :         }
   10857     10356323 :       else if (!bbs.is_empty ()
   10858      9100967 :                && bb->loop_father->header == bb
   10859       482291 :                && bb->loop_father->dont_vectorize)
   10860              :         {
   10861         6190 :           if (dump_enabled_p ())
   10862           72 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10863              :                              "splitting region at dont-vectorize loop %d "
   10864              :                              "entry at bb%d\n",
   10865              :                              bb->loop_father->num, bb->index);
   10866              :           split = true;
   10867              :         }
   10868              : 
   10869          221 :       if (split && !bbs.is_empty ())
   10870              :         {
   10871       735709 :           r |= vect_slp_bbs (bbs, NULL);
   10872       735709 :           bbs.truncate (0);
   10873              :         }
   10874              : 
   10875     11085842 :       if (bbs.is_empty ())
   10876              :         {
   10877              :           /* We need to be able to insert at the head of the region which
   10878              :              we cannot for region starting with a returns-twice call.  */
   10879      1991065 :           if (gcall *first = safe_dyn_cast <gcall *> (first_stmt (bb)))
   10880       423512 :             if (gimple_call_flags (first) & ECF_RETURNS_TWICE)
   10881              :               {
   10882          306 :                 if (dump_enabled_p ())
   10883            2 :                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10884              :                                    "skipping bb%d as start of region as it "
   10885              :                                    "starts with returns-twice call\n",
   10886              :                                    bb->index);
   10887        26417 :                 continue;
   10888              :               }
   10889              :           /* If the loop this BB belongs to is marked as not to be vectorized
   10890              :              honor that also for BB vectorization.  */
   10891      1990759 :           if (bb->loop_father->dont_vectorize)
   10892        26111 :             continue;
   10893              :         }
   10894              : 
   10895     11059425 :       bbs.safe_push (bb);
   10896              : 
   10897              :       /* When we have a stmt ending this block and defining a
   10898              :          value we have to insert on edges when inserting after it for
   10899              :          a vector containing its definition.  Avoid this for now.  */
   10900     22118850 :       if (gimple *last = *gsi_last_bb (bb))
   10901      9012996 :         if (gimple_get_lhs (last)
   10902      9012996 :             && is_ctrl_altering_stmt (last))
   10903              :           {
   10904       296665 :             if (dump_enabled_p ())
   10905            2 :               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   10906              :                                "splitting region at control altering "
   10907              :                                "definition %G", last);
   10908       296665 :             r |= vect_slp_bbs (bbs, NULL);
   10909       296665 :             bbs.truncate (0);
   10910              :           }
   10911              :     }
   10912              : 
   10913       932281 :   if (!bbs.is_empty ())
   10914       932274 :     r |= vect_slp_bbs (bbs, NULL);
   10915              : 
   10916       932281 :   free (rpo);
   10917              : 
   10918       932281 :   return r;
   10919       932281 : }
   10920              : 
   10921              : /* Build a variable-length vector in which the elements in ELTS are repeated
   10922              :    to a fill NRESULTS vectors of type VECTOR_TYPE.  Store the vectors in
   10923              :    RESULTS and add any new instructions to SEQ.
   10924              : 
   10925              :    The approach we use is:
   10926              : 
   10927              :    (1) Find a vector mode VM with integer elements of mode IM.
   10928              : 
   10929              :    (2) Replace ELTS[0:NELTS] with ELTS'[0:NELTS'], where each element of
   10930              :        ELTS' has mode IM.  This involves creating NELTS' VIEW_CONVERT_EXPRs
   10931              :        from small vectors to IM.
   10932              : 
   10933              :    (3) Duplicate each ELTS'[I] into a vector of mode VM.
   10934              : 
   10935              :    (4) Use a tree of interleaving VEC_PERM_EXPRs to create VMs with the
   10936              :        correct byte contents.
   10937              : 
   10938              :    (5) Use VIEW_CONVERT_EXPR to cast the final VMs to the required type.
   10939              : 
   10940              :    We try to find the largest IM for which this sequence works, in order
   10941              :    to cut down on the number of interleaves.  */
   10942              : 
   10943              : void
   10944            0 : duplicate_and_interleave (vec_info *vinfo, gimple_seq *seq, tree vector_type,
   10945              :                           const vec<tree> &elts, unsigned int nresults,
   10946              :                           vec<tree> &results)
   10947              : {
   10948            0 :   unsigned int nelts = elts.length ();
   10949            0 :   tree element_type = TREE_TYPE (vector_type);
   10950              : 
   10951              :   /* (1) Find a vector mode VM with integer elements of mode IM.  */
   10952            0 :   unsigned int nvectors = 1;
   10953            0 :   tree new_vector_type;
   10954            0 :   tree permutes[2];
   10955            0 :   if (!can_duplicate_and_interleave_p (vinfo, nelts, element_type,
   10956              :                                        &nvectors, &new_vector_type,
   10957              :                                        permutes))
   10958            0 :     gcc_unreachable ();
   10959              : 
   10960              :   /* Get a vector type that holds ELTS[0:NELTS/NELTS'].  */
   10961            0 :   unsigned int partial_nelts = nelts / nvectors;
   10962            0 :   tree partial_vector_type = build_vector_type (element_type, partial_nelts);
   10963              : 
   10964            0 :   tree_vector_builder partial_elts;
   10965            0 :   auto_vec<tree, 32> pieces (nvectors * 2);
   10966            0 :   pieces.quick_grow_cleared (nvectors * 2);
   10967            0 :   for (unsigned int i = 0; i < nvectors; ++i)
   10968              :     {
   10969              :       /* (2) Replace ELTS[0:NELTS] with ELTS'[0:NELTS'], where each element of
   10970              :              ELTS' has mode IM.  */
   10971            0 :       partial_elts.new_vector (partial_vector_type, partial_nelts, 1);
   10972            0 :       for (unsigned int j = 0; j < partial_nelts; ++j)
   10973            0 :         partial_elts.quick_push (elts[i * partial_nelts + j]);
   10974            0 :       tree t = gimple_build_vector (seq, &partial_elts);
   10975            0 :       t = gimple_build (seq, VIEW_CONVERT_EXPR,
   10976            0 :                         TREE_TYPE (new_vector_type), t);
   10977              : 
   10978              :       /* (3) Duplicate each ELTS'[I] into a vector of mode VM.  */
   10979            0 :       pieces[i] = gimple_build_vector_from_val (seq, new_vector_type, t);
   10980              :     }
   10981              : 
   10982              :   /* (4) Use a tree of VEC_PERM_EXPRs to create a single VM with the
   10983              :          correct byte contents.
   10984              : 
   10985              :      Conceptually, we need to repeat the following operation log2(nvectors)
   10986              :      times, where hi_start = nvectors / 2:
   10987              : 
   10988              :         out[i * 2] = VEC_PERM_EXPR (in[i], in[i + hi_start], lo_permute);
   10989              :         out[i * 2 + 1] = VEC_PERM_EXPR (in[i], in[i + hi_start], hi_permute);
   10990              : 
   10991              :      However, if each input repeats every N elements and the VF is
   10992              :      a multiple of N * 2, the HI result is the same as the LO result.
   10993              :      This will be true for the first N1 iterations of the outer loop,
   10994              :      followed by N2 iterations for which both the LO and HI results
   10995              :      are needed.  I.e.:
   10996              : 
   10997              :         N1 + N2 = log2(nvectors)
   10998              : 
   10999              :      Each "N1 iteration" doubles the number of redundant vectors and the
   11000              :      effect of the process as a whole is to have a sequence of nvectors/2**N1
   11001              :      vectors that repeats 2**N1 times.  Rather than generate these redundant
   11002              :      vectors, we halve the number of vectors for each N1 iteration.  */
   11003              :   unsigned int in_start = 0;
   11004              :   unsigned int out_start = nvectors;
   11005              :   unsigned int new_nvectors = nvectors;
   11006            0 :   for (unsigned int in_repeat = 1; in_repeat < nvectors; in_repeat *= 2)
   11007              :     {
   11008            0 :       unsigned int hi_start = new_nvectors / 2;
   11009            0 :       unsigned int out_i = 0;
   11010            0 :       for (unsigned int in_i = 0; in_i < new_nvectors; ++in_i)
   11011              :         {
   11012            0 :           if ((in_i & 1) != 0
   11013            0 :               && multiple_p (TYPE_VECTOR_SUBPARTS (new_vector_type),
   11014              :                              2 * in_repeat))
   11015            0 :             continue;
   11016              : 
   11017            0 :           tree output = make_ssa_name (new_vector_type);
   11018            0 :           tree input1 = pieces[in_start + (in_i / 2)];
   11019            0 :           tree input2 = pieces[in_start + (in_i / 2) + hi_start];
   11020            0 :           gassign *stmt = gimple_build_assign (output, VEC_PERM_EXPR,
   11021              :                                                input1, input2,
   11022              :                                                permutes[in_i & 1]);
   11023            0 :           gimple_seq_add_stmt (seq, stmt);
   11024            0 :           pieces[out_start + out_i] = output;
   11025            0 :           out_i += 1;
   11026              :         }
   11027            0 :       std::swap (in_start, out_start);
   11028            0 :       new_nvectors = out_i;
   11029              :     }
   11030              : 
   11031              :   /* (5) Use VIEW_CONVERT_EXPR to cast the final VM to the required type.  */
   11032            0 :   results.reserve (nresults);
   11033            0 :   for (unsigned int i = 0; i < nresults; ++i)
   11034            0 :     if (i < new_nvectors)
   11035            0 :       results.quick_push (gimple_build (seq, VIEW_CONVERT_EXPR, vector_type,
   11036            0 :                                         pieces[in_start + i]));
   11037              :     else
   11038            0 :       results.quick_push (results[i - new_nvectors]);
   11039            0 : }
   11040              : 
   11041              : 
   11042              : /* For constant and loop invariant defs in OP_NODE this function creates
   11043              :    vector defs that will be used in the vectorized stmts and stores them
   11044              :    to SLP_TREE_VEC_DEFS of OP_NODE.  */
   11045              : 
   11046              : static void
   11047       504199 : vect_create_constant_vectors (vec_info *vinfo, slp_tree op_node)
   11048              : {
   11049       504199 :   unsigned HOST_WIDE_INT nunits;
   11050       504199 :   tree vec_cst;
   11051       504199 :   unsigned j, number_of_places_left_in_vector;
   11052       504199 :   tree vector_type;
   11053       504199 :   tree vop;
   11054       504199 :   int group_size = op_node->ops.length ();
   11055       504199 :   unsigned int vec_num, i;
   11056       504199 :   unsigned number_of_copies = 1;
   11057       504199 :   bool constant_p;
   11058       504199 :   gimple_seq ctor_seq = NULL;
   11059       504199 :   auto_vec<tree, 16> permute_results;
   11060              : 
   11061              :   /* We always want SLP_TREE_VECTYPE (op_node) here correctly set.  */
   11062       504199 :   vector_type = SLP_TREE_VECTYPE (op_node);
   11063              : 
   11064       504199 :   unsigned int number_of_vectors, excess_elts;
   11065       504199 :   bool res = vect_get_num_copies_for_invariant (vinfo, op_node,
   11066              :                                                 &number_of_vectors,
   11067              :                                                 &excess_elts);
   11068       504199 :   gcc_assert (res);
   11069       504199 :   SLP_TREE_VEC_DEFS (op_node).create (number_of_vectors);
   11070       504199 :   auto_vec<tree> voprnds (number_of_vectors);
   11071              : 
   11072              :   /* NUMBER_OF_COPIES is the number of times we need to use the same values in
   11073              :      created vectors. It is greater than 1 if unrolling is performed.
   11074              : 
   11075              :      For example, we have two scalar operands, s1 and s2 (e.g., group of
   11076              :      strided accesses of size two), while NUNITS is four (i.e., four scalars
   11077              :      of this type can be packed in a vector).  The output vector will contain
   11078              :      two copies of each scalar operand: {s1, s2, s1, s2}.  (NUMBER_OF_COPIES
   11079              :      will be 2).
   11080              : 
   11081              :      If GROUP_SIZE > NUNITS, the scalars will be split into several vectors
   11082              :      containing the operands.
   11083              : 
   11084              :      For example, NUNITS is four as before, and the group size is 8
   11085              :      (s1, s2, ..., s8).  We will create two vectors {s1, s2, s3, s4} and
   11086              :      {s5, s6, s7, s8}.  */
   11087              : 
   11088              :   /* When using duplicate_and_interleave, we just need one element for
   11089              :      each scalar statement.  */
   11090       504199 :   if (!TYPE_VECTOR_SUBPARTS (vector_type).is_constant (&nunits))
   11091              :     nunits = group_size;
   11092              : 
   11093       504199 :   number_of_copies = (nunits * number_of_vectors - excess_elts) / group_size;
   11094              : 
   11095       504199 :   constant_p = true;
   11096       504199 :   tree uniform_elt = NULL_TREE;
   11097       504199 :   tree_vector_builder elts (vector_type, nunits, 1);
   11098       504199 :   elts.quick_grow (nunits);
   11099              :   /* Zero-pad the last vector if necessary.  */
   11100       504199 :   number_of_places_left_in_vector = nunits - excess_elts;
   11101       504457 :   for (i = nunits; i > number_of_places_left_in_vector; --i)
   11102          258 :     elts[i-1] = build_zero_cst (TREE_TYPE (vector_type));
   11103              :   stmt_vec_info insert_after = NULL;
   11104      1504962 :   for (j = 0; j < number_of_copies; j++)
   11105              :     {
   11106      1000763 :       tree op;
   11107      3832161 :       for (i = group_size - 1; op_node->ops.iterate (i, &op); i--)
   11108              :         {
   11109              :           /* Create 'vect_ = {op0,op1,...,opn}'.  */
   11110      1830635 :           tree orig_op = op;
   11111      1830635 :           if (number_of_places_left_in_vector == nunits)
   11112              :             uniform_elt = op;
   11113      1192590 :           else if (uniform_elt && operand_equal_p (uniform_elt, op))
   11114       757583 :             op = elts[number_of_places_left_in_vector];
   11115              :           else
   11116              :             uniform_elt = NULL_TREE;
   11117      1830635 :           number_of_places_left_in_vector--;
   11118      1830635 :           if (!types_compatible_p (TREE_TYPE (vector_type), TREE_TYPE (op)))
   11119              :             {
   11120       280329 :               if (CONSTANT_CLASS_P (op))
   11121              :                 {
   11122       101703 :                   if (VECTOR_BOOLEAN_TYPE_P (vector_type))
   11123              :                     {
   11124              :                       /* Can't use VIEW_CONVERT_EXPR for booleans because
   11125              :                          of possibly different sizes of scalar value and
   11126              :                          vector element.  */
   11127           66 :                       if (integer_zerop (op))
   11128           66 :                         op = build_int_cst (TREE_TYPE (vector_type), 0);
   11129            0 :                       else if (integer_onep (op))
   11130            0 :                         op = build_all_ones_cst (TREE_TYPE (vector_type));
   11131              :                       else
   11132            0 :                         gcc_unreachable ();
   11133              :                     }
   11134              :                   else
   11135       101637 :                     op = fold_unary (VIEW_CONVERT_EXPR,
   11136              :                                      TREE_TYPE (vector_type), op);
   11137       101703 :                   gcc_assert (op && CONSTANT_CLASS_P (op));
   11138              :                 }
   11139              :               else
   11140              :                 {
   11141       178626 :                   tree new_temp = make_ssa_name (TREE_TYPE (vector_type));
   11142       178626 :                   gimple *init_stmt;
   11143       178626 :                   if (VECTOR_BOOLEAN_TYPE_P (vector_type))
   11144              :                     {
   11145          427 :                       tree true_val
   11146          427 :                         = build_all_ones_cst (TREE_TYPE (vector_type));
   11147          427 :                       tree false_val
   11148          427 :                         = build_zero_cst (TREE_TYPE (vector_type));
   11149          427 :                       gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (op)));
   11150          427 :                       init_stmt = gimple_build_assign (new_temp, COND_EXPR,
   11151              :                                                        op, true_val,
   11152              :                                                        false_val);
   11153              :                     }
   11154              :                   else
   11155              :                     {
   11156       178199 :                       op = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (vector_type),
   11157              :                                    op);
   11158       178199 :                       init_stmt
   11159       178199 :                         = gimple_build_assign (new_temp, VIEW_CONVERT_EXPR,
   11160              :                                                op);
   11161              :                     }
   11162       178626 :                   gimple_seq_add_stmt (&ctor_seq, init_stmt);
   11163       178626 :                   op = new_temp;
   11164              :                 }
   11165              :             }
   11166      1830635 :           elts[number_of_places_left_in_vector] = op;
   11167      1830635 :           if (!CONSTANT_CLASS_P (op))
   11168       322846 :             constant_p = false;
   11169              :           /* For BB vectorization we have to compute an insert location
   11170              :              when a def is inside the analyzed region since we cannot
   11171              :              simply insert at the BB start in this case.  */
   11172      1830635 :           stmt_vec_info opdef;
   11173      1830635 :           if (TREE_CODE (orig_op) == SSA_NAME
   11174       184966 :               && !SSA_NAME_IS_DEFAULT_DEF (orig_op)
   11175       164402 :               && is_a <bb_vec_info> (vinfo)
   11176      1937040 :               && (opdef = vinfo->lookup_def (orig_op)))
   11177              :             {
   11178        86282 :               if (!insert_after)
   11179              :                 insert_after = opdef;
   11180              :               else
   11181        47573 :                 insert_after = get_later_stmt (insert_after, opdef);
   11182              :             }
   11183              : 
   11184      1830635 :           if (number_of_places_left_in_vector == 0)
   11185              :             {
   11186       638074 :               auto type_nunits = TYPE_VECTOR_SUBPARTS (vector_type);
   11187       638074 :               if (uniform_elt)
   11188       664244 :                 vec_cst = gimple_build_vector_from_val (&ctor_seq, vector_type,
   11189       332122 :                                                         elts[0]);
   11190       611904 :               else if (constant_p
   11191       611904 :                        ? multiple_p (type_nunits, nunits)
   11192       111991 :                        : known_eq (type_nunits, nunits))
   11193       305952 :                 vec_cst = gimple_build_vector (&ctor_seq, &elts);
   11194              :               else
   11195              :                 {
   11196            0 :                   if (permute_results.is_empty ())
   11197            0 :                     duplicate_and_interleave (vinfo, &ctor_seq, vector_type,
   11198              :                                               elts, number_of_vectors,
   11199              :                                               permute_results);
   11200            0 :                   vec_cst = permute_results[number_of_vectors - j - 1];
   11201              :                 }
   11202       638074 :               if (!gimple_seq_empty_p (ctor_seq))
   11203              :                 {
   11204       139827 :                   if (insert_after)
   11205              :                     {
   11206        38709 :                       gimple_stmt_iterator gsi;
   11207        38709 :                       if (gimple_code (insert_after->stmt) == GIMPLE_PHI)
   11208              :                         {
   11209          618 :                           gsi = gsi_after_labels (gimple_bb (insert_after->stmt));
   11210          618 :                           gsi_insert_seq_before (&gsi, ctor_seq,
   11211              :                                                  GSI_CONTINUE_LINKING);
   11212              :                         }
   11213        38091 :                       else if (!stmt_ends_bb_p (insert_after->stmt))
   11214              :                         {
   11215        38091 :                           gsi = gsi_for_stmt (insert_after->stmt);
   11216        38091 :                           gsi_insert_seq_after (&gsi, ctor_seq,
   11217              :                                                 GSI_CONTINUE_LINKING);
   11218              :                         }
   11219              :                       else
   11220              :                         {
   11221              :                           /* When we want to insert after a def where the
   11222              :                              defining stmt throws then insert on the fallthru
   11223              :                              edge.  */
   11224            0 :                           edge e = find_fallthru_edge
   11225            0 :                                      (gimple_bb (insert_after->stmt)->succs);
   11226            0 :                           basic_block new_bb
   11227            0 :                             = gsi_insert_seq_on_edge_immediate (e, ctor_seq);
   11228            0 :                           gcc_assert (!new_bb);
   11229              :                         }
   11230              :                     }
   11231              :                   else
   11232       101118 :                     vinfo->insert_seq_on_entry (NULL, ctor_seq);
   11233       139827 :                   ctor_seq = NULL;
   11234              :                 }
   11235       638074 :               voprnds.quick_push (vec_cst);
   11236       638074 :               insert_after = NULL;
   11237       638074 :               number_of_places_left_in_vector = nunits;
   11238       638074 :               constant_p = true;
   11239       638074 :               elts.new_vector (vector_type, nunits, 1);
   11240       638074 :               elts.quick_grow (nunits);
   11241              :             }
   11242              :         }
   11243              :     }
   11244              : 
   11245       504199 :   gcc_assert (number_of_places_left_in_vector == nunits);
   11246              : 
   11247              :   /* Since the vectors are created in the reverse order, we should invert
   11248              :      them.  */
   11249       504199 :   vec_num = voprnds.length ();
   11250       504199 :   gcc_checking_assert (vec_num > 0);
   11251              : 
   11252      1142273 :   for (j = vec_num; j != 0; j--)
   11253              :     {
   11254       638074 :       vop = voprnds[j - 1];
   11255       638074 :       SLP_TREE_VEC_DEFS (op_node).quick_push (vop);
   11256              :     }
   11257              : 
   11258              :   /* In case that VF is greater than the unrolling factor needed for the SLP
   11259              :      group of stmts, NUMBER_OF_VECTORS to be created is greater than
   11260              :      NUMBER_OF_SCALARS/NUNITS or NUNITS/NUMBER_OF_SCALARS, and hence we have
   11261              :      to replicate the vectors.  */
   11262      1008398 :   while (number_of_vectors > SLP_TREE_VEC_DEFS (op_node).length ())
   11263            0 :     for (i = 0; SLP_TREE_VEC_DEFS (op_node).iterate (i, &vop) && i < vec_num;
   11264              :          i++)
   11265            0 :       SLP_TREE_VEC_DEFS (op_node).quick_push (vop);
   11266       504199 : }
   11267              : 
   11268              : /* Get the scalar definition of the Nth lane from SLP_NODE or NULL_TREE
   11269              :    if there is no definition for it in the scalar IL or it is not known.  */
   11270              : 
   11271              : tree
   11272        73612 : vect_get_slp_scalar_def (slp_tree slp_node, unsigned n)
   11273              : {
   11274        73612 :   if (SLP_TREE_DEF_TYPE (slp_node) == vect_internal_def)
   11275              :     {
   11276         2693 :       if (!SLP_TREE_SCALAR_STMTS (slp_node).exists ())
   11277              :         return NULL_TREE;
   11278         2693 :       stmt_vec_info def = SLP_TREE_SCALAR_STMTS (slp_node)[n];
   11279         2693 :       if (!def)
   11280              :         return NULL_TREE;
   11281         2693 :       return gimple_get_lhs (STMT_VINFO_STMT (def));
   11282              :     }
   11283              :   else
   11284        70919 :     return SLP_TREE_SCALAR_OPS (slp_node)[n];
   11285              : }
   11286              : 
   11287              : /* Get the Ith vectorized definition from SLP_NODE.  */
   11288              : 
   11289              : tree
   11290       141725 : vect_get_slp_vect_def (slp_tree slp_node, unsigned i)
   11291              : {
   11292       141725 :   return SLP_TREE_VEC_DEFS (slp_node)[i];
   11293              : }
   11294              : 
   11295              : /* Get the vectorized definitions of SLP_NODE in *VEC_DEFS.  */
   11296              : 
   11297              : void
   11298       945157 : vect_get_slp_defs (slp_tree slp_node, vec<tree> *vec_defs)
   11299              : {
   11300      1890314 :   vec_defs->create (SLP_TREE_VEC_DEFS (slp_node).length ());
   11301       945157 :   vec_defs->splice (SLP_TREE_VEC_DEFS (slp_node));
   11302       945157 : }
   11303              : 
   11304              : /* Get N vectorized definitions for SLP_NODE.  */
   11305              : 
   11306              : void
   11307         3083 : vect_get_slp_defs (vec_info *,
   11308              :                    slp_tree slp_node, vec<vec<tree> > *vec_oprnds, unsigned n)
   11309              : {
   11310         3083 :   if (n == -1U)
   11311         3083 :     n = SLP_TREE_CHILDREN (slp_node).length ();
   11312              : 
   11313        11001 :   for (unsigned i = 0; i < n; ++i)
   11314              :     {
   11315         7918 :       slp_tree child = SLP_TREE_CHILDREN (slp_node)[i];
   11316         7918 :       vec<tree> vec_defs = vNULL;
   11317         7918 :       vect_get_slp_defs (child, &vec_defs);
   11318         7918 :       vec_oprnds->quick_push (vec_defs);
   11319              :     }
   11320         3083 : }
   11321              : 
   11322              : /* A subroutine of vect_transform_slp_perm_load with two extra arguments:
   11323              :    - PERM gives the permutation that the caller wants to use for NODE,
   11324              :      which might be different from SLP_LOAD_PERMUTATION.
   11325              :    - DUMP_P controls whether the function dumps information.  */
   11326              : 
   11327              : static bool
   11328       137664 : vect_transform_slp_perm_load_1 (vec_info *vinfo, slp_tree node,
   11329              :                                 load_permutation_t &perm,
   11330              :                                 const vec<tree> &dr_chain,
   11331              :                                 gimple_stmt_iterator *gsi, poly_uint64 vf,
   11332              :                                 bool analyze_only, bool dump_p,
   11333              :                                 unsigned *n_perms, unsigned int *n_loads,
   11334              :                                 bool dce_chain)
   11335              : {
   11336       137664 :   stmt_vec_info stmt_info = SLP_TREE_SCALAR_STMTS (node)[0];
   11337       137664 :   int vec_index = 0;
   11338       137664 :   tree vectype = SLP_TREE_VECTYPE (node);
   11339       137664 :   unsigned int group_size = SLP_TREE_LANES (node);
   11340       137664 :   unsigned int mask_element;
   11341       137664 :   unsigned dr_group_size;
   11342       137664 :   machine_mode mode;
   11343              : 
   11344       137664 :   if (!STMT_VINFO_GROUPED_ACCESS (stmt_info))
   11345              :     {
   11346              :       /* We have both splats of the same non-grouped load and groups
   11347              :          of distinct invariant loads entering here.  */
   11348         1521 :       unsigned max_idx = 0;
   11349         8413 :       for (auto idx : perm)
   11350         3850 :         max_idx = idx > max_idx ? idx : max_idx;
   11351         1521 :       dr_group_size = max_idx + 1;
   11352              :     }
   11353              :   else
   11354              :     {
   11355       136143 :       stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
   11356       136143 :       dr_group_size = DR_GROUP_SIZE (stmt_info);
   11357              :     }
   11358              : 
   11359       137664 :   mode = TYPE_MODE (vectype);
   11360       137664 :   poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
   11361       137664 :   unsigned int nstmts = vect_get_num_copies (vinfo, node);
   11362              : 
   11363              :   /* Initialize the vect stmts of NODE to properly insert the generated
   11364              :      stmts later.  */
   11365       137664 :   if (! analyze_only)
   11366        56872 :     for (unsigned i = SLP_TREE_VEC_DEFS (node).length (); i < nstmts; i++)
   11367        22008 :       SLP_TREE_VEC_DEFS (node).quick_push (NULL_TREE);
   11368              : 
   11369              :   /* Generate permutation masks for every NODE. Number of masks for each NODE
   11370              :      is equal to GROUP_SIZE.
   11371              :      E.g., we have a group of three nodes with three loads from the same
   11372              :      location in each node, and the vector size is 4. I.e., we have a
   11373              :      a0b0c0a1b1c1... sequence and we need to create the following vectors:
   11374              :      for a's: a0a0a0a1 a1a1a2a2 a2a3a3a3
   11375              :      for b's: b0b0b0b1 b1b1b2b2 b2b3b3b3
   11376              :      ...
   11377              : 
   11378              :      The masks for a's should be: {0,0,0,3} {3,3,6,6} {6,9,9,9}.
   11379              :      The last mask is illegal since we assume two operands for permute
   11380              :      operation, and the mask element values can't be outside that range.
   11381              :      Hence, the last mask must be converted into {2,5,5,5}.
   11382              :      For the first two permutations we need the first and the second input
   11383              :      vectors: {a0,b0,c0,a1} and {b1,c1,a2,b2}, and for the last permutation
   11384              :      we need the second and the third vectors: {b1,c1,a2,b2} and
   11385              :      {c2,a3,b3,c3}.  */
   11386              : 
   11387       137664 :   int vect_stmts_counter = 0;
   11388       137664 :   unsigned int index = 0;
   11389       137664 :   int first_vec_index = -1;
   11390       137664 :   int second_vec_index = -1;
   11391       137664 :   bool noop_p = true;
   11392       137664 :   *n_perms = 0;
   11393              : 
   11394       137664 :   vec_perm_builder mask;
   11395       137664 :   unsigned int nelts_to_build;
   11396       137664 :   unsigned int nvectors_per_build;
   11397       137664 :   unsigned int in_nlanes;
   11398       137664 :   bool repeating_p = (group_size == dr_group_size
   11399       173084 :                       && multiple_p (nunits, group_size));
   11400       137664 :   if (repeating_p)
   11401              :     {
   11402              :       /* A single vector contains a whole number of copies of the node, so:
   11403              :          (a) all permutes can use the same mask; and
   11404              :          (b) the permutes only need a single vector input.  */
   11405        32930 :       mask.new_vector (nunits, group_size, 3);
   11406        32930 :       nelts_to_build = mask.encoded_nelts ();
   11407              :       /* It's possible to obtain zero nstmts during analyze_only, so make
   11408              :          it at least one to ensure the later computation for n_perms
   11409              :          proceed.  */
   11410        32930 :       nvectors_per_build = nstmts > 0 ? nstmts : 1;
   11411        32930 :       in_nlanes = dr_group_size * 3;
   11412              :     }
   11413              :   else
   11414              :     {
   11415              :       /* We need to construct a separate mask for each vector statement.  */
   11416       104734 :       unsigned HOST_WIDE_INT const_nunits, const_vf;
   11417       104734 :       if (!nunits.is_constant (&const_nunits)
   11418       104734 :           || !vf.is_constant (&const_vf))
   11419              :         return false;
   11420       104734 :       mask.new_vector (const_nunits, const_nunits, 1);
   11421       104734 :       nelts_to_build = const_vf * group_size;
   11422       104734 :       nvectors_per_build = 1;
   11423       104734 :       in_nlanes = const_vf * dr_group_size;
   11424              :     }
   11425       137664 :   auto_sbitmap used_in_lanes (in_nlanes);
   11426       137664 :   bitmap_clear (used_in_lanes);
   11427       137664 :   auto_bitmap used_defs;
   11428              : 
   11429       137664 :   unsigned int count = mask.encoded_nelts ();
   11430       137664 :   mask.quick_grow (count);
   11431       137664 :   vec_perm_indices indices;
   11432              : 
   11433       724618 :   for (unsigned int j = 0; j < nelts_to_build; j++)
   11434              :     {
   11435       597922 :       unsigned int iter_num = j / group_size;
   11436       597922 :       unsigned int stmt_num = j % group_size;
   11437       597922 :       unsigned int i = (iter_num * dr_group_size + perm[stmt_num]);
   11438       597922 :       bitmap_set_bit (used_in_lanes, i);
   11439       597922 :       if (repeating_p)
   11440              :         {
   11441              :           first_vec_index = 0;
   11442              :           mask_element = i;
   11443              :         }
   11444              :       else
   11445              :         {
   11446              :           /* Enforced before the loop when !repeating_p.  */
   11447       383068 :           unsigned int const_nunits = nunits.to_constant ();
   11448       383068 :           vec_index = i / const_nunits;
   11449       383068 :           mask_element = i % const_nunits;
   11450       383068 :           if (vec_index == first_vec_index
   11451       383068 :               || first_vec_index == -1)
   11452              :             {
   11453              :               first_vec_index = vec_index;
   11454              :             }
   11455       153537 :           else if (vec_index == second_vec_index
   11456       153537 :                    || second_vec_index == -1)
   11457              :             {
   11458       147130 :               second_vec_index = vec_index;
   11459       147130 :               mask_element += const_nunits;
   11460              :             }
   11461              :           else
   11462              :             {
   11463         6407 :               if (dump_p)
   11464          280 :                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   11465              :                                  "permutation requires at "
   11466              :                                  "least three vectors %G",
   11467              :                                  stmt_info->stmt);
   11468         6407 :               gcc_assert (analyze_only);
   11469              :               return false;
   11470              :             }
   11471              : 
   11472       376661 :           gcc_assert (mask_element < 2 * const_nunits);
   11473              :         }
   11474              : 
   11475       591515 :       if (mask_element != index)
   11476       380706 :         noop_p = false;
   11477       591515 :       mask[index++] = mask_element;
   11478              : 
   11479       591515 :       if (index == count)
   11480              :         {
   11481       162413 :           if (!noop_p)
   11482              :             {
   11483       132122 :               indices.new_vector (mask, second_vec_index == -1 ? 1 : 2, nunits);
   11484       132122 :               if (!can_vec_perm_const_p (mode, mode, indices))
   11485              :                 {
   11486         4561 :                   if (dump_p)
   11487              :                     {
   11488           90 :                       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   11489              :                                        "unsupported vect permute { ");
   11490          876 :                       for (i = 0; i < count; ++i)
   11491              :                         {
   11492          786 :                           dump_dec (MSG_MISSED_OPTIMIZATION, mask[i]);
   11493          786 :                           dump_printf (MSG_MISSED_OPTIMIZATION, " ");
   11494              :                         }
   11495           90 :                       dump_printf (MSG_MISSED_OPTIMIZATION, "}\n");
   11496              :                     }
   11497         4561 :                   gcc_assert (analyze_only);
   11498              :                   return false;
   11499              :                 }
   11500              : 
   11501       127561 :               tree mask_vec = NULL_TREE;
   11502       127561 :               if (!analyze_only)
   11503        20286 :                 mask_vec = vect_gen_perm_mask_checked (vectype, indices);
   11504              : 
   11505       127561 :               if (second_vec_index == -1)
   11506        36362 :                 second_vec_index = first_vec_index;
   11507              : 
   11508       257987 :               for (unsigned int ri = 0; ri < nvectors_per_build; ++ri)
   11509              :                 {
   11510       130426 :                   ++*n_perms;
   11511       130426 :                   if (analyze_only)
   11512       109857 :                     continue;
   11513              :                   /* Generate the permute statement if necessary.  */
   11514        20569 :                   tree first_vec = dr_chain[first_vec_index + ri];
   11515        20569 :                   tree second_vec = dr_chain[second_vec_index + ri];
   11516        20569 :                   gassign *stmt = as_a<gassign *> (stmt_info->stmt);
   11517        20569 :                   tree perm_dest
   11518        20569 :                     = vect_create_destination_var (gimple_assign_lhs (stmt),
   11519              :                                                    vectype);
   11520        20569 :                   perm_dest = make_ssa_name (perm_dest);
   11521        20569 :                   gimple *perm_stmt
   11522        20569 :                     = gimple_build_assign (perm_dest, VEC_PERM_EXPR, first_vec,
   11523              :                                            second_vec, mask_vec);
   11524        20569 :                   vect_finish_stmt_generation (vinfo, stmt_info, perm_stmt,
   11525              :                                                gsi);
   11526        20569 :                   if (dce_chain)
   11527              :                     {
   11528        19646 :                       bitmap_set_bit (used_defs, first_vec_index + ri);
   11529        19646 :                       bitmap_set_bit (used_defs, second_vec_index + ri);
   11530              :                     }
   11531              : 
   11532              :                   /* Store the vector statement in NODE.  */
   11533        20569 :                   SLP_TREE_VEC_DEFS (node)[vect_stmts_counter++] = perm_dest;
   11534              :                 }
   11535              :             }
   11536        30291 :           else if (!analyze_only)
   11537              :             {
   11538         2878 :               for (unsigned int ri = 0; ri < nvectors_per_build; ++ri)
   11539              :                 {
   11540         1439 :                   tree first_vec = dr_chain[first_vec_index + ri];
   11541              :                   /* If mask was NULL_TREE generate the requested
   11542              :                      identity transform.  */
   11543         1439 :                   if (dce_chain)
   11544         1432 :                     bitmap_set_bit (used_defs, first_vec_index + ri);
   11545              : 
   11546              :                   /* Store the vector statement in NODE.  */
   11547         1439 :                   SLP_TREE_VEC_DEFS (node)[vect_stmts_counter++] = first_vec;
   11548              :                 }
   11549              :             }
   11550              : 
   11551              :           index = 0;
   11552              :           first_vec_index = -1;
   11553              :           second_vec_index = -1;
   11554              :           noop_p = true;
   11555              :         }
   11556              :     }
   11557              : 
   11558       126696 :   if (n_loads)
   11559              :     {
   11560        88706 :       if (repeating_p)
   11561        10242 :         *n_loads = nstmts;
   11562              :       else
   11563              :         {
   11564              :           /* Enforced above when !repeating_p.  */
   11565        78464 :           unsigned int const_nunits = nunits.to_constant ();
   11566        78464 :           *n_loads = 0;
   11567        78464 :           bool load_seen = false;
   11568      1056011 :           for (unsigned i = 0; i < in_nlanes; ++i)
   11569              :             {
   11570       977547 :               if (i % const_nunits == 0)
   11571              :                 {
   11572       417449 :                   if (load_seen)
   11573       124142 :                     *n_loads += 1;
   11574              :                   load_seen = false;
   11575              :                 }
   11576       977547 :               if (bitmap_bit_p (used_in_lanes, i))
   11577       271979 :                 load_seen = true;
   11578              :             }
   11579        78464 :           if (load_seen)
   11580        52407 :             *n_loads += 1;
   11581              :         }
   11582              :     }
   11583              : 
   11584       126696 :   if (dce_chain)
   11585       211347 :     for (unsigned i = 0; i < dr_chain.length (); ++i)
   11586        73683 :       if (!bitmap_bit_p (used_defs, i))
   11587              :         {
   11588        40932 :           tree def = dr_chain[i];
   11589        41338 :           do
   11590              :             {
   11591        41338 :               gimple *stmt = SSA_NAME_DEF_STMT (def);
   11592        41338 :               if (is_gimple_assign (stmt)
   11593        41338 :                   && (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR
   11594        41338 :                       || gimple_assign_rhs_code (stmt) == CONSTRUCTOR))
   11595         5019 :                 def = single_ssa_tree_operand (stmt, SSA_OP_USE);
   11596              :               else
   11597              :                 def = NULL;
   11598        41338 :               gimple_stmt_iterator rgsi = gsi_for_stmt (stmt);
   11599        41338 :               gsi_remove (&rgsi, true);
   11600        41338 :               release_defs (stmt);
   11601              :             }
   11602        41338 :           while (def);
   11603              :         }
   11604              : 
   11605              :   return true;
   11606       137664 : }
   11607              : 
   11608              : /* Generate vector permute statements from a list of loads in DR_CHAIN.
   11609              :    If ANALYZE_ONLY is TRUE, only check that it is possible to create valid
   11610              :    permute statements for the SLP node NODE.  Store the number of vector
   11611              :    permute instructions in *N_PERMS and the number of vector load
   11612              :    instructions in *N_LOADS.  If DCE_CHAIN is true, remove all definitions
   11613              :    that were not needed.  */
   11614              : 
   11615              : bool
   11616        98456 : vect_transform_slp_perm_load (vec_info *vinfo,
   11617              :                               slp_tree node, const vec<tree> &dr_chain,
   11618              :                               gimple_stmt_iterator *gsi, poly_uint64 vf,
   11619              :                               bool analyze_only, unsigned *n_perms,
   11620              :                               unsigned int *n_loads, bool dce_chain)
   11621              : {
   11622        98456 :   return vect_transform_slp_perm_load_1 (vinfo, node,
   11623        98456 :                                          SLP_TREE_LOAD_PERMUTATION (node),
   11624              :                                          dr_chain, gsi, vf, analyze_only,
   11625              :                                          dump_enabled_p (), n_perms, n_loads,
   11626        98456 :                                          dce_chain);
   11627              : }
   11628              : 
   11629              : /* Produce the next vector result for SLP permutation NODE by adding a vector
   11630              :    statement at GSI.  If MASK_VEC is nonnull, add:
   11631              : 
   11632              :       <new SSA name> = VEC_PERM_EXPR <FIRST_DEF, SECOND_DEF, MASK_VEC>
   11633              : 
   11634              :    otherwise add:
   11635              : 
   11636              :       <new SSA name> = VEC_PERM_EXPR <FIRST_DEF, SECOND_DEF,
   11637              :                                       { N, N+1, N+2, ... }>
   11638              : 
   11639              :    where N == IDENTITY_OFFSET which is either zero or equal to the
   11640              :    number of elements of the result.  */
   11641              : 
   11642              : static void
   11643        32415 : vect_add_slp_permutation (vec_info *vinfo, gimple_stmt_iterator *gsi,
   11644              :                           slp_tree node, tree first_def, tree second_def,
   11645              :                           tree mask_vec, poly_uint64 identity_offset)
   11646              : {
   11647        32415 :   tree vectype = SLP_TREE_VECTYPE (node);
   11648              : 
   11649              :   /* ???  We SLP match existing vector element extracts but
   11650              :      allow punning which we need to re-instantiate at uses
   11651              :      but have no good way of explicitly representing.  */
   11652        32415 :   if (operand_equal_p (TYPE_SIZE (TREE_TYPE (first_def)), TYPE_SIZE (vectype))
   11653        32415 :       && !types_compatible_p (TREE_TYPE (first_def), vectype))
   11654              :     {
   11655           11 :       gassign *conv_stmt
   11656           11 :         = gimple_build_assign (make_ssa_name (vectype),
   11657              :                                build1 (VIEW_CONVERT_EXPR, vectype, first_def));
   11658           11 :       vect_finish_stmt_generation (vinfo, NULL, conv_stmt, gsi);
   11659           11 :       first_def = gimple_assign_lhs (conv_stmt);
   11660              :     }
   11661        32415 :   gassign *perm_stmt;
   11662        32415 :   if (mask_vec)
   11663              :     {
   11664        28470 :       if (operand_equal_p (TYPE_SIZE (TREE_TYPE (first_def)),
   11665        28470 :                            TYPE_SIZE (vectype))
   11666        28470 :           && !types_compatible_p (TREE_TYPE (second_def), vectype))
   11667              :         {
   11668            8 :           gassign *conv_stmt
   11669            8 :             = gimple_build_assign (make_ssa_name (vectype),
   11670              :                                    build1 (VIEW_CONVERT_EXPR,
   11671              :                                            vectype, second_def));
   11672            8 :           vect_finish_stmt_generation (vinfo, NULL, conv_stmt, gsi);
   11673            8 :           second_def = gimple_assign_lhs (conv_stmt);
   11674              :         }
   11675        28470 :       tree perm_dest = make_ssa_name (vectype);
   11676        28470 :       perm_stmt = gimple_build_assign (perm_dest, VEC_PERM_EXPR,
   11677              :                                        first_def, second_def,
   11678              :                                        mask_vec);
   11679              :     }
   11680              :   else
   11681              :     {
   11682         3945 :       auto def_nunits = TYPE_VECTOR_SUBPARTS (TREE_TYPE (first_def));
   11683         3945 :       unsigned HOST_WIDE_INT vecno;
   11684         3945 :       poly_uint64 eltno;
   11685         3945 :       if (!can_div_trunc_p (poly_uint64 (identity_offset), def_nunits,
   11686              :                             &vecno, &eltno))
   11687              :         gcc_unreachable ();
   11688         3945 :       tree def = vecno & 1 ? second_def : first_def;
   11689         3945 :       if (!types_compatible_p (TREE_TYPE (def), vectype))
   11690              :         {
   11691              :           /* For identity permutes we still need to handle the case
   11692              :              of offsetted extracts or concats.  */
   11693          362 :           tree perm_dest = make_ssa_name (vectype);
   11694          362 :           unsigned HOST_WIDE_INT c;
   11695          362 :           if (known_le (TYPE_VECTOR_SUBPARTS (vectype), def_nunits))
   11696              :             {
   11697          358 :               unsigned HOST_WIDE_INT elsz
   11698          358 :                 = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (def))));
   11699          716 :               tree lowpart = build3 (BIT_FIELD_REF, vectype, def,
   11700          358 :                                      TYPE_SIZE (vectype),
   11701          358 :                                      bitsize_int (eltno * elsz));
   11702          358 :               perm_stmt = gimple_build_assign (perm_dest, lowpart);
   11703              :             }
   11704            4 :           else if (constant_multiple_p (TYPE_VECTOR_SUBPARTS (vectype),
   11705            4 :                                         def_nunits, &c) && c == 2)
   11706              :             {
   11707            4 :               gcc_assert (known_eq (identity_offset, 0U));
   11708            4 :               tree ctor = build_constructor_va (vectype, 2,
   11709              :                                                 NULL_TREE, first_def,
   11710              :                                                 NULL_TREE, second_def);
   11711            4 :               perm_stmt = gimple_build_assign (perm_dest, ctor);
   11712              :             }
   11713              :           else
   11714            0 :             gcc_unreachable ();
   11715              :         }
   11716              :       else
   11717              :         {
   11718         3583 :           gcc_assert (known_eq (eltno, 0U));
   11719         3583 :           node->push_vec_def (def);
   11720         3583 :           return;
   11721              :         }
   11722              :     }
   11723        28832 :   vect_finish_stmt_generation (vinfo, NULL, perm_stmt, gsi);
   11724              :   /* Store the vector statement in NODE.  */
   11725        28832 :   node->push_vec_def (perm_stmt);
   11726              : }
   11727              : 
   11728              : /* Subroutine of vectorizable_slp_permutation.  Check whether the target
   11729              :    can perform permutation PERM on the (1 or 2) input nodes in CHILDREN.
   11730              :    If GSI is nonnull, emit the permutation there.
   11731              : 
   11732              :    When GSI is null, the only purpose of NODE is to give properties
   11733              :    of the result, such as the vector type and number of SLP lanes.
   11734              :    The node does not need to be a VEC_PERM_EXPR.
   11735              : 
   11736              :    If the target supports the operation, return the number of individual
   11737              :    VEC_PERM_EXPRs needed, otherwise return -1.  Print information to the
   11738              :    dump file if DUMP_P is true.  */
   11739              : 
   11740              : static int
   11741       446166 : vectorizable_slp_permutation_1 (vec_info *vinfo, gimple_stmt_iterator *gsi,
   11742              :                                 slp_tree node, lane_permutation_t &perm,
   11743              :                                 vec<slp_tree> &children, bool dump_p)
   11744              : {
   11745       446166 :   tree vectype = SLP_TREE_VECTYPE (node);
   11746              : 
   11747              :   /* ???  We currently only support all same vector input types
   11748              :      while the SLP IL should really do a concat + select and thus accept
   11749              :      arbitrary mismatches.  */
   11750       446166 :   slp_tree child;
   11751       446166 :   unsigned i;
   11752       446166 :   poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
   11753       446166 :   bool repeating_p = multiple_p (nunits, SLP_TREE_LANES (node));
   11754              :   /* True if we're permuting a single input of 2N vectors down
   11755              :      to N vectors.  This case doesn't generalize beyond 2 since
   11756              :      VEC_PERM_EXPR only takes 2 inputs.  */
   11757       446166 :   bool pack_p = false;
   11758              :   /* If we're permuting inputs of N vectors each into X*N outputs,
   11759              :      this is the value of X, otherwise it is 1.  */
   11760       446166 :   unsigned int unpack_factor = 1;
   11761       446166 :   tree op_vectype = NULL_TREE;
   11762       447770 :   FOR_EACH_VEC_ELT (children, i, child)
   11763       447670 :     if (SLP_TREE_VECTYPE (child))
   11764              :       {
   11765              :         op_vectype = SLP_TREE_VECTYPE (child);
   11766              :         break;
   11767              :       }
   11768       446166 :   if (!op_vectype)
   11769          100 :     op_vectype = vectype;
   11770       937578 :   FOR_EACH_VEC_ELT (children, i, child)
   11771              :     {
   11772       491412 :       if ((SLP_TREE_DEF_TYPE (child) != vect_internal_def
   11773        18321 :            && !vect_maybe_update_slp_op_vectype (child, op_vectype))
   11774       491412 :           || !types_compatible_p (SLP_TREE_VECTYPE (child), op_vectype)
   11775       982824 :           || !types_compatible_p (TREE_TYPE (vectype), TREE_TYPE (op_vectype)))
   11776              :         {
   11777            0 :           if (dump_p)
   11778            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   11779              :                              "Unsupported vector types in lane permutation\n");
   11780       446166 :           return -1;
   11781              :         }
   11782       491412 :       auto op_nunits = TYPE_VECTOR_SUBPARTS (op_vectype);
   11783       491412 :       unsigned int this_unpack_factor;
   11784              :       /* Detect permutations of external, pre-existing vectors.  The external
   11785              :          node's SLP_TREE_LANES stores the total number of units in the vector,
   11786              :          or zero if the vector has variable length.
   11787              : 
   11788              :          We are expected to keep the original VEC_PERM_EXPR for such cases.
   11789              :          There is no repetition to model.  */
   11790       491412 :       if (SLP_TREE_DEF_TYPE (child) == vect_external_def
   11791       491412 :           && SLP_TREE_SCALAR_OPS (child).is_empty ())
   11792              :         repeating_p = false;
   11793              :       /* Check whether the input has twice as many lanes per vector.  */
   11794       475835 :       else if (children.length () == 1
   11795       475835 :                && known_eq (SLP_TREE_LANES (child) * nunits,
   11796              :                             SLP_TREE_LANES (node) * op_nunits * 2))
   11797              :         pack_p = true;
   11798              :       /* Check whether the output has N times as many lanes per vector.  */
   11799       491412 :       else if (constant_multiple_p (SLP_TREE_LANES (node) * op_nunits,
   11800       431699 :                                     SLP_TREE_LANES (child) * nunits,
   11801              :                                     &this_unpack_factor)
   11802       396822 :                && (i == 0 || unpack_factor == this_unpack_factor))
   11803              :         unpack_factor = this_unpack_factor;
   11804              :       else
   11805              :         repeating_p = false;
   11806              :     }
   11807              : 
   11808       892332 :   gcc_assert (perm.length () == SLP_TREE_LANES (node));
   11809              : 
   11810              :   /* Load-lanes permute.  This permute only acts as a forwarder to
   11811              :      select the correct vector def of the load-lanes load which
   11812              :      has the permuted vectors in its vector defs like
   11813              :      { v0, w0, r0, v1, w1, r1 ... } for a ld3.  All costs are
   11814              :      accounted for in the costing for the actual load so we
   11815              :      return zero here.  */
   11816       446166 :   if (node->ldst_lanes)
   11817              :     {
   11818            0 :       gcc_assert (children.length () == 1);
   11819            0 :       if (!gsi)
   11820              :         /* This is a trivial op always supported.  */
   11821              :         return 0;
   11822            0 :       slp_tree child = children[0];
   11823            0 :       unsigned vec_idx = (SLP_TREE_LANE_PERMUTATION (node)[0].second
   11824            0 :                           / SLP_TREE_LANES (node));
   11825            0 :       unsigned vec_num = SLP_TREE_LANES (child) / SLP_TREE_LANES (node);
   11826            0 :       unsigned nvectors = vect_get_num_copies (vinfo, node);
   11827            0 :       for (unsigned i = 0; i < nvectors; ++i)
   11828              :         {
   11829            0 :           tree def = SLP_TREE_VEC_DEFS (child)[i * vec_num  + vec_idx];
   11830            0 :           node->push_vec_def (def);
   11831              :         }
   11832              :       return 0;
   11833              :     }
   11834              : 
   11835              :   /* Set REPEATING_P to true if the permutations are cyclical wrt UNPACK_FACTOR
   11836              :      and if we can generate the vectors in a vector-length agnostic way.
   11837              :      This requires UNPACK_STEP == NUNITS / UNPACK_FACTOR to be known at
   11838              :      compile time.
   11839              : 
   11840              :      The significance of UNPACK_STEP is that, when PACK_P is false,
   11841              :      output vector I operates on a window of UNPACK_STEP elements from each
   11842              :      input, starting at lane UNPACK_STEP * (I % UNPACK_FACTOR).  For example,
   11843              :      when UNPACK_FACTOR is 2, the first output vector operates on lanes
   11844              :      [0, NUNITS / 2 - 1] of each input vector and the second output vector
   11845              :      operates on lanes [NUNITS / 2, NUNITS - 1] of each input vector.
   11846              : 
   11847              :      When REPEATING_P is true, NOUTPUTS holds the total number of outputs
   11848              :      that we actually need to generate.  */
   11849       446166 :   uint64_t noutputs = 0;
   11850       446166 :   poly_uint64 unpack_step = 0;
   11851       446166 :   loop_vec_info linfo = dyn_cast <loop_vec_info> (vinfo);
   11852       183423 :   if (!linfo
   11853       485221 :       || !multiple_p (nunits, unpack_factor, &unpack_step)
   11854       182485 :       || !constant_multiple_p (LOOP_VINFO_VECT_FACTOR (linfo)
   11855       182485 :                                * SLP_TREE_LANES (node), nunits, &noutputs))
   11856              :     repeating_p = false;
   11857              : 
   11858              :   /* We can handle the conditions described for REPEATING_P above for
   11859              :      both variable- and constant-length vectors.  The fallback requires
   11860              :      us to generate every element of every permute vector explicitly,
   11861              :      which is only possible for constant-length permute vectors.
   11862              : 
   11863              :      Set:
   11864              : 
   11865              :      - NPATTERNS and NELTS_PER_PATTERN to the encoding of the permute
   11866              :        mask vectors that we want to build.
   11867              : 
   11868              :      - NCOPIES to the number of copies of PERM that we need in order
   11869              :        to build the necessary permute mask vectors.  */
   11870       182485 :   uint64_t npatterns;
   11871       182485 :   unsigned nelts_per_pattern;
   11872       182485 :   uint64_t ncopies;
   11873       182485 :   if (repeating_p)
   11874              :     {
   11875              :       /* We need permute mask vectors that have the form:
   11876              : 
   11877              :            { X1, ..., Xn, X1 + n, ..., Xn + n, X1 + 2n, ..., Xn + 2n, ... }
   11878              : 
   11879              :          In other words, the original n-element permute in PERM is
   11880              :          "unrolled" to fill a full vector.  The stepped vector encoding
   11881              :          that we use for permutes requires 3n elements.  */
   11882       143430 :       npatterns = SLP_TREE_LANES (node);
   11883       143430 :       nelts_per_pattern = ncopies = 3;
   11884              :     }
   11885              :   else
   11886              :     {
   11887              :       /* Calculate every element of every permute mask vector explicitly,
   11888              :          instead of relying on the pattern described above.  */
   11889       302736 :       if (!nunits.is_constant (&npatterns)
   11890       302736 :           || !TYPE_VECTOR_SUBPARTS (op_vectype).is_constant ())
   11891              :         {
   11892              :           if (dump_p)
   11893              :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   11894              :                              "unsupported permutation %p on variable-length"
   11895              :                              " vectors\n", (void *) node);
   11896              :           return -1;
   11897              :         }
   11898       302736 :       nelts_per_pattern = ncopies = 1;
   11899       302736 :       if (linfo && !LOOP_VINFO_VECT_FACTOR (linfo).is_constant (&ncopies))
   11900              :         {
   11901              :           if (dump_p)
   11902              :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   11903              :                              "unsupported permutation %p for variable VF\n",
   11904              :                              (void *) node);
   11905              :           return -1;
   11906              :         }
   11907              :       pack_p = false;
   11908              :       unpack_factor = 1;
   11909              :     }
   11910       446166 :   unsigned olanes = unpack_factor * ncopies * SLP_TREE_LANES (node);
   11911       446166 :   gcc_assert (repeating_p || multiple_p (olanes, nunits));
   11912              : 
   11913              :   /* Compute the { { SLP operand, vector index}, lane } permutation sequence
   11914              :      from the { SLP operand, scalar lane } permutation as recorded in the
   11915              :      SLP node as intermediate step.  This part should already work
   11916              :      with SLP children with arbitrary number of lanes.  */
   11917       446166 :   auto_vec<std::pair<std::pair<unsigned, unsigned>, poly_uint64>> vperm;
   11918       446166 :   auto_vec<poly_uint64> active_lane;
   11919       446166 :   vperm.create (olanes);
   11920       446166 :   active_lane.safe_grow_cleared (children.length (), true);
   11921      1347020 :   for (unsigned int ui = 0; ui < unpack_factor; ++ui)
   11922              :     {
   11923      1926240 :       for (unsigned j = 0; j < children.length (); ++j)
   11924       508432 :         active_lane[j] = ui * unpack_step;
   11925      1311218 :       for (unsigned i = 0; i < ncopies; ++i)
   11926              :         {
   11927      5404462 :           for (unsigned pi = 0; pi < perm.length (); ++pi)
   11928              :             {
   11929      1845701 :               std::pair<unsigned, unsigned> p = perm[pi];
   11930      1845701 :               tree vtype = SLP_TREE_VECTYPE (children[p.first]);
   11931      1845701 :               if (repeating_p)
   11932       839097 :                 vperm.quick_push ({{p.first, 0},
   11933       839097 :                                    p.second + active_lane[p.first]});
   11934              :               else
   11935              :                 {
   11936              :                   /* We checked above that the vectors are constant-length.  */
   11937      1006604 :                   unsigned vnunits = TYPE_VECTOR_SUBPARTS (vtype)
   11938      1006604 :                     .to_constant ();
   11939      1006604 :                   unsigned lane = active_lane[p.first].to_constant ();
   11940      1006604 :                   unsigned vi = (lane + p.second) / vnunits;
   11941      1006604 :                   unsigned vl = (lane + p.second) % vnunits;
   11942      1006604 :                   vperm.quick_push ({{p.first, vi}, vl});
   11943              :                 }
   11944              :             }
   11945              :           /* Advance to the next group.  */
   11946      1832565 :           for (unsigned j = 0; j < children.length (); ++j)
   11947       976035 :             active_lane[j] += SLP_TREE_LANES (children[j]);
   11948              :         }
   11949              :     }
   11950              : 
   11951       446166 :   if (dump_p)
   11952              :     {
   11953         9031 :       dump_printf_loc (MSG_NOTE, vect_location,
   11954              :                        "vectorizing permutation %p", (void *)node);
   11955        32682 :       for (unsigned i = 0; i < perm.length (); ++i)
   11956        23651 :         dump_printf (MSG_NOTE, " op%u[%u]", perm[i].first, perm[i].second);
   11957         9031 :       if (repeating_p)
   11958         7574 :         dump_printf (MSG_NOTE, " (repeat %d)", SLP_TREE_LANES (node));
   11959         9031 :       dump_printf (MSG_NOTE, "\n");
   11960         9031 :       dump_printf_loc (MSG_NOTE, vect_location, "as");
   11961        90762 :       for (unsigned i = 0; i < vperm.length (); ++i)
   11962              :         {
   11963        81731 :           if (i != 0
   11964        81731 :               && (repeating_p
   11965        55351 :                   ? multiple_p (i, npatterns)
   11966        81731 :                   : multiple_p (i, TYPE_VECTOR_SUBPARTS (vectype))))
   11967        24385 :             dump_printf (MSG_NOTE, ",");
   11968        81731 :           dump_printf (MSG_NOTE, " vops%u[%u][",
   11969        81731 :                        vperm[i].first.first, vperm[i].first.second);
   11970        81731 :           dump_dec (MSG_NOTE, vperm[i].second);
   11971        81731 :           dump_printf (MSG_NOTE, "]");
   11972              :         }
   11973         9031 :       dump_printf (MSG_NOTE, "\n");
   11974              :     }
   11975              : 
   11976              :   /* We can only handle two-vector permutes, everything else should
   11977              :      be lowered on the SLP level.  The following is closely inspired
   11978              :      by vect_transform_slp_perm_load and is supposed to eventually
   11979              :      replace it.
   11980              :      ???   As intermediate step do code-gen in the SLP tree representation
   11981              :      somehow?  */
   11982       446166 :   std::pair<unsigned, unsigned> first_vec = std::make_pair (-1U, -1U);
   11983       446166 :   std::pair<unsigned, unsigned> second_vec = std::make_pair (-1U, -1U);
   11984       446166 :   unsigned int index = 0;
   11985       446166 :   poly_uint64 mask_element;
   11986       446166 :   vec_perm_builder mask;
   11987       446166 :   mask.new_vector (nunits, npatterns, nelts_per_pattern);
   11988       446166 :   unsigned int count = mask.encoded_nelts ();
   11989       446166 :   mask.quick_grow (count);
   11990       446166 :   vec_perm_indices indices;
   11991       446166 :   unsigned nperms = 0;
   11992              :   /* When REPEATING_P is true, we only have UNPACK_FACTOR unique permute
   11993              :      vectors to check during analysis, but we need to generate NOUTPUTS
   11994              :      vectors during transformation.  */
   11995       446166 :   unsigned total_nelts = olanes;
   11996       446166 :   unsigned process_nelts = olanes;
   11997       446166 :   if (repeating_p)
   11998              :     {
   11999       143430 :       total_nelts = (total_nelts / unpack_factor) * noutputs;
   12000       143430 :       if (gsi)
   12001         9960 :         process_nelts = total_nelts;
   12002              :     }
   12003       446166 :   unsigned last_ei = (total_nelts - 1) % process_nelts;
   12004      2296206 :   for (unsigned i = 0; i < process_nelts; ++i)
   12005              :     {
   12006              :       /* VI is the input vector index when generating code for REPEATING_P.  */
   12007      1860232 :       unsigned vi = i / olanes * (pack_p ? 2 : 1);
   12008      1860232 :       unsigned ei = i % olanes;
   12009      1860232 :       mask_element = vperm[ei].second;
   12010      1860232 :       if (pack_p)
   12011              :         {
   12012              :           /* In this case, we have N outputs and the single child provides 2N
   12013              :              inputs.  Output X permutes inputs 2X and 2X+1.
   12014              : 
   12015              :              The mask indices are taken directly from the SLP permutation node.
   12016              :              Index X selects from the first vector if (X / NUNITS) % 2 == 0;
   12017              :              X selects from the second vector otherwise.  These conditions
   12018              :              are only known at compile time for constant-length vectors.  */
   12019              :           first_vec = std::make_pair (0, 0);
   12020              :           second_vec = std::make_pair (0, 1);
   12021              :         }
   12022      1689982 :       else if (first_vec.first == -1U
   12023      1689982 :                || first_vec == vperm[ei].first)
   12024      1492483 :         first_vec = vperm[ei].first;
   12025       197499 :       else if (second_vec.first == -1U
   12026       197499 :                || second_vec == vperm[ei].first)
   12027              :         {
   12028       197093 :           second_vec = vperm[ei].first;
   12029       197093 :           mask_element += nunits;
   12030              :         }
   12031              :       else
   12032              :         {
   12033          406 :           if (dump_p)
   12034            7 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   12035              :                              "permutation requires at "
   12036              :                              "least three vectors\n");
   12037          406 :           gcc_assert (!gsi);
   12038              :           return -1;
   12039              :         }
   12040              : 
   12041      1859826 :       mask[index++] = mask_element;
   12042              : 
   12043      1859826 :       if (index == count)
   12044              :         {
   12045       591165 :           indices.new_vector (mask, second_vec.first == -1U ? 1 : 2,
   12046              :                               TYPE_VECTOR_SUBPARTS (op_vectype));
   12047       591165 :           bool identity_p = (indices.series_p (0, 1, mask[0], 1)
   12048       920748 :                              && constant_multiple_p (mask[0], nunits));
   12049       591165 :           machine_mode vmode = TYPE_MODE (vectype);
   12050       591165 :           machine_mode op_vmode = TYPE_MODE (op_vectype);
   12051       591165 :           unsigned HOST_WIDE_INT c;
   12052       591165 :           if ((!identity_p
   12053       541648 :                && !can_vec_perm_const_p (vmode, op_vmode, indices))
   12054       591165 :               || (identity_p
   12055        49517 :                   && !known_le (nunits,
   12056              :                                 TYPE_VECTOR_SUBPARTS (op_vectype))
   12057            8 :                   && (!constant_multiple_p (nunits,
   12058         9794 :                                             TYPE_VECTOR_SUBPARTS (op_vectype),
   12059            8 :                                             &c) || c != 2)))
   12060              :             {
   12061         9786 :               if (dump_p)
   12062              :                 {
   12063          154 :                   dump_printf_loc (MSG_MISSED_OPTIMIZATION,
   12064              :                                    vect_location,
   12065              :                                    "unsupported vect permute { ");
   12066         1596 :                   for (i = 0; i < count; ++i)
   12067              :                     {
   12068         1442 :                       dump_dec (MSG_MISSED_OPTIMIZATION, mask[i]);
   12069         1442 :                       dump_printf (MSG_MISSED_OPTIMIZATION, " ");
   12070              :                     }
   12071          154 :                   dump_printf (MSG_MISSED_OPTIMIZATION, "}\n");
   12072              :                 }
   12073         9786 :               gcc_assert (!gsi);
   12074       446166 :               return -1;
   12075              :             }
   12076              : 
   12077       581379 :           if (!identity_p)
   12078       531862 :             nperms += CEIL (total_nelts, process_nelts) - (ei > last_ei);
   12079       581379 :           if (gsi)
   12080              :             {
   12081        32415 :               if (second_vec.first == -1U)
   12082         7765 :                 second_vec = first_vec;
   12083              : 
   12084        32415 :               slp_tree
   12085        32415 :                 first_node = children[first_vec.first],
   12086        32415 :                 second_node = children[second_vec.first];
   12087              : 
   12088        32415 :               tree mask_vec = NULL_TREE;
   12089        32415 :               if (!identity_p)
   12090        28470 :                 mask_vec = vect_gen_perm_mask_checked (vectype, indices);
   12091              : 
   12092        32415 :               tree first_def
   12093        32415 :                 = vect_get_slp_vect_def (first_node, first_vec.second + vi);
   12094        32415 :               tree second_def
   12095        32415 :                 = vect_get_slp_vect_def (second_node, second_vec.second + vi);
   12096        32415 :               vect_add_slp_permutation (vinfo, gsi, node, first_def,
   12097        32415 :                                         second_def, mask_vec, mask[0]);
   12098              :             }
   12099              : 
   12100              :           index = 0;
   12101              :           first_vec = std::make_pair (-1U, -1U);
   12102              :           second_vec = std::make_pair (-1U, -1U);
   12103              :         }
   12104              :     }
   12105              : 
   12106       435974 :   return nperms;
   12107       446166 : }
   12108              : 
   12109              : /* Vectorize the SLP permutations in NODE as specified
   12110              :    in SLP_TREE_LANE_PERMUTATION which is a vector of pairs of SLP
   12111              :    child number and lane number.
   12112              :    Interleaving of two two-lane two-child SLP subtrees (not supported):
   12113              :      [ { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } ]
   12114              :    A blend of two four-lane two-child SLP subtrees:
   12115              :      [ { 0, 0 }, { 1, 1 }, { 0, 2 }, { 1, 3 } ]
   12116              :    Highpart of a four-lane one-child SLP subtree (not supported):
   12117              :      [ { 0, 2 }, { 0, 3 } ]
   12118              :    Where currently only a subset is supported by code generating below.  */
   12119              : 
   12120              : bool
   12121        99770 : vectorizable_slp_permutation (vec_info *vinfo, gimple_stmt_iterator *gsi,
   12122              :                               slp_tree node, stmt_vector_for_cost *cost_vec)
   12123              : {
   12124        99770 :   tree vectype = SLP_TREE_VECTYPE (node);
   12125        99770 :   lane_permutation_t &perm = SLP_TREE_LANE_PERMUTATION (node);
   12126        99770 :   int nperms = vectorizable_slp_permutation_1 (vinfo, gsi, node, perm,
   12127        99770 :                                                SLP_TREE_CHILDREN (node),
   12128              :                                                dump_enabled_p ());
   12129        99770 :   if (nperms < 0)
   12130              :     return false;
   12131              : 
   12132        98178 :   if (!gsi && nperms != 0)
   12133        74435 :     record_stmt_cost (cost_vec, nperms, vec_perm, node, vectype, 0, vect_body);
   12134              : 
   12135              :   return true;
   12136              : }
   12137              : 
   12138              : /* Vectorize SLP NODE.  Only compute the vector insertion places when
   12139              :    PLACE_ONLY is true.  When placing, return false if there is no possible
   12140              :    schedule.  */
   12141              : 
   12142              : static bool
   12143      3135925 : vect_schedule_slp_node (vec_info *vinfo,
   12144              :                         slp_tree node, slp_instance instance, bool place_only)
   12145              : {
   12146      3135925 :   int i;
   12147      3135925 :   slp_tree child;
   12148              : 
   12149              :   /* Vectorize externals and constants.  */
   12150      3135925 :   if (SLP_TREE_DEF_TYPE (node) == vect_constant_def
   12151      3135925 :       || SLP_TREE_DEF_TYPE (node) == vect_external_def)
   12152              :     {
   12153      1214398 :       if (place_only)
   12154              :         {
   12155       701274 :           if (SLP_TREE_DEF_TYPE (node) == vect_constant_def)
   12156              :             return true;
   12157       320591 :           gimple *last_stmt = NULL;
   12158       320591 :           vec<tree> &defs = (!SLP_TREE_SCALAR_OPS (node).is_empty ()
   12159              :                              ? SLP_TREE_SCALAR_OPS (node)
   12160       320591 :                              : SLP_TREE_VEC_DEFS (node));
   12161      1717223 :           for (tree def : defs)
   12162              :             /* If the stmt is not inside the region do not
   12163              :                use it as possible insertion point.  */
   12164       755450 :             if (auto stmt_info = vinfo->lookup_def (def))
   12165              :               {
   12166       391852 :                 gimple *stmt = stmt_info->stmt;
   12167       391852 :                 if (!last_stmt)
   12168              :                   last_stmt = stmt;
   12169       220862 :                 else if (vect_stmt_dominates_stmt_p (last_stmt, stmt))
   12170              :                   last_stmt = stmt;
   12171        67254 :                 else if (vect_stmt_dominates_stmt_p (stmt, last_stmt))
   12172              :                   ;
   12173              :                 else
   12174            0 :                   gcc_unreachable ();
   12175              :               }
   12176       320591 :           node->si = last_stmt;
   12177       320591 :           return true;
   12178              :         }
   12179              : 
   12180              :       /* ???  vectorizable_shift can end up using a scalar operand which is
   12181              :          currently denoted as !SLP_TREE_VECTYPE.  No need to vectorize the
   12182              :          node in this case.  */
   12183       513124 :       if (!SLP_TREE_VECTYPE (node))
   12184              :         return true;
   12185              : 
   12186              :       /* There are two reasons vector defs might already exist.  The first
   12187              :          is that we are vectorizing an existing vector def.  The second is
   12188              :          when performing BB vectorization shared constant/external nodes
   12189              :          are not split apart during partitioning so during the code-gen
   12190              :          DFS walk we can end up visiting them twice.  */
   12191       505022 :       if (! SLP_TREE_VEC_DEFS (node).exists ())
   12192       504199 :         vect_create_constant_vectors (vinfo, node);
   12193              :       return true;
   12194              :     }
   12195              : 
   12196      1921527 :   stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node);
   12197              : 
   12198      1921527 :   gcc_assert (SLP_TREE_VEC_DEFS (node).is_empty ());
   12199      1921527 :   if (!place_only && SLP_TREE_VECTYPE (node))
   12200       977250 :     SLP_TREE_VEC_DEFS (node).create (vect_get_num_copies (vinfo, node));
   12201              : 
   12202      1921527 :   gimple *last_stmt;
   12203      1921527 :   gimple_stmt_iterator si;
   12204              :   /* ???  When !place_only we'd like to re-use place_only computed info,
   12205              :      but this is a bit awkward due to using gsi_insert_before and the
   12206              :      requirement to insert after vector defs.  So we compute last_stmt
   12207              :      during pre-scheduling and si during scheduling.  */
   12208      1921527 :   if (!SLP_TREE_PERMUTE_P (node) && STMT_VINFO_DATA_REF (stmt_info))
   12209              :     {
   12210              :       /* Vectorized loads go before the first scalar load to make it
   12211              :          ready early, vectorized stores go before the last scalar
   12212              :          stmt which is where all uses are ready.
   12213              :          In theory, if we delay dependence checking until after
   12214              :          placing, we can schedule at other points, but then
   12215              :          dependence checking would need to honor that.  On the
   12216              :          other hand dependence checking could request a different
   12217              :          scheduling point as well, if dependences require that.  */
   12218      1489310 :       stmt_vec_info last_stmt_info = NULL;
   12219      1489310 :       if (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)))
   12220       270976 :         last_stmt_info = vect_find_first_scalar_stmt_in_slp (node);
   12221              :       else /* DR_IS_WRITE */
   12222              :         {
   12223      1218334 :           last_stmt_info = vect_find_last_scalar_stmt_in_slp (node);
   12224      1218334 :           if (place_only)
   12225      1336106 :             FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
   12226              :               {
   12227       668055 :                 if (child->si
   12228       668055 :                     && !vect_stmt_dominates_stmt_p (child->si,
   12229              :                                                     last_stmt_info->stmt))
   12230              :                   return false;
   12231              :               }
   12232              :         }
   12233      1489306 :       last_stmt = last_stmt_info->stmt;
   12234      1489306 :       si = gsi_for_stmt (last_stmt);
   12235      1489306 :     }
   12236       432217 :   else if (!SLP_TREE_PERMUTE_P (node)
   12237       410574 :            && (SLP_TREE_TYPE (node) == cycle_phi_info_type
   12238              :                || SLP_TREE_TYPE (node) == induc_vec_info_type
   12239              :                || SLP_TREE_TYPE (node) == phi_info_type))
   12240              :     {
   12241              :       /* For PHI node vectorization we do not use the insertion iterator.  */
   12242       106581 :       last_stmt = SLP_TREE_SCALAR_STMTS (node)[0]->stmt;
   12243       106581 :       if (place_only)
   12244       182464 :         FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
   12245              :           {
   12246       129101 :             if (child->si
   12247       225071 :                 && !dominated_by_p (CDI_DOMINATORS,
   12248              :                                     gimple_phi_arg_edge
   12249        95970 :                                       (as_a <gphi *> (last_stmt), i)->src,
   12250        95970 :                                     gimple_bb (child->si)))
   12251              :               return false;
   12252              :           }
   12253       106579 :       si = gsi_none ();
   12254              :     }
   12255              :   else
   12256              :     {
   12257              :       /* Emit other stmts after the children vectorized defs which is
   12258              :          earliest possible.  */
   12259              :       last_stmt = NULL;
   12260       902120 :       FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
   12261       576486 :         if (place_only)
   12262              :           {
   12263       188802 :             gimple *vstmt = child->si;
   12264       188802 :             if (!vstmt)
   12265              :               {
   12266              :                 /* vect_constant_def and defs at region boundary do not
   12267              :                    constrain placement.  */
   12268              :                 gcc_assert (SLP_TREE_DEF_TYPE (child) == vect_constant_def
   12269              :                             /* ???  Region boundary is not representated
   12270              :                                by a NULL stmt.  */
   12271              :                             || true);
   12272              :               }
   12273       147897 :             else if (!last_stmt)
   12274              :               last_stmt = vstmt;
   12275        42530 :             else if (vect_stmt_dominates_stmt_p (last_stmt, vstmt))
   12276              :               last_stmt = vstmt;
   12277        10720 :             else if (vect_stmt_dominates_stmt_p (vstmt, last_stmt))
   12278              :               ;
   12279              :             else
   12280              :               /* Non-trapping stmts from different BBs might be combined,
   12281              :                  and if we later CSE a low/high part we can run into this.  */
   12282              :               return false;
   12283              :           }
   12284       387684 :         else if (SLP_TREE_DEF_TYPE (child) == vect_internal_def)
   12285              :           {
   12286              :             /* For fold-left reductions we are retaining the scalar
   12287              :                reduction PHI but we still have SLP_TREE_NUM_VEC_STMTS
   12288              :                set so the representation isn't perfect.  Resort to the
   12289              :                last scalar def here.  */
   12290       308313 :             if (SLP_TREE_VEC_DEFS (child).is_empty ())
   12291              :               {
   12292          959 :                 gcc_assert (SLP_TREE_TYPE (child) == cycle_phi_info_type);
   12293          959 :                 gphi *phi = as_a <gphi *>
   12294          959 :                               (vect_find_last_scalar_stmt_in_slp (child)->stmt);
   12295          959 :                 if (!last_stmt)
   12296              :                   last_stmt = phi;
   12297          727 :                 else if (vect_stmt_dominates_stmt_p (last_stmt, phi))
   12298              :                   last_stmt = phi;
   12299          716 :                 else if (vect_stmt_dominates_stmt_p (phi, last_stmt))
   12300              :                   ;
   12301              :                 else
   12302            0 :                   gcc_unreachable ();
   12303              :               }
   12304              :             /* We are emitting all vectorized stmts in the same place and
   12305              :                the last one is the last.
   12306              :                ???  Unless we have a load permutation applied and that
   12307              :                figures to re-use an earlier generated load.  */
   12308       308313 :             unsigned j;
   12309       308313 :             tree vdef;
   12310       729185 :             FOR_EACH_VEC_ELT (SLP_TREE_VEC_DEFS (child), j, vdef)
   12311       420872 :               if (TREE_CODE (vdef) == SSA_NAME
   12312       420872 :                   && !SSA_NAME_IS_DEFAULT_DEF (vdef))
   12313              :                 {
   12314       420820 :                   gimple *vstmt = SSA_NAME_DEF_STMT (vdef);
   12315       420820 :                   if (!last_stmt)
   12316              :                     last_stmt = vstmt;
   12317       214928 :                   else if (vect_stmt_dominates_stmt_p (last_stmt, vstmt))
   12318              :                     last_stmt = vstmt;
   12319        47775 :                   else if (vect_stmt_dominates_stmt_p (vstmt, last_stmt))
   12320              :                     ;
   12321              :                   else
   12322            0 :                     gcc_unreachable ();
   12323              :                 }
   12324              :           }
   12325        79371 :         else if (!SLP_TREE_VECTYPE (child))
   12326              :           {
   12327              :             /* For externals we use unvectorized at all scalar defs.  */
   12328              :             unsigned j;
   12329              :             tree def;
   12330        17321 :             FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (child), j, def)
   12331              :               /* If the stmt is not inside the region do not
   12332              :                  use it as possible insertion point.  */
   12333         9847 :               if (auto stmt_info = vinfo->lookup_def (def))
   12334              :                 {
   12335          138 :                   gimple *stmt = stmt_info->stmt;
   12336          138 :                   if (!last_stmt)
   12337              :                     last_stmt = stmt;
   12338          118 :                   else if (vect_stmt_dominates_stmt_p (last_stmt, stmt))
   12339              :                     last_stmt = stmt;
   12340           26 :                   else if (vect_stmt_dominates_stmt_p (stmt, last_stmt))
   12341              :                     ;
   12342              :                   else
   12343            0 :                     gcc_unreachable ();
   12344              :                 }
   12345              :           }
   12346              :         else
   12347              :           {
   12348              :             /* For externals we have to look at all defs since their
   12349              :                insertion place is decided per vector.  But beware
   12350              :                of pre-existing vectors where we need to make sure
   12351              :                we do not insert before the region boundary.  */
   12352       143659 :             if (SLP_TREE_SCALAR_OPS (child).is_empty ()
   12353          596 :                 && !vinfo->lookup_def (SLP_TREE_VEC_DEFS (child)[0]))
   12354              :               ;
   12355              :             else
   12356              :               {
   12357              :                 unsigned j;
   12358              :                 tree vdef;
   12359       749394 :                 FOR_EACH_VEC_ELT (SLP_TREE_VEC_DEFS (child), j, vdef)
   12360       101148 :                   if (TREE_CODE (vdef) == SSA_NAME
   12361       101148 :                       && !SSA_NAME_IS_DEFAULT_DEF (vdef))
   12362              :                     {
   12363        20662 :                       gimple *vstmt = SSA_NAME_DEF_STMT (vdef);
   12364        20662 :                       if (!last_stmt)
   12365              :                         last_stmt = vstmt;
   12366        11290 :                       else if (vect_stmt_dominates_stmt_p (last_stmt, vstmt))
   12367              :                         last_stmt = vstmt;
   12368         8967 :                       else if (vect_stmt_dominates_stmt_p (vstmt, last_stmt))
   12369              :                         ;
   12370              :                       else
   12371            0 :                         gcc_unreachable ();
   12372              :                     }
   12373              :               }
   12374              :           }
   12375              : 
   12376              :       /* When we face existing vector defs that are external, make sure
   12377              :          to insert at region boundary.  */
   12378       325634 :       if (last_stmt
   12379       320881 :           && is_a <bb_vec_info> (vinfo)
   12380       125209 :           && vinfo->bbs[0] != gimple_bb (last_stmt)
   12381       427056 :           && dominated_by_p (CDI_DOMINATORS, vinfo->bbs[0],
   12382       101422 :                              gimple_bb (last_stmt)))
   12383              :         last_stmt = NULL;
   12384              : 
   12385              :       /* We split regions to vectorize at control altering stmts
   12386              :          with a definition so this can only be an external.  */
   12387       325628 :       gcc_checking_assert (!last_stmt
   12388              :                            || !is_ctrl_altering_stmt (last_stmt));
   12389              : 
   12390       325634 :       if (is_a <bb_vec_info> (vinfo)
   12391       128359 :           && !SLP_TREE_PERMUTE_P (node)
   12392       121906 :           && (!last_stmt
   12393       119041 :               || !dominated_by_p (CDI_DOMINATORS, gimple_bb (last_stmt),
   12394       119041 :                                   gimple_bb (stmt_info->stmt)))
   12395       350884 :           && gimple_could_trap_p (stmt_info->stmt))
   12396              :         {
   12397              :           /* We've constrained possibly trapping operations to all come
   12398              :              from the same basic-block, if vectorized defs would allow earlier
   12399              :              scheduling still force vectorized stmts to the original block.
   12400              :              This is only necessary for BB vectorization since for loop vect
   12401              :              all operations are in a single BB and scalar stmt based
   12402              :              placement doesn't play well with epilogue vectorization.  */
   12403          678 :           if (last_stmt
   12404         1258 :               && !dominated_by_p (CDI_DOMINATORS,
   12405          580 :                                   gimple_bb (stmt_info->stmt),
   12406          580 :                                   gimple_bb (last_stmt)))
   12407              :             {
   12408            4 :               gcc_assert (place_only);
   12409              :               return false;
   12410              :             }
   12411          674 :           si = gsi_after_labels (gimple_bb (stmt_info->stmt));
   12412          674 :           last_stmt = gsi_stmt (si);
   12413              :         }
   12414              :       /* When there is no in-region child def to guide placement, insert
   12415              :          at region boundary.  */
   12416       324956 :       else if (!last_stmt)
   12417              :         {
   12418         4661 :           si = gsi_after_labels (vinfo->bbs[0]);
   12419              :           /* last_stmt NULL marks the region start.  */
   12420              :         }
   12421       320295 :       else if (is_a <gphi *> (last_stmt))
   12422        31602 :         si = gsi_after_labels (gimple_bb (last_stmt));
   12423              :       else
   12424              :         {
   12425       288693 :           si = gsi_for_stmt (last_stmt);
   12426              :           /* We use gsi_insert_before, so when last_stmt is a vector
   12427              :              def we have to advance (or use gsi_insert_after).  */
   12428       288693 :           gsi_next (&si);
   12429              : 
   12430       288693 :           if (auto loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
   12431              :             {
   12432              :               /* We'll have to fix this up for loop vect.  */
   12433       181030 :               gcc_assert (!place_only);
   12434              :               /* Avoid scheduling stmts to random places in the CFG, any
   12435              :                  stmt dominance check we performed is possibly wrong as UIDs
   12436              :                  are not initialized for all of the function for loop
   12437              :                  vectorization.  Instead append to the loop preheader.  */
   12438       181030 :               if ((LOOP_VINFO_LOOP (loop_vinfo)->header
   12439       181030 :                    != gimple_bb (last_stmt))
   12440       183995 :                   && dominated_by_p (CDI_DOMINATORS,
   12441              :                                      LOOP_VINFO_LOOP (loop_vinfo)->header,
   12442         2965 :                                      gimple_bb (last_stmt)))
   12443         1146 :                 si = gsi_end_bb (loop_preheader_edge
   12444          573 :                                    (LOOP_VINFO_LOOP (loop_vinfo))->src);
   12445              :               /* Avoid scheduling internal defs outside of the loop when
   12446              :                  we might have only implicitly tracked loop mask/len defs.  */
   12447           76 :               if (LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)
   12448       181030 :                   || LOOP_VINFO_FULLY_WITH_LENGTH_P (loop_vinfo))
   12449              :                 {
   12450           76 :                   gimple_stmt_iterator si2
   12451           76 :                     = gsi_after_labels (LOOP_VINFO_LOOP (loop_vinfo)->header);
   12452           76 :                   if ((gsi_end_p (si2)
   12453            0 :                        && (LOOP_VINFO_LOOP (loop_vinfo)->header
   12454            0 :                            != gimple_bb (last_stmt))
   12455            0 :                        && dominated_by_p (CDI_DOMINATORS,
   12456              :                                           LOOP_VINFO_LOOP (loop_vinfo)->header,
   12457            0 :                                           gimple_bb (last_stmt)))
   12458           76 :                       || (!gsi_end_p (si2)
   12459           76 :                           && last_stmt != *si2
   12460           73 :                           && vect_stmt_dominates_stmt_p (last_stmt, *si2)))
   12461            3 :                     si = si2;
   12462              :                 }
   12463              :             }
   12464              :         }
   12465              :     }
   12466              : 
   12467      1921515 :   if (place_only)
   12468              :     {
   12469       944259 :       if (dump_enabled_p () && last_stmt)
   12470         3976 :         dump_printf_loc (MSG_NOTE, vect_location,
   12471              :                          "placing node %p at %G:", (void *)node, last_stmt);
   12472              :       /* Verify we either get a stmt anchor or region start.  */
   12473       944259 :       gcc_assert ((last_stmt && gimple_bb (last_stmt))
   12474              :                   || (!last_stmt && gsi_bb (si)));
   12475       944259 :       node->si = last_stmt;
   12476       944259 :       return true;
   12477              :     }
   12478              : 
   12479              :   /* ???  Asserting vect_stmt_dominates_stmt_p (gsi_stmt (si), node->si)
   12480              :      does not work because in some cases we advance si from last_stmt (as
   12481              :      we want to insert after vector stmts) and because vector stmts of
   12482              :      children have been inserted possibly at the same location constraint,
   12483              :      moving si even further.  */
   12484       977256 :   if (flag_checking && node->si && gimple_bb (node->si) && !gsi_end_p (si))
   12485              :     {
   12486       601850 :       auto gsi2 = si;
   12487       601850 :       while (1)
   12488              :         {
   12489       601850 :           if (vect_stmt_dominates_stmt_p (gsi_stmt (gsi2), node->si))
   12490              :             break;
   12491              :           /* As we have possibly advanced si it might now point to the
   12492              :              scalar stmt immediately following node->si.  That's OK.  */
   12493        23523 :           if (gsi_stmt (gsi2) != gsi_stmt (si)
   12494        23523 :               && gimple_uid (gsi_stmt (gsi2)) != 0)
   12495            0 :             gcc_unreachable ();
   12496        23523 :           gsi_prev (&gsi2);
   12497        23523 :           if (gsi_end_p (gsi2))
   12498              :             {
   12499          537 :               if (is_a <gphi *> (node->si)
   12500          537 :                   && gimple_bb (node->si) == gsi_bb (si))
   12501              :                 break;
   12502            0 :               gcc_unreachable ();
   12503              :             }
   12504              :         }
   12505              :     }
   12506              : 
   12507       977256 :   if (dump_enabled_p ())
   12508              :     {
   12509        74283 :       if (stmt_info)
   12510        70861 :         dump_printf_loc (MSG_NOTE, vect_location,
   12511              :                          "------>vectorizing SLP node starting from: %G",
   12512              :                          stmt_info->stmt);
   12513              :       else
   12514              :         {
   12515         3422 :           dump_printf_loc (MSG_NOTE, vect_location,
   12516              :                            "------>vectorizing SLP node:\n");
   12517         3422 :           vect_print_slp_tree (MSG_NOTE, vect_location, node);
   12518              :         }
   12519              :     }
   12520       977256 :   vect_transform_stmt (vinfo, stmt_info, &si, node, instance);
   12521       977256 :   return true;
   12522              : }
   12523              : 
   12524              : /* Replace scalar calls from SLP node NODE with setting of their lhs to zero.
   12525              :    For loop vectorization this is done in vectorizable_call, but for SLP
   12526              :    it needs to be deferred until end of vect_schedule_slp, because multiple
   12527              :    SLP instances may refer to the same scalar stmt.  */
   12528              : 
   12529              : static void
   12530       623408 : vect_remove_slp_scalar_calls (vec_info *vinfo,
   12531              :                               slp_tree node, hash_set<slp_tree> &visited)
   12532              : {
   12533       623408 :   gimple *new_stmt;
   12534       623408 :   gimple_stmt_iterator gsi;
   12535       623408 :   tree lhs;
   12536              : 
   12537       623408 :   if (!node || SLP_TREE_DEF_TYPE (node) != vect_internal_def)
   12538       197343 :     return;
   12539              : 
   12540       470945 :   if (visited.add (node))
   12541              :     return;
   12542              : 
   12543      1595509 :   for (auto child : SLP_TREE_CHILDREN (node))
   12544       531074 :     vect_remove_slp_scalar_calls (vinfo, child, visited);
   12545              : 
   12546      1770031 :   for (auto stmt_info : SLP_TREE_SCALAR_STMTS (node))
   12547              :     {
   12548       500472 :       if (!stmt_info)
   12549         4140 :         continue;
   12550       496332 :       stmt_info = vect_orig_stmt (stmt_info);
   12551       496332 :       gcall *stmt = dyn_cast <gcall *> (stmt_info->stmt);
   12552         5176 :       if (!stmt || gimple_bb (stmt) == NULL)
   12553       491198 :         continue;
   12554         5134 :       lhs = gimple_call_lhs (stmt);
   12555         5134 :       if (lhs)
   12556         4563 :         new_stmt = gimple_build_assign (lhs, build_zero_cst (TREE_TYPE (lhs)));
   12557              :       else
   12558          571 :         new_stmt = gimple_build_nop ();
   12559         5134 :       unlink_stmt_vdef (stmt_info->stmt);
   12560         5134 :       gsi = gsi_for_stmt (stmt);
   12561         5134 :       vinfo->replace_stmt (&gsi, stmt_info, new_stmt);
   12562         5134 :       if (lhs)
   12563         4563 :         SSA_NAME_DEF_STMT (lhs) = new_stmt;
   12564              :     }
   12565              : }
   12566              : 
   12567              : static void
   12568        92334 : vect_remove_slp_scalar_calls (vec_info *vinfo, slp_tree node)
   12569              : {
   12570        92334 :   hash_set<slp_tree> visited;
   12571        92334 :   vect_remove_slp_scalar_calls (vinfo, node, visited);
   12572        92334 : }
   12573              : 
   12574              : /* Vectorize the instance root.  */
   12575              : 
   12576              : void
   12577         9250 : vectorize_slp_instance_root_stmt (vec_info *vinfo, slp_tree node, slp_instance instance)
   12578              : {
   12579         9250 :   if (instance->kind == slp_inst_kind_ctor)
   12580              :     {
   12581         5525 :       tree new_def;
   12582         5525 :       if (SLP_TREE_VEC_DEFS (node).length () == 1)
   12583              :         {
   12584         5480 :           new_def = SLP_TREE_VEC_DEFS (node)[0];
   12585         5480 :           tree root_lhs = gimple_get_lhs (instance->root_stmts[0]->stmt);
   12586         5480 :           if (!useless_type_conversion_p (TREE_TYPE (root_lhs),
   12587         5480 :                                           TREE_TYPE (new_def)))
   12588            0 :             new_def = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (root_lhs),
   12589              :                                new_def);
   12590              :         }
   12591              :       else
   12592              :         {
   12593           45 :           gcc_assert (SLP_TREE_VEC_DEFS (node).length () > 1);
   12594           45 :           tree child_def;
   12595           45 :           int j;
   12596           45 :           vec<constructor_elt, va_gc> *v;
   12597           45 :           vec_alloc (v, SLP_TREE_VEC_DEFS (node).length ());
   12598              : 
   12599              :           /* A CTOR can handle V16HI composition from VNx8HI so we
   12600              :              do not need to convert vector elements if the types
   12601              :              do not match.  */
   12602          180 :           FOR_EACH_VEC_ELT (SLP_TREE_VEC_DEFS (node), j, child_def)
   12603           90 :             CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, child_def);
   12604           45 :           tree rtype
   12605           45 :             = TREE_TYPE (gimple_assign_rhs1 (instance->root_stmts[0]->stmt));
   12606           45 :           new_def = build_constructor (rtype, v);
   12607              :         }
   12608              : 
   12609         5525 :       gimple_stmt_iterator rgsi = gsi_for_stmt (instance->root_stmts[0]->stmt);
   12610         5525 :       gimple_assign_set_rhs_from_tree (&rgsi, new_def);
   12611         5525 :       update_stmt (gsi_stmt (rgsi));
   12612         5525 :       return;
   12613              :     }
   12614         3725 :   else if (instance->kind == slp_inst_kind_bb_reduc)
   12615              :     {
   12616              :       /* Largely inspired by reduction chain epilogue handling in
   12617              :          vect_create_epilog_for_reduction.  */
   12618         2129 :       vec<tree> vec_defs = vNULL;
   12619         2129 :       vect_get_slp_defs (node, &vec_defs);
   12620         2129 :       enum tree_code reduc_code
   12621         2129 :         = gimple_assign_rhs_code (instance->root_stmts[0]->stmt);
   12622              :       /* ???  We actually have to reflect signs somewhere.  */
   12623         2129 :       if (reduc_code == MINUS_EXPR)
   12624            0 :         reduc_code = PLUS_EXPR;
   12625         2129 :       gimple_seq epilogue = NULL;
   12626              :       /* We may end up with more than one vector result, reduce them
   12627              :          to one vector.  */
   12628         2129 :       tree vec_def = vec_defs[0];
   12629         2129 :       tree vectype = TREE_TYPE (vec_def);
   12630         2129 :       tree compute_vectype = vectype;
   12631         2129 :       bool pun_for_overflow_p = (ANY_INTEGRAL_TYPE_P (vectype)
   12632          968 :                                  && TYPE_OVERFLOW_UNDEFINED (vectype)
   12633         2714 :                                  && operation_can_overflow (reduc_code));
   12634          437 :       if (pun_for_overflow_p)
   12635              :         {
   12636          437 :           compute_vectype = unsigned_type_for (vectype);
   12637          437 :           vec_def = gimple_build (&epilogue, VIEW_CONVERT_EXPR,
   12638              :                                   compute_vectype, vec_def);
   12639              :         }
   12640         2394 :       for (unsigned i = 1; i < vec_defs.length (); ++i)
   12641              :         {
   12642          265 :           tree def = vec_defs[i];
   12643          265 :           if (pun_for_overflow_p)
   12644           39 :             def = gimple_build (&epilogue, VIEW_CONVERT_EXPR,
   12645              :                                 compute_vectype, def);
   12646          265 :           vec_def = gimple_build (&epilogue, reduc_code, compute_vectype,
   12647              :                                   vec_def, def);
   12648              :         }
   12649         2129 :       vec_defs.release ();
   12650              :       /* ???  Support other schemes than direct internal fn or two
   12651              :          element vectors.  */
   12652         2129 :       tree scalar_def;
   12653         2129 :       internal_fn reduc_fn;
   12654         3105 :       if (!reduction_fn_for_scalar_code (reduc_code, &reduc_fn)
   12655         2129 :           || reduc_fn == IFN_LAST
   12656         4258 :           || !direct_internal_fn_supported_p (reduc_fn, compute_vectype,
   12657              :                                               OPTIMIZE_FOR_BOTH))
   12658              :         {
   12659          976 :           gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (compute_vectype), 2u));
   12660          976 :           tree tem0 = gimple_build (&epilogue, BIT_FIELD_REF,
   12661          976 :                                     TREE_TYPE (compute_vectype), vec_def,
   12662          976 :                                     TYPE_SIZE (TREE_TYPE (compute_vectype)),
   12663          976 :                                     bitsize_zero_node);
   12664          976 :           tree tem1 = gimple_build (&epilogue, BIT_FIELD_REF,
   12665          976 :                                     TREE_TYPE (compute_vectype), vec_def,
   12666          976 :                                     TYPE_SIZE (TREE_TYPE (compute_vectype)),
   12667          976 :                                     TYPE_SIZE (TREE_TYPE (compute_vectype)));
   12668          976 :           scalar_def = gimple_build (&epilogue, reduc_code,
   12669          976 :                                      TREE_TYPE (compute_vectype), tem0, tem1);
   12670              :         }
   12671              :       else
   12672         1153 :         scalar_def = gimple_build (&epilogue, as_combined_fn (reduc_fn),
   12673         1153 :                                    TREE_TYPE (compute_vectype), vec_def);
   12674         2129 :       if (!SLP_INSTANCE_REMAIN_DEFS (instance).is_empty ())
   12675              :         {
   12676          850 :           tree rem_def = NULL_TREE;
   12677         1984 :           for (auto def : SLP_INSTANCE_REMAIN_DEFS (instance))
   12678              :             {
   12679         1134 :               def = gimple_convert (&epilogue, TREE_TYPE (scalar_def), def);
   12680         1134 :               if (!rem_def)
   12681              :                 rem_def = def;
   12682              :               else
   12683          284 :                 rem_def = gimple_build (&epilogue, reduc_code,
   12684          284 :                                         TREE_TYPE (scalar_def),
   12685              :                                         rem_def, def);
   12686              :             }
   12687          850 :           scalar_def = gimple_build (&epilogue, reduc_code,
   12688          850 :                                      TREE_TYPE (scalar_def),
   12689              :                                      scalar_def, rem_def);
   12690              :         }
   12691         2129 :       scalar_def = gimple_convert (&epilogue,
   12692         2129 :                                    TREE_TYPE (vectype), scalar_def);
   12693         2129 :       gimple_stmt_iterator rgsi = gsi_for_stmt (instance->root_stmts[0]->stmt);
   12694         2129 :       gsi_insert_seq_before (&rgsi, epilogue, GSI_SAME_STMT);
   12695         2129 :       gimple_assign_set_rhs_from_tree (&rgsi, scalar_def);
   12696         2129 :       update_stmt (gsi_stmt (rgsi));
   12697         2129 :       return;
   12698              :     }
   12699         1596 :   else if (instance->kind == slp_inst_kind_gcond)
   12700              :     {
   12701              :       /* Only support a single root for now as we can't codegen CFG yet and so we
   12702              :          can't support lane > 1 at this time.  */
   12703         1596 :       gcc_assert (instance->root_stmts.length () == 1);
   12704         1596 :       auto root_stmt_info = instance->root_stmts[0];
   12705         1596 :       auto last_stmt = STMT_VINFO_STMT (vect_orig_stmt (root_stmt_info));
   12706         1596 :       gimple_stmt_iterator rgsi = gsi_for_stmt (last_stmt);
   12707         1596 :       gcc_assert (!SLP_TREE_VEC_DEFS (node).is_empty ());
   12708         1596 :       bool res = vectorizable_early_exit (as_a <loop_vec_info> (vinfo),
   12709              :                                           root_stmt_info, &rgsi, node, NULL);
   12710         1596 :       gcc_assert (res);
   12711         1596 :       return;
   12712              :     }
   12713              :   else
   12714            0 :     gcc_unreachable ();
   12715              : }
   12716              : 
   12717              : struct slp_scc_info
   12718              : {
   12719              :   bool on_stack;
   12720              :   bool res;
   12721              :   int dfs;
   12722              :   int lowlink;
   12723              : };
   12724              : 
   12725              : /* Schedule the SLP INSTANCE doing a DFS walk and collecting SCCs.
   12726              :    When PLACE_ONLY, return false if there is no possible schedule.  */
   12727              : 
   12728              : static bool
   12729      3135925 : vect_schedule_scc (vec_info *vinfo, slp_tree node, slp_instance instance,
   12730              :                    hash_map<slp_tree, slp_scc_info> &scc_info,
   12731              :                    int &maxdfs, vec<slp_tree> &stack, bool place_only)
   12732              : {
   12733      3135925 :   bool existed_p;
   12734      3135925 :   slp_scc_info *info = &scc_info.get_or_insert (node, &existed_p);
   12735      3135925 :   gcc_assert (!existed_p);
   12736      3135925 :   info->dfs = maxdfs;
   12737      3135925 :   info->lowlink = maxdfs;
   12738      3135925 :   maxdfs++;
   12739              : 
   12740              :   /* Leaf.  */
   12741      3135925 :   if (SLP_TREE_DEF_TYPE (node) != vect_internal_def)
   12742              :     {
   12743      1214398 :       info->on_stack = false;
   12744      1214398 :       bool res = vect_schedule_slp_node (vinfo, node, instance, place_only);
   12745      1214398 :       gcc_assert (res);
   12746      1214398 :       info->res = res;
   12747      1214398 :       return res;
   12748              :     }
   12749              : 
   12750      1921527 :   info->on_stack = true;
   12751      1921527 :   info->res = true;
   12752      1921527 :   stack.safe_push (node);
   12753              : 
   12754      1921527 :   bool res = true;
   12755      1921527 :   unsigned i;
   12756      1921527 :   slp_tree child;
   12757              :   /* DFS recurse.  */
   12758      7533450 :   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
   12759              :     {
   12760      2040150 :       if (!child)
   12761        56398 :         continue;
   12762      1983752 :       slp_scc_info *child_info = scc_info.get (child);
   12763      1983752 :       if (!child_info)
   12764              :         {
   12765      1834155 :           res &= vect_schedule_scc (vinfo, child, instance, scc_info,
   12766              :                                     maxdfs, stack, place_only);
   12767              :           /* Recursion might have re-allocated the node.  */
   12768      1834155 :           info = scc_info.get (node);
   12769      1834155 :           child_info = scc_info.get (child);
   12770      1834155 :           info->lowlink = MIN (info->lowlink, child_info->lowlink);
   12771              :         }
   12772       149597 :       else if (child_info->on_stack)
   12773        35528 :         info->lowlink = MIN (info->lowlink, child_info->dfs);
   12774              :       else
   12775       114069 :         res &= child_info->res;
   12776              :     }
   12777      1921527 :   if (info->lowlink != info->dfs)
   12778              :     return res;
   12779              : 
   12780      1882124 :   auto_vec<slp_tree, 4> phis_to_fixup;
   12781              : 
   12782              :   /* Singleton.  */
   12783      1882124 :   if (stack.last () == node)
   12784              :     {
   12785      1853229 :       stack.pop ();
   12786      1853229 :       info->on_stack = false;
   12787      1853229 :       res &= vect_schedule_slp_node (vinfo, node, instance, place_only);
   12788      1853229 :       info->res = res;
   12789      1853229 :       if (!SLP_TREE_PERMUTE_P (node)
   12790      1853229 :           && is_a <gphi *> (SLP_TREE_REPRESENTATIVE (node)->stmt))
   12791        71784 :         phis_to_fixup.quick_push (node);
   12792              :     }
   12793              :   else
   12794              :     {
   12795              :       /* SCC.  */
   12796        28895 :       int last_idx = stack.length () - 1;
   12797        68298 :       while (stack[last_idx] != node)
   12798        39403 :         last_idx--;
   12799              :       /* We can break the cycle at PHIs who have at least one child
   12800              :          code generated.  Then we could re-start the DFS walk until
   12801              :          all nodes in the SCC are covered (we might have new entries
   12802              :          for only back-reachable nodes).  But it's simpler to just
   12803              :          iterate and schedule those that are ready.  */
   12804        28895 :       unsigned todo = stack.length () - last_idx;
   12805        28895 :       auto_vec<slp_tree, 4> saved_scc (todo);
   12806        28895 :       saved_scc.quick_grow (todo);
   12807        86685 :       memcpy (saved_scc.address (), &stack.address ()[last_idx],
   12808              :               sizeof (slp_tree) * todo);
   12809        29703 :       do
   12810              :         {
   12811       131927 :           for (int idx = stack.length () - 1; idx >= last_idx; --idx)
   12812              :             {
   12813        72521 :               slp_tree entry = stack[idx];
   12814        72521 :               if (!entry)
   12815         2553 :                 continue;
   12816        69968 :               bool phi = (!SLP_TREE_PERMUTE_P (entry)
   12817        69968 :                           && is_a <gphi *> (SLP_TREE_REPRESENTATIVE (entry)->stmt));
   12818        69968 :               bool ready = !phi;
   12819       212874 :               FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (entry), i, child)
   12820       132720 :                 if (!child)
   12821              :                   {
   12822        22932 :                     gcc_assert (phi);
   12823              :                     ready = true;
   12824              :                     break;
   12825              :                   }
   12826       109788 :                 else if (scc_info.get (child)->on_stack)
   12827              :                   {
   12828        30787 :                     if (!phi)
   12829              :                       {
   12830              :                         ready = false;
   12831              :                         break;
   12832              :                       }
   12833              :                   }
   12834              :                 else
   12835              :                   {
   12836        79001 :                     if (phi)
   12837              :                       {
   12838              :                         ready = true;
   12839              :                         break;
   12840              :                       }
   12841              :                   }
   12842        47036 :               if (ready)
   12843              :                 {
   12844        68298 :                   res &= vect_schedule_slp_node (vinfo, entry, instance,
   12845              :                                                  place_only);
   12846        68298 :                   scc_info.get (entry)->on_stack = false;
   12847        68298 :                   stack[idx] = NULL;
   12848        68298 :                   todo--;
   12849        68298 :                   if (phi)
   12850        35356 :                     phis_to_fixup.safe_push (entry);
   12851              :                 }
   12852              :             }
   12853              :         }
   12854        29703 :       while (todo != 0);
   12855              : 
   12856              :       /* Push the scheduling result to all of the SCC.  */
   12857       154983 :       for (slp_tree entry : saved_scc)
   12858        68298 :         scc_info.get (entry)->res = res;
   12859              : 
   12860              :       /* Pop the SCC.  */
   12861        28895 :       stack.truncate (last_idx);
   12862        28895 :     }
   12863              : 
   12864      1882124 :   if (place_only)
   12865              :     return res;
   12866              : 
   12867              :   /* Now fixup the backedge def of the vectorized PHIs in this SCC.  */
   12868              :   slp_tree phi_node;
   12869       999250 :   FOR_EACH_VEC_ELT (phis_to_fixup, i, phi_node)
   12870              :     {
   12871        53775 :       gphi *phi = as_a <gphi *> (SLP_TREE_REPRESENTATIVE (phi_node)->stmt);
   12872        53775 :       edge_iterator ei;
   12873        53775 :       edge e;
   12874       167552 :       FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
   12875              :         {
   12876       113777 :           unsigned dest_idx = e->dest_idx;
   12877       113777 :           child = SLP_TREE_CHILDREN (phi_node)[dest_idx];
   12878       113777 :           if (!child || SLP_TREE_DEF_TYPE (child) != vect_internal_def)
   12879        66380 :             continue;
   12880        47397 :           unsigned n = SLP_TREE_VEC_DEFS (phi_node).length ();
   12881              :           /* Simply fill all args.  */
   12882        47397 :           if (STMT_VINFO_DEF_TYPE (SLP_TREE_REPRESENTATIVE (phi_node))
   12883              :               != vect_first_order_recurrence)
   12884       100182 :             for (unsigned i = 0; i < n; ++i)
   12885              :               {
   12886        52828 :                 tree phidef = SLP_TREE_VEC_DEFS (phi_node)[i];
   12887        52828 :                 gphi *phi = as_a <gphi *> (SSA_NAME_DEF_STMT (phidef));
   12888        52828 :                 add_phi_arg (phi, vect_get_slp_vect_def (child, i),
   12889              :                              e, gimple_phi_arg_location (phi, dest_idx));
   12890              :               }
   12891              :           else
   12892              :             {
   12893              :               /* Unless it is a first order recurrence which needs
   12894              :                  args filled in for both the PHI node and the permutes.  */
   12895           43 :               gimple *perm
   12896           43 :                 = SSA_NAME_DEF_STMT (SLP_TREE_VEC_DEFS (phi_node)[0]);
   12897           43 :               gimple *rphi = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (perm));
   12898           43 :               add_phi_arg (as_a <gphi *> (rphi),
   12899              :                            vect_get_slp_vect_def (child, n - 1),
   12900              :                            e, gimple_phi_arg_location (phi, dest_idx));
   12901          166 :               for (unsigned i = 0; i < n; ++i)
   12902              :                 {
   12903           80 :                   gimple *perm
   12904           80 :                     = SSA_NAME_DEF_STMT (SLP_TREE_VEC_DEFS (phi_node)[i]);
   12905           80 :                   if (i > 0)
   12906           37 :                     gimple_assign_set_rhs1 (perm,
   12907              :                                             vect_get_slp_vect_def (child, i - 1));
   12908           80 :                   gimple_assign_set_rhs2 (perm,
   12909              :                                           vect_get_slp_vect_def (child, i));
   12910           80 :                   update_stmt (perm);
   12911              :                 }
   12912              :             }
   12913              :         }
   12914              :     }
   12915              : 
   12916       945475 :   gcc_assert (res);
   12917              :   return true;
   12918      1882124 : }
   12919              : 
   12920              : /* Generate vector code for SLP_INSTANCES in the loop/basic block.  Perform
   12921              :    vector stmt placement only when PLACE_ONLY is true, removing SLP graph
   12922              :    entries that cannot be scheduled.  If placing, return false if a schedule
   12923              :    cannot be computed for any entry.  */
   12924              : 
   12925              : bool
   12926       793397 : vect_schedule_slp (vec_info *vinfo, vec<slp_instance> &slp_instances,
   12927              :                    bool place_only)
   12928              : {
   12929       793397 :   slp_instance instance;
   12930       793397 :   unsigned int i;
   12931              : 
   12932       793397 :   hash_map<slp_tree, slp_scc_info> scc_info;
   12933       793397 :   int maxdfs = 0;
   12934      2099023 :   for (i = 0; slp_instances.iterate (i, &instance); )
   12935              :     {
   12936      1305626 :       slp_tree node = SLP_INSTANCE_TREE (instance);
   12937      1305626 :       if (!place_only && dump_enabled_p ())
   12938              :         {
   12939        16561 :           dump_printf_loc (MSG_NOTE, vect_location,
   12940              :                            "Vectorizing SLP tree:\n");
   12941              :           /* ???  Dump all?  */
   12942        16561 :           if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ())
   12943          520 :             dump_printf_loc (MSG_NOTE, vect_location, "Root stmt: %G",
   12944          520 :                          SLP_INSTANCE_ROOT_STMTS (instance)[0]->stmt);
   12945        16561 :           vect_print_slp_graph (MSG_NOTE, vect_location,
   12946              :                                 SLP_INSTANCE_TREE (instance));
   12947              :         }
   12948              :       /* Schedule the tree of INSTANCE, scheduling SCCs in a way to
   12949              :          have a PHI be the node breaking the cycle.  */
   12950      1305626 :       bool res;
   12951      1305626 :       if (slp_scc_info *info = scc_info.get (node))
   12952         3856 :         res = info->res;
   12953              :       else
   12954              :         {
   12955      1301770 :           auto_vec<slp_tree> stack;
   12956      1301770 :           res = vect_schedule_scc (vinfo, node, instance, scc_info,
   12957              :                                    maxdfs, stack, place_only);
   12958      1301770 :         }
   12959              : 
   12960      1305626 :       if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ())
   12961              :         {
   12962        61965 :           if (place_only)
   12963              :             {
   12964        52715 :               gimple *root_stmt = instance->root_stmts[0]->stmt;
   12965        52715 :               res &= (!node->si
   12966              :                       /* As we instert after node->si it may not be the
   12967              :                          root_stmt itself.  */
   12968        52715 :                       || (node->si != root_stmt
   12969        51821 :                           && vect_stmt_dominates_stmt_p (node->si, root_stmt)));
   12970              :             }
   12971              :           else
   12972         9250 :             vectorize_slp_instance_root_stmt (vinfo, node, instance);
   12973              :         }
   12974              : 
   12975      1305626 :       if (!place_only && dump_enabled_p ())
   12976        16561 :         dump_printf_loc (MSG_NOTE, vect_location,
   12977              :                          "vectorizing stmts using SLP.\n");
   12978              : 
   12979      1305626 :       if (!res)
   12980              :         {
   12981           38 :           gcc_assert (place_only);
   12982           38 :           if (dump_enabled_p ())
   12983           24 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
   12984              :                              "not vectorized: cannot schedule SLP graph "
   12985              :                              "entry %p\n", (void *)instance);
   12986           38 :           vect_free_slp_instance (instance);
   12987           38 :           slp_instances.ordered_remove (i);
   12988           38 :           continue;
   12989              :         }
   12990      1305588 :       ++i;
   12991              :     }
   12992              : 
   12993       793397 :   if (place_only)
   12994       497242 :     return !slp_instances.is_empty ();
   12995              : 
   12996      1923029 :   FOR_EACH_VEC_ELT (slp_instances, i, instance)
   12997              :     {
   12998       584856 :       slp_tree root = SLP_INSTANCE_TREE (instance);
   12999       584856 :       stmt_vec_info store_info;
   13000       584856 :       unsigned int j;
   13001              : 
   13002              :       /* Remove scalar call stmts.  Do not do this for basic-block
   13003              :          vectorization as not all uses may be vectorized.
   13004              :          ???  Why should this be necessary?  DCE should be able to
   13005              :          remove the stmts itself.
   13006              :          ???  For BB vectorization we can as well remove scalar
   13007              :          stmts starting from the SLP tree root if they have no
   13008              :          uses.  */
   13009       584856 :       if (is_a <loop_vec_info> (vinfo))
   13010        92334 :         vect_remove_slp_scalar_calls (vinfo, root);
   13011              : 
   13012              :       /* Remove vectorized stores original scalar stmts.  */
   13013      2617192 :       for (j = 0; SLP_TREE_SCALAR_STMTS (root).iterate (j, &store_info); j++)
   13014              :         {
   13015      1482057 :           if (!store_info
   13016      1482040 :               || !STMT_VINFO_DATA_REF (store_info)
   13017      1453262 :               || !DR_IS_WRITE (STMT_VINFO_DATA_REF (store_info)))
   13018              :             break;
   13019              : 
   13020      1447480 :           store_info = vect_orig_stmt (store_info);
   13021              :           /* Free the attached stmt_vec_info and remove the stmt.  */
   13022      1447480 :           vinfo->remove_stmt (store_info);
   13023              : 
   13024              :           /* Invalidate SLP_TREE_REPRESENTATIVE in case we released it
   13025              :              to not crash in vect_free_slp_tree later.  */
   13026      1447480 :           if (SLP_TREE_REPRESENTATIVE (root) == store_info)
   13027       549948 :             SLP_TREE_REPRESENTATIVE (root) = NULL;
   13028              :         }
   13029              :     }
   13030              : 
   13031              :   return true;
   13032       793397 : }
        

Generated by: LCOV version 2.5.0-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.