Home | History | Annotate | Line # | Download | only in gcc
      1 /* Vectorizer
      2    Copyright (C) 2003-2024 Free Software Foundation, Inc.
      3    Contributed by Dorit Naishlos <dorit (at) il.ibm.com>
      4 
      5 This file is part of GCC.
      6 
      7 GCC is free software; you can redistribute it and/or modify it under
      8 the terms of the GNU General Public License as published by the Free
      9 Software Foundation; either version 3, or (at your option) any later
     10 version.
     11 
     12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15 for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with GCC; see the file COPYING3.  If not see
     19 <http://www.gnu.org/licenses/>.  */
     20 
     21 #ifndef GCC_TREE_VECTORIZER_H
     22 #define GCC_TREE_VECTORIZER_H
     23 
     24 typedef class _stmt_vec_info *stmt_vec_info;
     25 typedef struct _slp_tree *slp_tree;
     26 
     27 #include "tree-data-ref.h"
     28 #include "tree-hash-traits.h"
     29 #include "target.h"
     30 #include "internal-fn.h"
     31 #include "tree-ssa-operands.h"
     32 #include "gimple-match.h"
     33 
     34 /* Used for naming of new temporaries.  */
     35 enum vect_var_kind {
     36   vect_simple_var,
     37   vect_pointer_var,
     38   vect_scalar_var,
     39   vect_mask_var
     40 };
     41 
     42 /* Defines type of operation.  */
     43 enum operation_type {
     44   unary_op = 1,
     45   binary_op,
     46   ternary_op
     47 };
     48 
     49 /* Define type of available alignment support.  */
     50 enum dr_alignment_support {
     51   dr_unaligned_unsupported,
     52   dr_unaligned_supported,
     53   dr_explicit_realign,
     54   dr_explicit_realign_optimized,
     55   dr_aligned
     56 };
     57 
     58 /* Define type of def-use cross-iteration cycle.  */
     59 enum vect_def_type {
     60   vect_uninitialized_def = 0,
     61   vect_constant_def = 1,
     62   vect_external_def,
     63   vect_internal_def,
     64   vect_induction_def,
     65   vect_reduction_def,
     66   vect_double_reduction_def,
     67   vect_nested_cycle,
     68   vect_first_order_recurrence,
     69   vect_condition_def,
     70   vect_unknown_def_type
     71 };
     72 
     73 /* Define operation type of linear/non-linear induction variable.  */
     74 enum vect_induction_op_type {
     75    vect_step_op_add = 0,
     76    vect_step_op_neg,
     77    vect_step_op_mul,
     78    vect_step_op_shl,
     79    vect_step_op_shr
     80 };
     81 
     82 /* Define type of reduction.  */
     83 enum vect_reduction_type {
     84   TREE_CODE_REDUCTION,
     85   COND_REDUCTION,
     86   INTEGER_INDUC_COND_REDUCTION,
     87   CONST_COND_REDUCTION,
     88 
     89   /* Retain a scalar phi and use a FOLD_EXTRACT_LAST within the loop
     90      to implement:
     91 
     92        for (int i = 0; i < VF; ++i)
     93          res = cond[i] ? val[i] : res;  */
     94   EXTRACT_LAST_REDUCTION,
     95 
     96   /* Use a folding reduction within the loop to implement:
     97 
     98        for (int i = 0; i < VF; ++i)
     99 	 res = res OP val[i];
    100 
    101      (with no reassocation).  */
    102   FOLD_LEFT_REDUCTION
    103 };
    104 
    105 #define VECTORIZABLE_CYCLE_DEF(D) (((D) == vect_reduction_def)           \
    106                                    || ((D) == vect_double_reduction_def) \
    107                                    || ((D) == vect_nested_cycle))
    108 
    109 /* Structure to encapsulate information about a group of like
    110    instructions to be presented to the target cost model.  */
    111 struct stmt_info_for_cost {
    112   int count;
    113   enum vect_cost_for_stmt kind;
    114   enum vect_cost_model_location where;
    115   stmt_vec_info stmt_info;
    116   slp_tree node;
    117   tree vectype;
    118   int misalign;
    119 };
    120 
    121 typedef vec<stmt_info_for_cost> stmt_vector_for_cost;
    122 
    123 /* Maps base addresses to an innermost_loop_behavior and the stmt it was
    124    derived from that gives the maximum known alignment for that base.  */
    125 typedef hash_map<tree_operand_hash,
    126 		 std::pair<stmt_vec_info, innermost_loop_behavior *> >
    127 	  vec_base_alignments;
    128 
    129 /* Represents elements [START, START + LENGTH) of cyclical array OPS*
    130    (i.e. OPS repeated to give at least START + LENGTH elements)  */
    131 struct vect_scalar_ops_slice
    132 {
    133   tree op (unsigned int i) const;
    134   bool all_same_p () const;
    135 
    136   vec<tree> *ops;
    137   unsigned int start;
    138   unsigned int length;
    139 };
    140 
    141 /* Return element I of the slice.  */
    142 inline tree
    143 vect_scalar_ops_slice::op (unsigned int i) const
    144 {
    145   return (*ops)[(i + start) % ops->length ()];
    146 }
    147 
    148 /* Hash traits for vect_scalar_ops_slice.  */
    149 struct vect_scalar_ops_slice_hash : typed_noop_remove<vect_scalar_ops_slice>
    150 {
    151   typedef vect_scalar_ops_slice value_type;
    152   typedef vect_scalar_ops_slice compare_type;
    153 
    154   static const bool empty_zero_p = true;
    155 
    156   static void mark_deleted (value_type &s) { s.length = ~0U; }
    157   static void mark_empty (value_type &s) { s.length = 0; }
    158   static bool is_deleted (const value_type &s) { return s.length == ~0U; }
    159   static bool is_empty (const value_type &s) { return s.length == 0; }
    160   static hashval_t hash (const value_type &);
    161   static bool equal (const value_type &, const compare_type &);
    162 };
    163 
    164 /************************************************************************
    165   SLP
    166  ************************************************************************/
    167 typedef vec<std::pair<unsigned, unsigned> > lane_permutation_t;
    168 typedef auto_vec<std::pair<unsigned, unsigned>, 16> auto_lane_permutation_t;
    169 typedef vec<unsigned> load_permutation_t;
    170 typedef auto_vec<unsigned, 16> auto_load_permutation_t;
    171 
    172 /* A computation tree of an SLP instance.  Each node corresponds to a group of
    173    stmts to be packed in a SIMD stmt.  */
    174 struct _slp_tree {
    175   _slp_tree ();
    176   ~_slp_tree ();
    177 
    178   void push_vec_def (gimple *def);
    179   void push_vec_def (tree def) { vec_defs.quick_push (def); }
    180 
    181   /* Nodes that contain def-stmts of this node statements operands.  */
    182   vec<slp_tree> children;
    183 
    184   /* A group of scalar stmts to be vectorized together.  */
    185   vec<stmt_vec_info> stmts;
    186   /* A group of scalar operands to be vectorized together.  */
    187   vec<tree> ops;
    188   /* The representative that should be used for analysis and
    189      code generation.  */
    190   stmt_vec_info representative;
    191 
    192   /* Load permutation relative to the stores, NULL if there is no
    193      permutation.  */
    194   load_permutation_t load_permutation;
    195   /* Lane permutation of the operands scalar lanes encoded as pairs
    196      of { operand number, lane number }.  The number of elements
    197      denotes the number of output lanes.  */
    198   lane_permutation_t lane_permutation;
    199 
    200   /* Selected SIMD clone's function info.  First vector element
    201      is SIMD clone's function decl, followed by a pair of trees (base + step)
    202      for linear arguments (pair of NULLs for other arguments).  */
    203   vec<tree> simd_clone_info;
    204 
    205   tree vectype;
    206   /* Vectorized defs.  */
    207   vec<tree> vec_defs;
    208   /* Number of vector stmts that are created to replace the group of scalar
    209      stmts. It is calculated during the transformation phase as the number of
    210      scalar elements in one scalar iteration (GROUP_SIZE) multiplied by VF
    211      divided by vector size.  */
    212   unsigned int vec_stmts_size;
    213 
    214   /* Reference count in the SLP graph.  */
    215   unsigned int refcnt;
    216   /* The maximum number of vector elements for the subtree rooted
    217      at this node.  */
    218   poly_uint64 max_nunits;
    219   /* The DEF type of this node.  */
    220   enum vect_def_type def_type;
    221   /* The number of scalar lanes produced by this node.  */
    222   unsigned int lanes;
    223   /* The operation of this node.  */
    224   enum tree_code code;
    225 
    226   int vertex;
    227 
    228   /* If not NULL this is a cached failed SLP discovery attempt with
    229      the lanes that failed during SLP discovery as 'false'.  This is
    230      a copy of the matches array.  */
    231   bool *failed;
    232 
    233   /* Allocate from slp_tree_pool.  */
    234   static void *operator new (size_t);
    235 
    236   /* Return memory to slp_tree_pool.  */
    237   static void operator delete (void *, size_t);
    238 
    239   /* Linked list of nodes to release when we free the slp_tree_pool.  */
    240   slp_tree next_node;
    241   slp_tree prev_node;
    242 };
    243 
    244 /* The enum describes the type of operations that an SLP instance
    245    can perform. */
    246 
    247 enum slp_instance_kind {
    248     slp_inst_kind_store,
    249     slp_inst_kind_reduc_group,
    250     slp_inst_kind_reduc_chain,
    251     slp_inst_kind_bb_reduc,
    252     slp_inst_kind_ctor
    253 };
    254 
    255 /* SLP instance is a sequence of stmts in a loop that can be packed into
    256    SIMD stmts.  */
    257 typedef class _slp_instance {
    258 public:
    259   /* The root of SLP tree.  */
    260   slp_tree root;
    261 
    262   /* For vector constructors, the constructor stmt that the SLP tree is built
    263      from, NULL otherwise.  */
    264   vec<stmt_vec_info> root_stmts;
    265 
    266   /* For slp_inst_kind_bb_reduc the defs that were not vectorized, NULL
    267      otherwise.  */
    268   vec<tree> remain_defs;
    269 
    270   /* The unrolling factor required to vectorized this SLP instance.  */
    271   poly_uint64 unrolling_factor;
    272 
    273   /* The group of nodes that contain loads of this SLP instance.  */
    274   vec<slp_tree> loads;
    275 
    276   /* The SLP node containing the reduction PHIs.  */
    277   slp_tree reduc_phis;
    278 
    279   /* Vector cost of this entry to the SLP graph.  */
    280   stmt_vector_for_cost cost_vec;
    281 
    282   /* If this instance is the main entry of a subgraph the set of
    283      entries into the same subgraph, including itself.  */
    284   vec<_slp_instance *> subgraph_entries;
    285 
    286   /* The type of operation the SLP instance is performing.  */
    287   slp_instance_kind kind;
    288 
    289   dump_user_location_t location () const;
    290 } *slp_instance;
    291 
    292 
    293 /* Access Functions.  */
    294 #define SLP_INSTANCE_TREE(S)                     (S)->root
    295 #define SLP_INSTANCE_UNROLLING_FACTOR(S)         (S)->unrolling_factor
    296 #define SLP_INSTANCE_LOADS(S)                    (S)->loads
    297 #define SLP_INSTANCE_ROOT_STMTS(S)               (S)->root_stmts
    298 #define SLP_INSTANCE_REMAIN_DEFS(S)              (S)->remain_defs
    299 #define SLP_INSTANCE_KIND(S)                     (S)->kind
    300 
    301 #define SLP_TREE_CHILDREN(S)                     (S)->children
    302 #define SLP_TREE_SCALAR_STMTS(S)                 (S)->stmts
    303 #define SLP_TREE_SCALAR_OPS(S)                   (S)->ops
    304 #define SLP_TREE_REF_COUNT(S)                    (S)->refcnt
    305 #define SLP_TREE_VEC_DEFS(S)                     (S)->vec_defs
    306 #define SLP_TREE_NUMBER_OF_VEC_STMTS(S)          (S)->vec_stmts_size
    307 #define SLP_TREE_LOAD_PERMUTATION(S)             (S)->load_permutation
    308 #define SLP_TREE_LANE_PERMUTATION(S)             (S)->lane_permutation
    309 #define SLP_TREE_SIMD_CLONE_INFO(S)              (S)->simd_clone_info
    310 #define SLP_TREE_DEF_TYPE(S)			 (S)->def_type
    311 #define SLP_TREE_VECTYPE(S)			 (S)->vectype
    312 #define SLP_TREE_REPRESENTATIVE(S)		 (S)->representative
    313 #define SLP_TREE_LANES(S)			 (S)->lanes
    314 #define SLP_TREE_CODE(S)			 (S)->code
    315 
    316 enum vect_partial_vector_style {
    317     vect_partial_vectors_none,
    318     vect_partial_vectors_while_ult,
    319     vect_partial_vectors_avx512,
    320     vect_partial_vectors_len
    321 };
    322 
    323 /* Key for map that records association between
    324    scalar conditions and corresponding loop mask, and
    325    is populated by vect_record_loop_mask.  */
    326 
    327 struct scalar_cond_masked_key
    328 {
    329   scalar_cond_masked_key (tree t, unsigned ncopies_)
    330     : ncopies (ncopies_)
    331   {
    332     get_cond_ops_from_tree (t);
    333   }
    334 
    335   void get_cond_ops_from_tree (tree);
    336 
    337   unsigned ncopies;
    338   bool inverted_p;
    339   tree_code code;
    340   tree op0;
    341   tree op1;
    342 };
    343 
    344 template<>
    345 struct default_hash_traits<scalar_cond_masked_key>
    346 {
    347   typedef scalar_cond_masked_key compare_type;
    348   typedef scalar_cond_masked_key value_type;
    349 
    350   static inline hashval_t
    351   hash (value_type v)
    352   {
    353     inchash::hash h;
    354     h.add_int (v.code);
    355     inchash::add_expr (v.op0, h, 0);
    356     inchash::add_expr (v.op1, h, 0);
    357     h.add_int (v.ncopies);
    358     h.add_flag (v.inverted_p);
    359     return h.end ();
    360   }
    361 
    362   static inline bool
    363   equal (value_type existing, value_type candidate)
    364   {
    365     return (existing.ncopies == candidate.ncopies
    366 	    && existing.code == candidate.code
    367 	    && existing.inverted_p == candidate.inverted_p
    368 	    && operand_equal_p (existing.op0, candidate.op0, 0)
    369 	    && operand_equal_p (existing.op1, candidate.op1, 0));
    370   }
    371 
    372   static const bool empty_zero_p = true;
    373 
    374   static inline void
    375   mark_empty (value_type &v)
    376   {
    377     v.ncopies = 0;
    378     v.inverted_p = false;
    379   }
    380 
    381   static inline bool
    382   is_empty (value_type v)
    383   {
    384     return v.ncopies == 0;
    385   }
    386 
    387   static inline void mark_deleted (value_type &) {}
    388 
    389   static inline bool is_deleted (const value_type &)
    390   {
    391     return false;
    392   }
    393 
    394   static inline void remove (value_type &) {}
    395 };
    396 
    397 typedef hash_set<scalar_cond_masked_key> scalar_cond_masked_set_type;
    398 
    399 /* Key and map that records association between vector conditions and
    400    corresponding loop mask, and is populated by prepare_vec_mask.  */
    401 
    402 typedef pair_hash<tree_operand_hash, tree_operand_hash> tree_cond_mask_hash;
    403 typedef hash_set<tree_cond_mask_hash> vec_cond_masked_set_type;
    404 
    405 /* Describes two objects whose addresses must be unequal for the vectorized
    406    loop to be valid.  */
    407 typedef std::pair<tree, tree> vec_object_pair;
    408 
    409 /* Records that vectorization is only possible if abs (EXPR) >= MIN_VALUE.
    410    UNSIGNED_P is true if we can assume that abs (EXPR) == EXPR.  */
    411 class vec_lower_bound {
    412 public:
    413   vec_lower_bound () {}
    414   vec_lower_bound (tree e, bool u, poly_uint64 m)
    415     : expr (e), unsigned_p (u), min_value (m) {}
    416 
    417   tree expr;
    418   bool unsigned_p;
    419   poly_uint64 min_value;
    420 };
    421 
    422 /* Vectorizer state shared between different analyses like vector sizes
    423    of the same CFG region.  */
    424 class vec_info_shared {
    425 public:
    426   vec_info_shared();
    427   ~vec_info_shared();
    428 
    429   void save_datarefs();
    430   void check_datarefs();
    431 
    432   /* The number of scalar stmts.  */
    433   unsigned n_stmts;
    434 
    435   /* All data references.  Freed by free_data_refs, so not an auto_vec.  */
    436   vec<data_reference_p> datarefs;
    437   vec<data_reference> datarefs_copy;
    438 
    439   /* The loop nest in which the data dependences are computed.  */
    440   auto_vec<loop_p> loop_nest;
    441 
    442   /* All data dependences.  Freed by free_dependence_relations, so not
    443      an auto_vec.  */
    444   vec<ddr_p> ddrs;
    445 };
    446 
    447 /* Vectorizer state common between loop and basic-block vectorization.  */
    448 class vec_info {
    449 public:
    450   typedef hash_set<int_hash<machine_mode, E_VOIDmode, E_BLKmode> > mode_set;
    451   enum vec_kind { bb, loop };
    452 
    453   vec_info (vec_kind, vec_info_shared *);
    454   ~vec_info ();
    455 
    456   stmt_vec_info add_stmt (gimple *);
    457   stmt_vec_info add_pattern_stmt (gimple *, stmt_vec_info);
    458   stmt_vec_info lookup_stmt (gimple *);
    459   stmt_vec_info lookup_def (tree);
    460   stmt_vec_info lookup_single_use (tree);
    461   class dr_vec_info *lookup_dr (data_reference *);
    462   void move_dr (stmt_vec_info, stmt_vec_info);
    463   void remove_stmt (stmt_vec_info);
    464   void replace_stmt (gimple_stmt_iterator *, stmt_vec_info, gimple *);
    465   void insert_on_entry (stmt_vec_info, gimple *);
    466   void insert_seq_on_entry (stmt_vec_info, gimple_seq);
    467 
    468   /* The type of vectorization.  */
    469   vec_kind kind;
    470 
    471   /* Shared vectorizer state.  */
    472   vec_info_shared *shared;
    473 
    474   /* The mapping of GIMPLE UID to stmt_vec_info.  */
    475   vec<stmt_vec_info> stmt_vec_infos;
    476   /* Whether the above mapping is complete.  */
    477   bool stmt_vec_info_ro;
    478 
    479   /* Whether we've done a transform we think OK to not update virtual
    480      SSA form.  */
    481   bool any_known_not_updated_vssa;
    482 
    483   /* The SLP graph.  */
    484   auto_vec<slp_instance> slp_instances;
    485 
    486   /* Maps base addresses to an innermost_loop_behavior that gives the maximum
    487      known alignment for that base.  */
    488   vec_base_alignments base_alignments;
    489 
    490   /* All interleaving chains of stores, represented by the first
    491      stmt in the chain.  */
    492   auto_vec<stmt_vec_info> grouped_stores;
    493 
    494   /* The set of vector modes used in the vectorized region.  */
    495   mode_set used_vector_modes;
    496 
    497   /* The argument we should pass to related_vector_mode when looking up
    498      the vector mode for a scalar mode, or VOIDmode if we haven't yet
    499      made any decisions about which vector modes to use.  */
    500   machine_mode vector_mode;
    501 
    502 private:
    503   stmt_vec_info new_stmt_vec_info (gimple *stmt);
    504   void set_vinfo_for_stmt (gimple *, stmt_vec_info, bool = true);
    505   void free_stmt_vec_infos ();
    506   void free_stmt_vec_info (stmt_vec_info);
    507 };
    508 
    509 class _loop_vec_info;
    510 class _bb_vec_info;
    511 
    512 template<>
    513 template<>
    514 inline bool
    515 is_a_helper <_loop_vec_info *>::test (vec_info *i)
    516 {
    517   return i->kind == vec_info::loop;
    518 }
    519 
    520 template<>
    521 template<>
    522 inline bool
    523 is_a_helper <_bb_vec_info *>::test (vec_info *i)
    524 {
    525   return i->kind == vec_info::bb;
    526 }
    527 
    528 /* In general, we can divide the vector statements in a vectorized loop
    529    into related groups ("rgroups") and say that for each rgroup there is
    530    some nS such that the rgroup operates on nS values from one scalar
    531    iteration followed by nS values from the next.  That is, if VF is the
    532    vectorization factor of the loop, the rgroup operates on a sequence:
    533 
    534      (1,1) (1,2) ... (1,nS) (2,1) ... (2,nS) ... (VF,1) ... (VF,nS)
    535 
    536    where (i,j) represents a scalar value with index j in a scalar
    537    iteration with index i.
    538 
    539    [ We use the term "rgroup" to emphasise that this grouping isn't
    540      necessarily the same as the grouping of statements used elsewhere.
    541      For example, if we implement a group of scalar loads using gather
    542      loads, we'll use a separate gather load for each scalar load, and
    543      thus each gather load will belong to its own rgroup. ]
    544 
    545    In general this sequence will occupy nV vectors concatenated
    546    together.  If these vectors have nL lanes each, the total number
    547    of scalar values N is given by:
    548 
    549        N = nS * VF = nV * nL
    550 
    551    None of nS, VF, nV and nL are required to be a power of 2.  nS and nV
    552    are compile-time constants but VF and nL can be variable (if the target
    553    supports variable-length vectors).
    554 
    555    In classical vectorization, each iteration of the vector loop would
    556    handle exactly VF iterations of the original scalar loop.  However,
    557    in vector loops that are able to operate on partial vectors, a
    558    particular iteration of the vector loop might handle fewer than VF
    559    iterations of the scalar loop.  The vector lanes that correspond to
    560    iterations of the scalar loop are said to be "active" and the other
    561    lanes are said to be "inactive".
    562 
    563    In such vector loops, many rgroups need to be controlled to ensure
    564    that they have no effect for the inactive lanes.  Conceptually, each
    565    such rgroup needs a sequence of booleans in the same order as above,
    566    but with each (i,j) replaced by a boolean that indicates whether
    567    iteration i is active.  This sequence occupies nV vector controls
    568    that again have nL lanes each.  Thus the control sequence as a whole
    569    consists of VF independent booleans that are each repeated nS times.
    570 
    571    Taking mask-based approach as a partially-populated vectors example.
    572    We make the simplifying assumption that if a sequence of nV masks is
    573    suitable for one (nS,nL) pair, we can reuse it for (nS/2,nL/2) by
    574    VIEW_CONVERTing it.  This holds for all current targets that support
    575    fully-masked loops.  For example, suppose the scalar loop is:
    576 
    577      float *f;
    578      double *d;
    579      for (int i = 0; i < n; ++i)
    580        {
    581 	 f[i * 2 + 0] += 1.0f;
    582 	 f[i * 2 + 1] += 2.0f;
    583 	 d[i] += 3.0;
    584        }
    585 
    586    and suppose that vectors have 256 bits.  The vectorized f accesses
    587    will belong to one rgroup and the vectorized d access to another:
    588 
    589      f rgroup: nS = 2, nV = 1, nL = 8
    590      d rgroup: nS = 1, nV = 1, nL = 4
    591 	       VF = 4
    592 
    593      [ In this simple example the rgroups do correspond to the normal
    594        SLP grouping scheme. ]
    595 
    596    If only the first three lanes are active, the masks we need are:
    597 
    598      f rgroup: 1 1 | 1 1 | 1 1 | 0 0
    599      d rgroup:  1  |  1  |  1  |  0
    600 
    601    Here we can use a mask calculated for f's rgroup for d's, but not
    602    vice versa.
    603 
    604    Thus for each value of nV, it is enough to provide nV masks, with the
    605    mask being calculated based on the highest nL (or, equivalently, based
    606    on the highest nS) required by any rgroup with that nV.  We therefore
    607    represent the entire collection of masks as a two-level table, with the
    608    first level being indexed by nV - 1 (since nV == 0 doesn't exist) and
    609    the second being indexed by the mask index 0 <= i < nV.  */
    610 
    611 /* The controls (like masks or lengths) needed by rgroups with nV vectors,
    612    according to the description above.  */
    613 struct rgroup_controls {
    614   /* The largest nS for all rgroups that use these controls.
    615      For vect_partial_vectors_avx512 this is the constant nscalars_per_iter
    616      for all members of the group.  */
    617   unsigned int max_nscalars_per_iter;
    618 
    619   /* For the largest nS recorded above, the loop controls divide each scalar
    620      into FACTOR equal-sized pieces.  This is useful if we need to split
    621      element-based accesses into byte-based accesses.
    622      For vect_partial_vectors_avx512 this records nV instead.  */
    623   unsigned int factor;
    624 
    625   /* This is a vector type with MAX_NSCALARS_PER_ITER * VF / nV elements.
    626      For mask-based controls, it is the type of the masks in CONTROLS.
    627      For length-based controls, it can be any vector type that has the
    628      specified number of elements; the type of the elements doesn't matter.  */
    629   tree type;
    630 
    631   /* When there is no uniformly used LOOP_VINFO_RGROUP_COMPARE_TYPE this
    632      is the rgroup specific type used.  */
    633   tree compare_type;
    634 
    635   /* A vector of nV controls, in iteration order.  */
    636   vec<tree> controls;
    637 
    638   /* In case of len_load and len_store with a bias there is only one
    639      rgroup.  This holds the adjusted loop length for the this rgroup.  */
    640   tree bias_adjusted_ctrl;
    641 };
    642 
    643 struct vec_loop_masks
    644 {
    645   bool is_empty () const { return mask_set.is_empty (); }
    646 
    647   /* Set to record vectype, nvector pairs.  */
    648   hash_set<pair_hash <nofree_ptr_hash <tree_node>,
    649 		      int_hash<unsigned, 0>>> mask_set;
    650 
    651   /* rgroup_controls used for the partial vector scheme.  */
    652   auto_vec<rgroup_controls> rgc_vec;
    653 };
    654 
    655 typedef auto_vec<rgroup_controls> vec_loop_lens;
    656 
    657 typedef auto_vec<std::pair<data_reference*, tree> > drs_init_vec;
    658 
    659 /* Information about a reduction accumulator from the main loop that could
    660    conceivably be reused as the input to a reduction in an epilogue loop.  */
    661 struct vect_reusable_accumulator {
    662   /* The final value of the accumulator, which forms the input to the
    663      reduction operation.  */
    664   tree reduc_input;
    665 
    666   /* The stmt_vec_info that describes the reduction (i.e. the one for
    667      which is_reduc_info is true).  */
    668   stmt_vec_info reduc_info;
    669 };
    670 
    671 /*-----------------------------------------------------------------*/
    672 /* Info on vectorized loops.                                       */
    673 /*-----------------------------------------------------------------*/
    674 typedef class _loop_vec_info : public vec_info {
    675 public:
    676   _loop_vec_info (class loop *, vec_info_shared *);
    677   ~_loop_vec_info ();
    678 
    679   /* The loop to which this info struct refers to.  */
    680   class loop *loop;
    681 
    682   /* The loop basic blocks.  */
    683   basic_block *bbs;
    684 
    685   /* Number of latch executions.  */
    686   tree num_itersm1;
    687   /* Number of iterations.  */
    688   tree num_iters;
    689   /* Number of iterations of the original loop.  */
    690   tree num_iters_unchanged;
    691   /* Condition under which this loop is analyzed and versioned.  */
    692   tree num_iters_assumptions;
    693 
    694   /* The cost of the vector code.  */
    695   class vector_costs *vector_costs;
    696 
    697   /* The cost of the scalar code.  */
    698   class vector_costs *scalar_costs;
    699 
    700   /* Threshold of number of iterations below which vectorization will not be
    701      performed. It is calculated from MIN_PROFITABLE_ITERS and
    702      param_min_vect_loop_bound.  */
    703   unsigned int th;
    704 
    705   /* When applying loop versioning, the vector form should only be used
    706      if the number of scalar iterations is >= this value, on top of all
    707      the other requirements.  Ignored when loop versioning is not being
    708      used.  */
    709   poly_uint64 versioning_threshold;
    710 
    711   /* Unrolling factor  */
    712   poly_uint64 vectorization_factor;
    713 
    714   /* If this loop is an epilogue loop whose main loop can be skipped,
    715      MAIN_LOOP_EDGE is the edge from the main loop to this loop's
    716      preheader.  SKIP_MAIN_LOOP_EDGE is then the edge that skips the
    717      main loop and goes straight to this loop's preheader.
    718 
    719      Both fields are null otherwise.  */
    720   edge main_loop_edge;
    721   edge skip_main_loop_edge;
    722 
    723   /* If this loop is an epilogue loop that might be skipped after executing
    724      the main loop, this edge is the one that skips the epilogue.  */
    725   edge skip_this_loop_edge;
    726 
    727   /* The vectorized form of a standard reduction replaces the original
    728      scalar code's final result (a loop-closed SSA PHI) with the result
    729      of a vector-to-scalar reduction operation.  After vectorization,
    730      this variable maps these vector-to-scalar results to information
    731      about the reductions that generated them.  */
    732   hash_map<tree, vect_reusable_accumulator> reusable_accumulators;
    733 
    734   /* The number of times that the target suggested we unroll the vector loop
    735      in order to promote more ILP.  This value will be used to re-analyze the
    736      loop for vectorization and if successful the value will be folded into
    737      vectorization_factor (and therefore exactly divides
    738      vectorization_factor).  */
    739   unsigned int suggested_unroll_factor;
    740 
    741   /* Maximum runtime vectorization factor, or MAX_VECTORIZATION_FACTOR
    742      if there is no particular limit.  */
    743   unsigned HOST_WIDE_INT max_vectorization_factor;
    744 
    745   /* The masks that a fully-masked loop should use to avoid operating
    746      on inactive scalars.  */
    747   vec_loop_masks masks;
    748 
    749   /* The lengths that a loop with length should use to avoid operating
    750      on inactive scalars.  */
    751   vec_loop_lens lens;
    752 
    753   /* Set of scalar conditions that have loop mask applied.  */
    754   scalar_cond_masked_set_type scalar_cond_masked_set;
    755 
    756   /* Set of vector conditions that have loop mask applied.  */
    757   vec_cond_masked_set_type vec_cond_masked_set;
    758 
    759   /* If we are using a loop mask to align memory addresses, this variable
    760      contains the number of vector elements that we should skip in the
    761      first iteration of the vector loop (i.e. the number of leading
    762      elements that should be false in the first mask).  */
    763   tree mask_skip_niters;
    764 
    765   /* The type that the loop control IV should be converted to before
    766      testing which of the VF scalars are active and inactive.
    767      Only meaningful if LOOP_VINFO_USING_PARTIAL_VECTORS_P.  */
    768   tree rgroup_compare_type;
    769 
    770   /* For #pragma omp simd if (x) loops the x expression.  If constant 0,
    771      the loop should not be vectorized, if constant non-zero, simd_if_cond
    772      shouldn't be set and loop vectorized normally, if SSA_NAME, the loop
    773      should be versioned on that condition, using scalar loop if the condition
    774      is false and vectorized loop otherwise.  */
    775   tree simd_if_cond;
    776 
    777   /* The type that the vector loop control IV should have when
    778      LOOP_VINFO_USING_PARTIAL_VECTORS_P is true.  */
    779   tree rgroup_iv_type;
    780 
    781   /* The style used for implementing partial vectors when
    782      LOOP_VINFO_USING_PARTIAL_VECTORS_P is true.  */
    783   vect_partial_vector_style partial_vector_style;
    784 
    785   /* Unknown DRs according to which loop was peeled.  */
    786   class dr_vec_info *unaligned_dr;
    787 
    788   /* peeling_for_alignment indicates whether peeling for alignment will take
    789      place, and what the peeling factor should be:
    790      peeling_for_alignment = X means:
    791         If X=0: Peeling for alignment will not be applied.
    792         If X>0: Peel first X iterations.
    793         If X=-1: Generate a runtime test to calculate the number of iterations
    794                  to be peeled, using the dataref recorded in the field
    795                  unaligned_dr.  */
    796   int peeling_for_alignment;
    797 
    798   /* The mask used to check the alignment of pointers or arrays.  */
    799   int ptr_mask;
    800 
    801   /* Data Dependence Relations defining address ranges that are candidates
    802      for a run-time aliasing check.  */
    803   auto_vec<ddr_p> may_alias_ddrs;
    804 
    805   /* Data Dependence Relations defining address ranges together with segment
    806      lengths from which the run-time aliasing check is built.  */
    807   auto_vec<dr_with_seg_len_pair_t> comp_alias_ddrs;
    808 
    809   /* Check that the addresses of each pair of objects is unequal.  */
    810   auto_vec<vec_object_pair> check_unequal_addrs;
    811 
    812   /* List of values that are required to be nonzero.  This is used to check
    813      whether things like "x[i * n] += 1;" are safe and eventually gets added
    814      to the checks for lower bounds below.  */
    815   auto_vec<tree> check_nonzero;
    816 
    817   /* List of values that need to be checked for a minimum value.  */
    818   auto_vec<vec_lower_bound> lower_bounds;
    819 
    820   /* Statements in the loop that have data references that are candidates for a
    821      runtime (loop versioning) misalignment check.  */
    822   auto_vec<stmt_vec_info> may_misalign_stmts;
    823 
    824   /* Reduction cycles detected in the loop. Used in loop-aware SLP.  */
    825   auto_vec<stmt_vec_info> reductions;
    826 
    827   /* All reduction chains in the loop, represented by the first
    828      stmt in the chain.  */
    829   auto_vec<stmt_vec_info> reduction_chains;
    830 
    831   /* Cost vector for a single scalar iteration.  */
    832   auto_vec<stmt_info_for_cost> scalar_cost_vec;
    833 
    834   /* Map of IV base/step expressions to inserted name in the preheader.  */
    835   hash_map<tree_operand_hash, tree> *ivexpr_map;
    836 
    837   /* Map of OpenMP "omp simd array" scan variables to corresponding
    838      rhs of the store of the initializer.  */
    839   hash_map<tree, tree> *scan_map;
    840 
    841   /* The unrolling factor needed to SLP the loop. In case of that pure SLP is
    842      applied to the loop, i.e., no unrolling is needed, this is 1.  */
    843   poly_uint64 slp_unrolling_factor;
    844 
    845   /* The factor used to over weight those statements in an inner loop
    846      relative to the loop being vectorized.  */
    847   unsigned int inner_loop_cost_factor;
    848 
    849   /* Is the loop vectorizable? */
    850   bool vectorizable;
    851 
    852   /* Records whether we still have the option of vectorizing this loop
    853      using partially-populated vectors; in other words, whether it is
    854      still possible for one iteration of the vector loop to handle
    855      fewer than VF scalars.  */
    856   bool can_use_partial_vectors_p;
    857 
    858   /* True if we've decided to use partially-populated vectors, so that
    859      the vector loop can handle fewer than VF scalars.  */
    860   bool using_partial_vectors_p;
    861 
    862   /* True if we've decided to use a decrementing loop control IV that counts
    863      scalars. This can be done for any loop that:
    864 
    865 	(a) uses length "controls"; and
    866 	(b) can iterate more than once.  */
    867   bool using_decrementing_iv_p;
    868 
    869   /* True if we've decided to use output of select_vl to adjust IV of
    870      both loop control and data reference pointer. This is only true
    871      for single-rgroup control.  */
    872   bool using_select_vl_p;
    873 
    874   /* True if we've decided to use partially-populated vectors for the
    875      epilogue of loop.  */
    876   bool epil_using_partial_vectors_p;
    877 
    878   /* The bias for len_load and len_store.  For now, only 0 and -1 are
    879      supported.  -1 must be used when a backend does not support
    880      len_load/len_store with a length of zero.  */
    881   signed char partial_load_store_bias;
    882 
    883   /* When we have grouped data accesses with gaps, we may introduce invalid
    884      memory accesses.  We peel the last iteration of the loop to prevent
    885      this.  */
    886   bool peeling_for_gaps;
    887 
    888   /* When the number of iterations is not a multiple of the vector size
    889      we need to peel off iterations at the end to form an epilogue loop.  */
    890   bool peeling_for_niter;
    891 
    892   /* When the loop has early breaks that we can vectorize we need to peel
    893      the loop for the break finding loop.  */
    894   bool early_breaks;
    895 
    896   /* List of loop additional IV conditionals found in the loop.  */
    897   auto_vec<gcond *> conds;
    898 
    899   /* Main loop IV cond.  */
    900   gcond* loop_iv_cond;
    901 
    902   /* True if there are no loop carried data dependencies in the loop.
    903      If loop->safelen <= 1, then this is always true, either the loop
    904      didn't have any loop carried data dependencies, or the loop is being
    905      vectorized guarded with some runtime alias checks, or couldn't
    906      be vectorized at all, but then this field shouldn't be used.
    907      For loop->safelen >= 2, the user has asserted that there are no
    908      backward dependencies, but there still could be loop carried forward
    909      dependencies in such loops.  This flag will be false if normal
    910      vectorizer data dependency analysis would fail or require versioning
    911      for alias, but because of loop->safelen >= 2 it has been vectorized
    912      even without versioning for alias.  E.g. in:
    913      #pragma omp simd
    914      for (int i = 0; i < m; i++)
    915        a[i] = a[i + k] * c;
    916      (or #pragma simd or #pragma ivdep) we can vectorize this and it will
    917      DTRT even for k > 0 && k < m, but without safelen we would not
    918      vectorize this, so this field would be false.  */
    919   bool no_data_dependencies;
    920 
    921   /* Mark loops having masked stores.  */
    922   bool has_mask_store;
    923 
    924   /* Queued scaling factor for the scalar loop.  */
    925   profile_probability scalar_loop_scaling;
    926 
    927   /* If if-conversion versioned this loop before conversion, this is the
    928      loop version without if-conversion.  */
    929   class loop *scalar_loop;
    930 
    931   /* For loops being epilogues of already vectorized loops
    932      this points to the original vectorized loop.  Otherwise NULL.  */
    933   _loop_vec_info *orig_loop_info;
    934 
    935   /* Used to store loop_vec_infos of epilogues of this loop during
    936      analysis.  */
    937   vec<_loop_vec_info *> epilogue_vinfos;
    938 
    939   /* The controlling loop IV for the current loop when vectorizing.  This IV
    940      controls the natural exits of the loop.  */
    941   edge vec_loop_iv_exit;
    942 
    943   /* The controlling loop IV for the epilogue loop when vectorizing.  This IV
    944      controls the natural exits of the loop.  */
    945   edge vec_epilogue_loop_iv_exit;
    946 
    947   /* The controlling loop IV for the scalar loop being vectorized.  This IV
    948      controls the natural exits of the loop.  */
    949   edge scalar_loop_iv_exit;
    950 
    951   /* Used to store the list of stores needing to be moved if doing early
    952      break vectorization as they would violate the scalar loop semantics if
    953      vectorized in their current location.  These are stored in order that they
    954      need to be moved.  */
    955   auto_vec<gimple *> early_break_stores;
    956 
    957   /* The final basic block where to move statements to.  In the case of
    958      multiple exits this could be pretty far away.  */
    959   basic_block early_break_dest_bb;
    960 
    961   /* Statements whose VUSES need updating if early break vectorization is to
    962      happen.  */
    963   auto_vec<gimple*> early_break_vuses;
    964 } *loop_vec_info;
    965 
    966 /* Access Functions.  */
    967 #define LOOP_VINFO_LOOP(L)                 (L)->loop
    968 #define LOOP_VINFO_IV_EXIT(L)              (L)->vec_loop_iv_exit
    969 #define LOOP_VINFO_EPILOGUE_IV_EXIT(L)     (L)->vec_epilogue_loop_iv_exit
    970 #define LOOP_VINFO_SCALAR_IV_EXIT(L)       (L)->scalar_loop_iv_exit
    971 #define LOOP_VINFO_BBS(L)                  (L)->bbs
    972 #define LOOP_VINFO_NITERSM1(L)             (L)->num_itersm1
    973 #define LOOP_VINFO_NITERS(L)               (L)->num_iters
    974 /* Since LOOP_VINFO_NITERS and LOOP_VINFO_NITERSM1 can change after
    975    prologue peeling retain total unchanged scalar loop iterations for
    976    cost model.  */
    977 #define LOOP_VINFO_NITERS_UNCHANGED(L)     (L)->num_iters_unchanged
    978 #define LOOP_VINFO_NITERS_ASSUMPTIONS(L)   (L)->num_iters_assumptions
    979 #define LOOP_VINFO_COST_MODEL_THRESHOLD(L) (L)->th
    980 #define LOOP_VINFO_VERSIONING_THRESHOLD(L) (L)->versioning_threshold
    981 #define LOOP_VINFO_VECTORIZABLE_P(L)       (L)->vectorizable
    982 #define LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P(L) (L)->can_use_partial_vectors_p
    983 #define LOOP_VINFO_USING_PARTIAL_VECTORS_P(L) (L)->using_partial_vectors_p
    984 #define LOOP_VINFO_USING_DECREMENTING_IV_P(L) (L)->using_decrementing_iv_p
    985 #define LOOP_VINFO_USING_SELECT_VL_P(L) (L)->using_select_vl_p
    986 #define LOOP_VINFO_EPIL_USING_PARTIAL_VECTORS_P(L)                             \
    987   (L)->epil_using_partial_vectors_p
    988 #define LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS(L) (L)->partial_load_store_bias
    989 #define LOOP_VINFO_VECT_FACTOR(L)          (L)->vectorization_factor
    990 #define LOOP_VINFO_MAX_VECT_FACTOR(L)      (L)->max_vectorization_factor
    991 #define LOOP_VINFO_MASKS(L)                (L)->masks
    992 #define LOOP_VINFO_LENS(L)                 (L)->lens
    993 #define LOOP_VINFO_MASK_SKIP_NITERS(L)     (L)->mask_skip_niters
    994 #define LOOP_VINFO_RGROUP_COMPARE_TYPE(L)  (L)->rgroup_compare_type
    995 #define LOOP_VINFO_RGROUP_IV_TYPE(L)       (L)->rgroup_iv_type
    996 #define LOOP_VINFO_PARTIAL_VECTORS_STYLE(L) (L)->partial_vector_style
    997 #define LOOP_VINFO_PTR_MASK(L)             (L)->ptr_mask
    998 #define LOOP_VINFO_N_STMTS(L)		   (L)->shared->n_stmts
    999 #define LOOP_VINFO_LOOP_NEST(L)            (L)->shared->loop_nest
   1000 #define LOOP_VINFO_DATAREFS(L)             (L)->shared->datarefs
   1001 #define LOOP_VINFO_DDRS(L)                 (L)->shared->ddrs
   1002 #define LOOP_VINFO_INT_NITERS(L)           (TREE_INT_CST_LOW ((L)->num_iters))
   1003 #define LOOP_VINFO_PEELING_FOR_ALIGNMENT(L) (L)->peeling_for_alignment
   1004 #define LOOP_VINFO_UNALIGNED_DR(L)         (L)->unaligned_dr
   1005 #define LOOP_VINFO_MAY_MISALIGN_STMTS(L)   (L)->may_misalign_stmts
   1006 #define LOOP_VINFO_MAY_ALIAS_DDRS(L)       (L)->may_alias_ddrs
   1007 #define LOOP_VINFO_COMP_ALIAS_DDRS(L)      (L)->comp_alias_ddrs
   1008 #define LOOP_VINFO_CHECK_UNEQUAL_ADDRS(L)  (L)->check_unequal_addrs
   1009 #define LOOP_VINFO_CHECK_NONZERO(L)        (L)->check_nonzero
   1010 #define LOOP_VINFO_LOWER_BOUNDS(L)         (L)->lower_bounds
   1011 #define LOOP_VINFO_GROUPED_STORES(L)       (L)->grouped_stores
   1012 #define LOOP_VINFO_SLP_INSTANCES(L)        (L)->slp_instances
   1013 #define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor
   1014 #define LOOP_VINFO_REDUCTIONS(L)           (L)->reductions
   1015 #define LOOP_VINFO_REDUCTION_CHAINS(L)     (L)->reduction_chains
   1016 #define LOOP_VINFO_PEELING_FOR_GAPS(L)     (L)->peeling_for_gaps
   1017 #define LOOP_VINFO_PEELING_FOR_NITER(L)    (L)->peeling_for_niter
   1018 #define LOOP_VINFO_EARLY_BREAKS(L)         (L)->early_breaks
   1019 #define LOOP_VINFO_EARLY_BRK_STORES(L)     (L)->early_break_stores
   1020 #define LOOP_VINFO_EARLY_BREAKS_VECT_PEELED(L)  \
   1021   (single_pred ((L)->loop->latch) != (L)->vec_loop_iv_exit->src)
   1022 #define LOOP_VINFO_EARLY_BRK_DEST_BB(L)    (L)->early_break_dest_bb
   1023 #define LOOP_VINFO_EARLY_BRK_VUSES(L)      (L)->early_break_vuses
   1024 #define LOOP_VINFO_LOOP_CONDS(L)           (L)->conds
   1025 #define LOOP_VINFO_LOOP_IV_COND(L)         (L)->loop_iv_cond
   1026 #define LOOP_VINFO_NO_DATA_DEPENDENCIES(L) (L)->no_data_dependencies
   1027 #define LOOP_VINFO_SCALAR_LOOP(L)	   (L)->scalar_loop
   1028 #define LOOP_VINFO_SCALAR_LOOP_SCALING(L)  (L)->scalar_loop_scaling
   1029 #define LOOP_VINFO_HAS_MASK_STORE(L)       (L)->has_mask_store
   1030 #define LOOP_VINFO_SCALAR_ITERATION_COST(L) (L)->scalar_cost_vec
   1031 #define LOOP_VINFO_ORIG_LOOP_INFO(L)       (L)->orig_loop_info
   1032 #define LOOP_VINFO_SIMD_IF_COND(L)         (L)->simd_if_cond
   1033 #define LOOP_VINFO_INNER_LOOP_COST_FACTOR(L) (L)->inner_loop_cost_factor
   1034 
   1035 #define LOOP_VINFO_FULLY_MASKED_P(L)		\
   1036   (LOOP_VINFO_USING_PARTIAL_VECTORS_P (L)	\
   1037    && !LOOP_VINFO_MASKS (L).is_empty ())
   1038 
   1039 #define LOOP_VINFO_FULLY_WITH_LENGTH_P(L)	\
   1040   (LOOP_VINFO_USING_PARTIAL_VECTORS_P (L)	\
   1041    && !LOOP_VINFO_LENS (L).is_empty ())
   1042 
   1043 #define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L)	\
   1044   ((L)->may_misalign_stmts.length () > 0)
   1045 #define LOOP_REQUIRES_VERSIONING_FOR_ALIAS(L)		\
   1046   ((L)->comp_alias_ddrs.length () > 0 \
   1047    || (L)->check_unequal_addrs.length () > 0 \
   1048    || (L)->lower_bounds.length () > 0)
   1049 #define LOOP_REQUIRES_VERSIONING_FOR_NITERS(L)		\
   1050   (LOOP_VINFO_NITERS_ASSUMPTIONS (L))
   1051 #define LOOP_REQUIRES_VERSIONING_FOR_SIMD_IF_COND(L)	\
   1052   (LOOP_VINFO_SIMD_IF_COND (L))
   1053 #define LOOP_REQUIRES_VERSIONING(L)			\
   1054   (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (L)		\
   1055    || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (L)		\
   1056    || LOOP_REQUIRES_VERSIONING_FOR_NITERS (L)		\
   1057    || LOOP_REQUIRES_VERSIONING_FOR_SIMD_IF_COND (L))
   1058 
   1059 #define LOOP_VINFO_NITERS_KNOWN_P(L)          \
   1060   (tree_fits_shwi_p ((L)->num_iters) && tree_to_shwi ((L)->num_iters) > 0)
   1061 
   1062 #define LOOP_VINFO_EPILOGUE_P(L) \
   1063   (LOOP_VINFO_ORIG_LOOP_INFO (L) != NULL)
   1064 
   1065 #define LOOP_VINFO_ORIG_MAX_VECT_FACTOR(L) \
   1066   (LOOP_VINFO_MAX_VECT_FACTOR (LOOP_VINFO_ORIG_LOOP_INFO (L)))
   1067 
   1068 /* Wrapper for loop_vec_info, for tracking success/failure, where a non-NULL
   1069    value signifies success, and a NULL value signifies failure, supporting
   1070    propagating an opt_problem * describing the failure back up the call
   1071    stack.  */
   1072 typedef opt_pointer_wrapper <loop_vec_info> opt_loop_vec_info;
   1073 
   1074 inline loop_vec_info
   1075 loop_vec_info_for_loop (class loop *loop)
   1076 {
   1077   return (loop_vec_info) loop->aux;
   1078 }
   1079 
   1080 struct slp_root
   1081 {
   1082   slp_root (slp_instance_kind kind_, vec<stmt_vec_info> stmts_,
   1083 	    vec<stmt_vec_info> roots_, vec<tree> remain_ = vNULL)
   1084     : kind(kind_), stmts(stmts_), roots(roots_), remain(remain_) {}
   1085   slp_instance_kind kind;
   1086   vec<stmt_vec_info> stmts;
   1087   vec<stmt_vec_info> roots;
   1088   vec<tree> remain;
   1089 };
   1090 
   1091 typedef class _bb_vec_info : public vec_info
   1092 {
   1093 public:
   1094   _bb_vec_info (vec<basic_block> bbs, vec_info_shared *);
   1095   ~_bb_vec_info ();
   1096 
   1097   /* The region we are operating on.  bbs[0] is the entry, excluding
   1098      its PHI nodes.  In the future we might want to track an explicit
   1099      entry edge to cover bbs[0] PHI nodes and have a region entry
   1100      insert location.  */
   1101   vec<basic_block> bbs;
   1102 
   1103   vec<slp_root> roots;
   1104 } *bb_vec_info;
   1105 
   1106 #define BB_VINFO_BB(B)               (B)->bb
   1107 #define BB_VINFO_GROUPED_STORES(B)   (B)->grouped_stores
   1108 #define BB_VINFO_SLP_INSTANCES(B)    (B)->slp_instances
   1109 #define BB_VINFO_DATAREFS(B)         (B)->shared->datarefs
   1110 #define BB_VINFO_DDRS(B)             (B)->shared->ddrs
   1111 
   1112 /*-----------------------------------------------------------------*/
   1113 /* Info on vectorized defs.                                        */
   1114 /*-----------------------------------------------------------------*/
   1115 enum stmt_vec_info_type {
   1116   undef_vec_info_type = 0,
   1117   load_vec_info_type,
   1118   store_vec_info_type,
   1119   shift_vec_info_type,
   1120   op_vec_info_type,
   1121   call_vec_info_type,
   1122   call_simd_clone_vec_info_type,
   1123   assignment_vec_info_type,
   1124   condition_vec_info_type,
   1125   comparison_vec_info_type,
   1126   reduc_vec_info_type,
   1127   induc_vec_info_type,
   1128   type_promotion_vec_info_type,
   1129   type_demotion_vec_info_type,
   1130   type_conversion_vec_info_type,
   1131   cycle_phi_info_type,
   1132   lc_phi_info_type,
   1133   phi_info_type,
   1134   recurr_info_type,
   1135   loop_exit_ctrl_vec_info_type
   1136 };
   1137 
   1138 /* Indicates whether/how a variable is used in the scope of loop/basic
   1139    block.  */
   1140 enum vect_relevant {
   1141   vect_unused_in_scope = 0,
   1142 
   1143   /* The def is only used outside the loop.  */
   1144   vect_used_only_live,
   1145   /* The def is in the inner loop, and the use is in the outer loop, and the
   1146      use is a reduction stmt.  */
   1147   vect_used_in_outer_by_reduction,
   1148   /* The def is in the inner loop, and the use is in the outer loop (and is
   1149      not part of reduction).  */
   1150   vect_used_in_outer,
   1151 
   1152   /* defs that feed computations that end up (only) in a reduction. These
   1153      defs may be used by non-reduction stmts, but eventually, any
   1154      computations/values that are affected by these defs are used to compute
   1155      a reduction (i.e. don't get stored to memory, for example). We use this
   1156      to identify computations that we can change the order in which they are
   1157      computed.  */
   1158   vect_used_by_reduction,
   1159 
   1160   vect_used_in_scope
   1161 };
   1162 
   1163 /* The type of vectorization that can be applied to the stmt: regular loop-based
   1164    vectorization; pure SLP - the stmt is a part of SLP instances and does not
   1165    have uses outside SLP instances; or hybrid SLP and loop-based - the stmt is
   1166    a part of SLP instance and also must be loop-based vectorized, since it has
   1167    uses outside SLP sequences.
   1168 
   1169    In the loop context the meanings of pure and hybrid SLP are slightly
   1170    different. By saying that pure SLP is applied to the loop, we mean that we
   1171    exploit only intra-iteration parallelism in the loop; i.e., the loop can be
   1172    vectorized without doing any conceptual unrolling, cause we don't pack
   1173    together stmts from different iterations, only within a single iteration.
   1174    Loop hybrid SLP means that we exploit both intra-iteration and
   1175    inter-iteration parallelism (e.g., number of elements in the vector is 4
   1176    and the slp-group-size is 2, in which case we don't have enough parallelism
   1177    within an iteration, so we obtain the rest of the parallelism from subsequent
   1178    iterations by unrolling the loop by 2).  */
   1179 enum slp_vect_type {
   1180   loop_vect = 0,
   1181   pure_slp,
   1182   hybrid
   1183 };
   1184 
   1185 /* Says whether a statement is a load, a store of a vectorized statement
   1186    result, or a store of an invariant value.  */
   1187 enum vec_load_store_type {
   1188   VLS_LOAD,
   1189   VLS_STORE,
   1190   VLS_STORE_INVARIANT
   1191 };
   1192 
   1193 /* Describes how we're going to vectorize an individual load or store,
   1194    or a group of loads or stores.  */
   1195 enum vect_memory_access_type {
   1196   /* An access to an invariant address.  This is used only for loads.  */
   1197   VMAT_INVARIANT,
   1198 
   1199   /* A simple contiguous access.  */
   1200   VMAT_CONTIGUOUS,
   1201 
   1202   /* A contiguous access that goes down in memory rather than up,
   1203      with no additional permutation.  This is used only for stores
   1204      of invariants.  */
   1205   VMAT_CONTIGUOUS_DOWN,
   1206 
   1207   /* A simple contiguous access in which the elements need to be permuted
   1208      after loading or before storing.  Only used for loop vectorization;
   1209      SLP uses separate permutes.  */
   1210   VMAT_CONTIGUOUS_PERMUTE,
   1211 
   1212   /* A simple contiguous access in which the elements need to be reversed
   1213      after loading or before storing.  */
   1214   VMAT_CONTIGUOUS_REVERSE,
   1215 
   1216   /* An access that uses IFN_LOAD_LANES or IFN_STORE_LANES.  */
   1217   VMAT_LOAD_STORE_LANES,
   1218 
   1219   /* An access in which each scalar element is loaded or stored
   1220      individually.  */
   1221   VMAT_ELEMENTWISE,
   1222 
   1223   /* A hybrid of VMAT_CONTIGUOUS and VMAT_ELEMENTWISE, used for grouped
   1224      SLP accesses.  Each unrolled iteration uses a contiguous load
   1225      or store for the whole group, but the groups from separate iterations
   1226      are combined in the same way as for VMAT_ELEMENTWISE.  */
   1227   VMAT_STRIDED_SLP,
   1228 
   1229   /* The access uses gather loads or scatter stores.  */
   1230   VMAT_GATHER_SCATTER
   1231 };
   1232 
   1233 class dr_vec_info {
   1234 public:
   1235   /* The data reference itself.  */
   1236   data_reference *dr;
   1237   /* The statement that contains the data reference.  */
   1238   stmt_vec_info stmt;
   1239   /* The analysis group this DR belongs to when doing BB vectorization.
   1240      DRs of the same group belong to the same conditional execution context.  */
   1241   unsigned group;
   1242   /* The misalignment in bytes of the reference, or -1 if not known.  */
   1243   int misalignment;
   1244   /* The byte alignment that we'd ideally like the reference to have,
   1245      and the value that misalignment is measured against.  */
   1246   poly_uint64 target_alignment;
   1247   /* If true the alignment of base_decl needs to be increased.  */
   1248   bool base_misaligned;
   1249   tree base_decl;
   1250 
   1251   /* Stores current vectorized loop's offset.  To be added to the DR's
   1252      offset to calculate current offset of data reference.  */
   1253   tree offset;
   1254 };
   1255 
   1256 typedef struct data_reference *dr_p;
   1257 
   1258 class _stmt_vec_info {
   1259 public:
   1260 
   1261   enum stmt_vec_info_type type;
   1262 
   1263   /* Indicates whether this stmts is part of a computation whose result is
   1264      used outside the loop.  */
   1265   bool live;
   1266 
   1267   /* Stmt is part of some pattern (computation idiom)  */
   1268   bool in_pattern_p;
   1269 
   1270   /* True if the statement was created during pattern recognition as
   1271      part of the replacement for RELATED_STMT.  This implies that the
   1272      statement isn't part of any basic block, although for convenience
   1273      its gimple_bb is the same as for RELATED_STMT.  */
   1274   bool pattern_stmt_p;
   1275 
   1276   /* Is this statement vectorizable or should it be skipped in (partial)
   1277      vectorization.  */
   1278   bool vectorizable;
   1279 
   1280   /* The stmt to which this info struct refers to.  */
   1281   gimple *stmt;
   1282 
   1283   /* The vector type to be used for the LHS of this statement.  */
   1284   tree vectype;
   1285 
   1286   /* The vectorized stmts.  */
   1287   vec<gimple *> vec_stmts;
   1288 
   1289   /* The following is relevant only for stmts that contain a non-scalar
   1290      data-ref (array/pointer/struct access). A GIMPLE stmt is expected to have
   1291      at most one such data-ref.  */
   1292 
   1293   dr_vec_info dr_aux;
   1294 
   1295   /* Information about the data-ref relative to this loop
   1296      nest (the loop that is being considered for vectorization).  */
   1297   innermost_loop_behavior dr_wrt_vec_loop;
   1298 
   1299   /* For loop PHI nodes, the base and evolution part of it.  This makes sure
   1300      this information is still available in vect_update_ivs_after_vectorizer
   1301      where we may not be able to re-analyze the PHI nodes evolution as
   1302      peeling for the prologue loop can make it unanalyzable.  The evolution
   1303      part is still correct after peeling, but the base may have changed from
   1304      the version here.  */
   1305   tree loop_phi_evolution_base_unchanged;
   1306   tree loop_phi_evolution_part;
   1307   enum vect_induction_op_type loop_phi_evolution_type;
   1308 
   1309   /* Used for various bookkeeping purposes, generally holding a pointer to
   1310      some other stmt S that is in some way "related" to this stmt.
   1311      Current use of this field is:
   1312         If this stmt is part of a pattern (i.e. the field 'in_pattern_p' is
   1313         true): S is the "pattern stmt" that represents (and replaces) the
   1314         sequence of stmts that constitutes the pattern.  Similarly, the
   1315         related_stmt of the "pattern stmt" points back to this stmt (which is
   1316         the last stmt in the original sequence of stmts that constitutes the
   1317         pattern).  */
   1318   stmt_vec_info related_stmt;
   1319 
   1320   /* Used to keep a sequence of def stmts of a pattern stmt if such exists.
   1321      The sequence is attached to the original statement rather than the
   1322      pattern statement.  */
   1323   gimple_seq pattern_def_seq;
   1324 
   1325   /* Selected SIMD clone's function info.  First vector element
   1326      is SIMD clone's function decl, followed by a pair of trees (base + step)
   1327      for linear arguments (pair of NULLs for other arguments).  */
   1328   vec<tree> simd_clone_info;
   1329 
   1330   /* Classify the def of this stmt.  */
   1331   enum vect_def_type def_type;
   1332 
   1333   /*  Whether the stmt is SLPed, loop-based vectorized, or both.  */
   1334   enum slp_vect_type slp_type;
   1335 
   1336   /* Interleaving and reduction chains info.  */
   1337   /* First element in the group.  */
   1338   stmt_vec_info first_element;
   1339   /* Pointer to the next element in the group.  */
   1340   stmt_vec_info next_element;
   1341   /* The size of the group.  */
   1342   unsigned int size;
   1343   /* For stores, number of stores from this group seen. We vectorize the last
   1344      one.  */
   1345   unsigned int store_count;
   1346   /* For loads only, the gap from the previous load. For consecutive loads, GAP
   1347      is 1.  */
   1348   unsigned int gap;
   1349 
   1350   /* The minimum negative dependence distance this stmt participates in
   1351      or zero if none.  */
   1352   unsigned int min_neg_dist;
   1353 
   1354   /* Not all stmts in the loop need to be vectorized. e.g, the increment
   1355      of the loop induction variable and computation of array indexes. relevant
   1356      indicates whether the stmt needs to be vectorized.  */
   1357   enum vect_relevant relevant;
   1358 
   1359   /* For loads if this is a gather, for stores if this is a scatter.  */
   1360   bool gather_scatter_p;
   1361 
   1362   /* True if this is an access with loop-invariant stride.  */
   1363   bool strided_p;
   1364 
   1365   /* For both loads and stores.  */
   1366   unsigned simd_lane_access_p : 3;
   1367 
   1368   /* Classifies how the load or store is going to be implemented
   1369      for loop vectorization.  */
   1370   vect_memory_access_type memory_access_type;
   1371 
   1372   /* For INTEGER_INDUC_COND_REDUCTION, the initial value to be used.  */
   1373   tree induc_cond_initial_val;
   1374 
   1375   /* If not NULL the value to be added to compute final reduction value.  */
   1376   tree reduc_epilogue_adjustment;
   1377 
   1378   /* On a reduction PHI the reduction type as detected by
   1379      vect_is_simple_reduction and vectorizable_reduction.  */
   1380   enum vect_reduction_type reduc_type;
   1381 
   1382   /* The original reduction code, to be used in the epilogue.  */
   1383   code_helper reduc_code;
   1384   /* An internal function we should use in the epilogue.  */
   1385   internal_fn reduc_fn;
   1386 
   1387   /* On a stmt participating in the reduction the index of the operand
   1388      on the reduction SSA cycle.  */
   1389   int reduc_idx;
   1390 
   1391   /* On a reduction PHI the def returned by vect_force_simple_reduction.
   1392      On the def returned by vect_force_simple_reduction the
   1393      corresponding PHI.  */
   1394   stmt_vec_info reduc_def;
   1395 
   1396   /* The vector input type relevant for reduction vectorization.  */
   1397   tree reduc_vectype_in;
   1398 
   1399   /* The vector type for performing the actual reduction.  */
   1400   tree reduc_vectype;
   1401 
   1402   /* If IS_REDUC_INFO is true and if the vector code is performing
   1403      N scalar reductions in parallel, this variable gives the initial
   1404      scalar values of those N reductions.  */
   1405   vec<tree> reduc_initial_values;
   1406 
   1407   /* If IS_REDUC_INFO is true and if the vector code is performing
   1408      N scalar reductions in parallel, this variable gives the vectorized code's
   1409      final (scalar) result for each of those N reductions.  In other words,
   1410      REDUC_SCALAR_RESULTS[I] replaces the original scalar code's loop-closed
   1411      SSA PHI for reduction number I.  */
   1412   vec<tree> reduc_scalar_results;
   1413 
   1414   /* Only meaningful if IS_REDUC_INFO.  If non-null, the reduction is
   1415      being performed by an epilogue loop and we have decided to reuse
   1416      this accumulator from the main loop.  */
   1417   vect_reusable_accumulator *reused_accumulator;
   1418 
   1419   /* Whether we force a single cycle PHI during reduction vectorization.  */
   1420   bool force_single_cycle;
   1421 
   1422   /* Whether on this stmt reduction meta is recorded.  */
   1423   bool is_reduc_info;
   1424 
   1425   /* If nonzero, the lhs of the statement could be truncated to this
   1426      many bits without affecting any users of the result.  */
   1427   unsigned int min_output_precision;
   1428 
   1429   /* If nonzero, all non-boolean input operands have the same precision,
   1430      and they could each be truncated to this many bits without changing
   1431      the result.  */
   1432   unsigned int min_input_precision;
   1433 
   1434   /* If OPERATION_BITS is nonzero, the statement could be performed on
   1435      an integer with the sign and number of bits given by OPERATION_SIGN
   1436      and OPERATION_BITS without changing the result.  */
   1437   unsigned int operation_precision;
   1438   signop operation_sign;
   1439 
   1440   /* If the statement produces a boolean result, this value describes
   1441      how we should choose the associated vector type.  The possible
   1442      values are:
   1443 
   1444      - an integer precision N if we should use the vector mask type
   1445        associated with N-bit integers.  This is only used if all relevant
   1446        input booleans also want the vector mask type for N-bit integers,
   1447        or if we can convert them into that form by pattern-matching.
   1448 
   1449      - ~0U if we considered choosing a vector mask type but decided
   1450        to treat the boolean as a normal integer type instead.
   1451 
   1452      - 0 otherwise.  This means either that the operation isn't one that
   1453        could have a vector mask type (and so should have a normal vector
   1454        type instead) or that we simply haven't made a choice either way.  */
   1455   unsigned int mask_precision;
   1456 
   1457   /* True if this is only suitable for SLP vectorization.  */
   1458   bool slp_vect_only_p;
   1459 
   1460   /* True if this is a pattern that can only be handled by SLP
   1461      vectorization.  */
   1462   bool slp_vect_pattern_only_p;
   1463 };
   1464 
   1465 /* Information about a gather/scatter call.  */
   1466 struct gather_scatter_info {
   1467   /* The internal function to use for the gather/scatter operation,
   1468      or IFN_LAST if a built-in function should be used instead.  */
   1469   internal_fn ifn;
   1470 
   1471   /* The FUNCTION_DECL for the built-in gather/scatter function,
   1472      or null if an internal function should be used instead.  */
   1473   tree decl;
   1474 
   1475   /* The loop-invariant base value.  */
   1476   tree base;
   1477 
   1478   /* The original scalar offset, which is a non-loop-invariant SSA_NAME.  */
   1479   tree offset;
   1480 
   1481   /* Each offset element should be multiplied by this amount before
   1482      being added to the base.  */
   1483   int scale;
   1484 
   1485   /* The definition type for the vectorized offset.  */
   1486   enum vect_def_type offset_dt;
   1487 
   1488   /* The type of the vectorized offset.  */
   1489   tree offset_vectype;
   1490 
   1491   /* The type of the scalar elements after loading or before storing.  */
   1492   tree element_type;
   1493 
   1494   /* The type of the scalar elements being loaded or stored.  */
   1495   tree memory_type;
   1496 };
   1497 
   1498 /* Access Functions.  */
   1499 #define STMT_VINFO_TYPE(S)                 (S)->type
   1500 #define STMT_VINFO_STMT(S)                 (S)->stmt
   1501 #define STMT_VINFO_RELEVANT(S)             (S)->relevant
   1502 #define STMT_VINFO_LIVE_P(S)               (S)->live
   1503 #define STMT_VINFO_VECTYPE(S)              (S)->vectype
   1504 #define STMT_VINFO_VEC_STMTS(S)            (S)->vec_stmts
   1505 #define STMT_VINFO_VECTORIZABLE(S)         (S)->vectorizable
   1506 #define STMT_VINFO_DATA_REF(S)             ((S)->dr_aux.dr + 0)
   1507 #define STMT_VINFO_GATHER_SCATTER_P(S)	   (S)->gather_scatter_p
   1508 #define STMT_VINFO_STRIDED_P(S)	   	   (S)->strided_p
   1509 #define STMT_VINFO_MEMORY_ACCESS_TYPE(S)   (S)->memory_access_type
   1510 #define STMT_VINFO_SIMD_LANE_ACCESS_P(S)   (S)->simd_lane_access_p
   1511 #define STMT_VINFO_VEC_INDUC_COND_INITIAL_VAL(S) (S)->induc_cond_initial_val
   1512 #define STMT_VINFO_REDUC_EPILOGUE_ADJUSTMENT(S) (S)->reduc_epilogue_adjustment
   1513 #define STMT_VINFO_REDUC_IDX(S)		   (S)->reduc_idx
   1514 #define STMT_VINFO_FORCE_SINGLE_CYCLE(S)   (S)->force_single_cycle
   1515 
   1516 #define STMT_VINFO_DR_WRT_VEC_LOOP(S)      (S)->dr_wrt_vec_loop
   1517 #define STMT_VINFO_DR_BASE_ADDRESS(S)      (S)->dr_wrt_vec_loop.base_address
   1518 #define STMT_VINFO_DR_INIT(S)              (S)->dr_wrt_vec_loop.init
   1519 #define STMT_VINFO_DR_OFFSET(S)            (S)->dr_wrt_vec_loop.offset
   1520 #define STMT_VINFO_DR_STEP(S)              (S)->dr_wrt_vec_loop.step
   1521 #define STMT_VINFO_DR_BASE_ALIGNMENT(S)    (S)->dr_wrt_vec_loop.base_alignment
   1522 #define STMT_VINFO_DR_BASE_MISALIGNMENT(S) \
   1523   (S)->dr_wrt_vec_loop.base_misalignment
   1524 #define STMT_VINFO_DR_OFFSET_ALIGNMENT(S) \
   1525   (S)->dr_wrt_vec_loop.offset_alignment
   1526 #define STMT_VINFO_DR_STEP_ALIGNMENT(S) \
   1527   (S)->dr_wrt_vec_loop.step_alignment
   1528 
   1529 #define STMT_VINFO_DR_INFO(S) \
   1530   (gcc_checking_assert ((S)->dr_aux.stmt == (S)), &(S)->dr_aux)
   1531 
   1532 #define STMT_VINFO_IN_PATTERN_P(S)         (S)->in_pattern_p
   1533 #define STMT_VINFO_RELATED_STMT(S)         (S)->related_stmt
   1534 #define STMT_VINFO_PATTERN_DEF_SEQ(S)      (S)->pattern_def_seq
   1535 #define STMT_VINFO_SIMD_CLONE_INFO(S)	   (S)->simd_clone_info
   1536 #define STMT_VINFO_DEF_TYPE(S)             (S)->def_type
   1537 #define STMT_VINFO_GROUPED_ACCESS(S) \
   1538   ((S)->dr_aux.dr && DR_GROUP_FIRST_ELEMENT(S))
   1539 #define STMT_VINFO_LOOP_PHI_EVOLUTION_BASE_UNCHANGED(S) (S)->loop_phi_evolution_base_unchanged
   1540 #define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part
   1541 #define STMT_VINFO_LOOP_PHI_EVOLUTION_TYPE(S) (S)->loop_phi_evolution_type
   1542 #define STMT_VINFO_MIN_NEG_DIST(S)	(S)->min_neg_dist
   1543 #define STMT_VINFO_REDUC_TYPE(S)	(S)->reduc_type
   1544 #define STMT_VINFO_REDUC_CODE(S)	(S)->reduc_code
   1545 #define STMT_VINFO_REDUC_FN(S)		(S)->reduc_fn
   1546 #define STMT_VINFO_REDUC_DEF(S)		(S)->reduc_def
   1547 #define STMT_VINFO_REDUC_VECTYPE(S)     (S)->reduc_vectype
   1548 #define STMT_VINFO_REDUC_VECTYPE_IN(S)  (S)->reduc_vectype_in
   1549 #define STMT_VINFO_SLP_VECT_ONLY(S)     (S)->slp_vect_only_p
   1550 #define STMT_VINFO_SLP_VECT_ONLY_PATTERN(S) (S)->slp_vect_pattern_only_p
   1551 
   1552 #define DR_GROUP_FIRST_ELEMENT(S) \
   1553   (gcc_checking_assert ((S)->dr_aux.dr), (S)->first_element)
   1554 #define DR_GROUP_NEXT_ELEMENT(S) \
   1555   (gcc_checking_assert ((S)->dr_aux.dr), (S)->next_element)
   1556 #define DR_GROUP_SIZE(S) \
   1557   (gcc_checking_assert ((S)->dr_aux.dr), (S)->size)
   1558 #define DR_GROUP_STORE_COUNT(S) \
   1559   (gcc_checking_assert ((S)->dr_aux.dr), (S)->store_count)
   1560 #define DR_GROUP_GAP(S) \
   1561   (gcc_checking_assert ((S)->dr_aux.dr), (S)->gap)
   1562 
   1563 #define REDUC_GROUP_FIRST_ELEMENT(S) \
   1564   (gcc_checking_assert (!(S)->dr_aux.dr), (S)->first_element)
   1565 #define REDUC_GROUP_NEXT_ELEMENT(S) \
   1566   (gcc_checking_assert (!(S)->dr_aux.dr), (S)->next_element)
   1567 #define REDUC_GROUP_SIZE(S) \
   1568   (gcc_checking_assert (!(S)->dr_aux.dr), (S)->size)
   1569 
   1570 #define STMT_VINFO_RELEVANT_P(S)          ((S)->relevant != vect_unused_in_scope)
   1571 
   1572 #define HYBRID_SLP_STMT(S)                ((S)->slp_type == hybrid)
   1573 #define PURE_SLP_STMT(S)                  ((S)->slp_type == pure_slp)
   1574 #define STMT_SLP_TYPE(S)                   (S)->slp_type
   1575 
   1576 /* Contains the scalar or vector costs for a vec_info.  */
   1577 class vector_costs
   1578 {
   1579 public:
   1580   vector_costs (vec_info *, bool);
   1581   virtual ~vector_costs () {}
   1582 
   1583   /* Update the costs in response to adding COUNT copies of a statement.
   1584 
   1585      - WHERE specifies whether the cost occurs in the loop prologue,
   1586        the loop body, or the loop epilogue.
   1587      - KIND is the kind of statement, which is always meaningful.
   1588      - STMT_INFO or NODE, if nonnull, describe the statement that will be
   1589        vectorized.
   1590      - VECTYPE, if nonnull, is the vector type that the vectorized
   1591        statement will operate on.  Note that this should be used in
   1592        preference to STMT_VINFO_VECTYPE (STMT_INFO) since the latter
   1593        is not correct for SLP.
   1594      - for unaligned_load and unaligned_store statements, MISALIGN is
   1595        the byte misalignment of the load or store relative to the target's
   1596        preferred alignment for VECTYPE, or DR_MISALIGNMENT_UNKNOWN
   1597        if the misalignment is not known.
   1598 
   1599      Return the calculated cost as well as recording it.  The return
   1600      value is used for dumping purposes.  */
   1601   virtual unsigned int add_stmt_cost (int count, vect_cost_for_stmt kind,
   1602 				      stmt_vec_info stmt_info,
   1603 				      slp_tree node,
   1604 				      tree vectype, int misalign,
   1605 				      vect_cost_model_location where);
   1606 
   1607   /* Finish calculating the cost of the code.  The results can be
   1608      read back using the functions below.
   1609 
   1610      If the costs describe vector code, SCALAR_COSTS gives the costs
   1611      of the corresponding scalar code, otherwise it is null.  */
   1612   virtual void finish_cost (const vector_costs *scalar_costs);
   1613 
   1614   /* The costs in THIS and OTHER both describe ways of vectorizing
   1615      a main loop.  Return true if the costs described by THIS are
   1616      cheaper than the costs described by OTHER.  Return false if any
   1617      of the following are true:
   1618 
   1619      - THIS and OTHER are of equal cost
   1620      - OTHER is better than THIS
   1621      - we can't be sure about the relative costs of THIS and OTHER.  */
   1622   virtual bool better_main_loop_than_p (const vector_costs *other) const;
   1623 
   1624   /* Likewise, but the costs in THIS and OTHER both describe ways of
   1625      vectorizing an epilogue loop of MAIN_LOOP.  */
   1626   virtual bool better_epilogue_loop_than_p (const vector_costs *other,
   1627 					    loop_vec_info main_loop) const;
   1628 
   1629   unsigned int prologue_cost () const;
   1630   unsigned int body_cost () const;
   1631   unsigned int epilogue_cost () const;
   1632   unsigned int outside_cost () const;
   1633   unsigned int total_cost () const;
   1634   unsigned int suggested_unroll_factor () const;
   1635 
   1636 protected:
   1637   unsigned int record_stmt_cost (stmt_vec_info, vect_cost_model_location,
   1638 				 unsigned int);
   1639   unsigned int adjust_cost_for_freq (stmt_vec_info, vect_cost_model_location,
   1640 				     unsigned int);
   1641   int compare_inside_loop_cost (const vector_costs *) const;
   1642   int compare_outside_loop_cost (const vector_costs *) const;
   1643 
   1644   /* The region of code that we're considering vectorizing.  */
   1645   vec_info *m_vinfo;
   1646 
   1647   /* True if we're costing the scalar code, false if we're costing
   1648      the vector code.  */
   1649   bool m_costing_for_scalar;
   1650 
   1651   /* The costs of the three regions, indexed by vect_cost_model_location.  */
   1652   unsigned int m_costs[3];
   1653 
   1654   /* The suggested unrolling factor determined at finish_cost.  */
   1655   unsigned int m_suggested_unroll_factor;
   1656 
   1657   /* True if finish_cost has been called.  */
   1658   bool m_finished;
   1659 };
   1660 
   1661 /* Create costs for VINFO.  COSTING_FOR_SCALAR is true if the costs
   1662    are for scalar code, false if they are for vector code.  */
   1663 
   1664 inline
   1665 vector_costs::vector_costs (vec_info *vinfo, bool costing_for_scalar)
   1666   : m_vinfo (vinfo),
   1667     m_costing_for_scalar (costing_for_scalar),
   1668     m_costs (),
   1669     m_suggested_unroll_factor(1),
   1670     m_finished (false)
   1671 {
   1672 }
   1673 
   1674 /* Return the cost of the prologue code (in abstract units).  */
   1675 
   1676 inline unsigned int
   1677 vector_costs::prologue_cost () const
   1678 {
   1679   gcc_checking_assert (m_finished);
   1680   return m_costs[vect_prologue];
   1681 }
   1682 
   1683 /* Return the cost of the body code (in abstract units).  */
   1684 
   1685 inline unsigned int
   1686 vector_costs::body_cost () const
   1687 {
   1688   gcc_checking_assert (m_finished);
   1689   return m_costs[vect_body];
   1690 }
   1691 
   1692 /* Return the cost of the epilogue code (in abstract units).  */
   1693 
   1694 inline unsigned int
   1695 vector_costs::epilogue_cost () const
   1696 {
   1697   gcc_checking_assert (m_finished);
   1698   return m_costs[vect_epilogue];
   1699 }
   1700 
   1701 /* Return the cost of the prologue and epilogue code (in abstract units).  */
   1702 
   1703 inline unsigned int
   1704 vector_costs::outside_cost () const
   1705 {
   1706   return prologue_cost () + epilogue_cost ();
   1707 }
   1708 
   1709 /* Return the cost of the prologue, body and epilogue code
   1710    (in abstract units).  */
   1711 
   1712 inline unsigned int
   1713 vector_costs::total_cost () const
   1714 {
   1715   return body_cost () + outside_cost ();
   1716 }
   1717 
   1718 /* Return the suggested unroll factor.  */
   1719 
   1720 inline unsigned int
   1721 vector_costs::suggested_unroll_factor () const
   1722 {
   1723   gcc_checking_assert (m_finished);
   1724   return m_suggested_unroll_factor;
   1725 }
   1726 
   1727 #define VECT_MAX_COST 1000
   1728 
   1729 /* The maximum number of intermediate steps required in multi-step type
   1730    conversion.  */
   1731 #define MAX_INTERM_CVT_STEPS         3
   1732 
   1733 #define MAX_VECTORIZATION_FACTOR INT_MAX
   1734 
   1735 /* Nonzero if TYPE represents a (scalar) boolean type or type
   1736    in the middle-end compatible with it (unsigned precision 1 integral
   1737    types).  Used to determine which types should be vectorized as
   1738    VECTOR_BOOLEAN_TYPE_P.  */
   1739 
   1740 #define VECT_SCALAR_BOOLEAN_TYPE_P(TYPE) \
   1741   (TREE_CODE (TYPE) == BOOLEAN_TYPE		\
   1742    || ((TREE_CODE (TYPE) == INTEGER_TYPE	\
   1743 	|| TREE_CODE (TYPE) == ENUMERAL_TYPE)	\
   1744        && TYPE_PRECISION (TYPE) == 1		\
   1745        && TYPE_UNSIGNED (TYPE)))
   1746 
   1747 inline bool
   1748 nested_in_vect_loop_p (class loop *loop, stmt_vec_info stmt_info)
   1749 {
   1750   return (loop->inner
   1751 	  && (loop->inner == (gimple_bb (stmt_info->stmt))->loop_father));
   1752 }
   1753 
   1754 /* PHI is either a scalar reduction phi or a scalar induction phi.
   1755    Return the initial value of the variable on entry to the containing
   1756    loop.  */
   1757 
   1758 inline tree
   1759 vect_phi_initial_value (gphi *phi)
   1760 {
   1761   basic_block bb = gimple_bb (phi);
   1762   edge pe = loop_preheader_edge (bb->loop_father);
   1763   gcc_assert (pe->dest == bb);
   1764   return PHI_ARG_DEF_FROM_EDGE (phi, pe);
   1765 }
   1766 
   1767 /* Return true if STMT_INFO should produce a vector mask type rather than
   1768    a normal nonmask type.  */
   1769 
   1770 inline bool
   1771 vect_use_mask_type_p (stmt_vec_info stmt_info)
   1772 {
   1773   return stmt_info->mask_precision && stmt_info->mask_precision != ~0U;
   1774 }
   1775 
   1776 /* Return TRUE if a statement represented by STMT_INFO is a part of a
   1777    pattern.  */
   1778 
   1779 inline bool
   1780 is_pattern_stmt_p (stmt_vec_info stmt_info)
   1781 {
   1782   return stmt_info->pattern_stmt_p;
   1783 }
   1784 
   1785 /* If STMT_INFO is a pattern statement, return the statement that it
   1786    replaces, otherwise return STMT_INFO itself.  */
   1787 
   1788 inline stmt_vec_info
   1789 vect_orig_stmt (stmt_vec_info stmt_info)
   1790 {
   1791   if (is_pattern_stmt_p (stmt_info))
   1792     return STMT_VINFO_RELATED_STMT (stmt_info);
   1793   return stmt_info;
   1794 }
   1795 
   1796 /* Return the later statement between STMT1_INFO and STMT2_INFO.  */
   1797 
   1798 inline stmt_vec_info
   1799 get_later_stmt (stmt_vec_info stmt1_info, stmt_vec_info stmt2_info)
   1800 {
   1801   if (gimple_uid (vect_orig_stmt (stmt1_info)->stmt)
   1802       > gimple_uid (vect_orig_stmt (stmt2_info)->stmt))
   1803     return stmt1_info;
   1804   else
   1805     return stmt2_info;
   1806 }
   1807 
   1808 /* If STMT_INFO has been replaced by a pattern statement, return the
   1809    replacement statement, otherwise return STMT_INFO itself.  */
   1810 
   1811 inline stmt_vec_info
   1812 vect_stmt_to_vectorize (stmt_vec_info stmt_info)
   1813 {
   1814   if (STMT_VINFO_IN_PATTERN_P (stmt_info))
   1815     return STMT_VINFO_RELATED_STMT (stmt_info);
   1816   return stmt_info;
   1817 }
   1818 
   1819 /* Return true if BB is a loop header.  */
   1820 
   1821 inline bool
   1822 is_loop_header_bb_p (basic_block bb)
   1823 {
   1824   if (bb == (bb->loop_father)->header)
   1825     return true;
   1826 
   1827   return false;
   1828 }
   1829 
   1830 /* Return pow2 (X).  */
   1831 
   1832 inline int
   1833 vect_pow2 (int x)
   1834 {
   1835   int i, res = 1;
   1836 
   1837   for (i = 0; i < x; i++)
   1838     res *= 2;
   1839 
   1840   return res;
   1841 }
   1842 
   1843 /* Alias targetm.vectorize.builtin_vectorization_cost.  */
   1844 
   1845 inline int
   1846 builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
   1847 			    tree vectype, int misalign)
   1848 {
   1849   return targetm.vectorize.builtin_vectorization_cost (type_of_cost,
   1850 						       vectype, misalign);
   1851 }
   1852 
   1853 /* Get cost by calling cost target builtin.  */
   1854 
   1855 inline
   1856 int vect_get_stmt_cost (enum vect_cost_for_stmt type_of_cost)
   1857 {
   1858   return builtin_vectorization_cost (type_of_cost, NULL, 0);
   1859 }
   1860 
   1861 /* Alias targetm.vectorize.init_cost.  */
   1862 
   1863 inline vector_costs *
   1864 init_cost (vec_info *vinfo, bool costing_for_scalar)
   1865 {
   1866   return targetm.vectorize.create_costs (vinfo, costing_for_scalar);
   1867 }
   1868 
   1869 extern void dump_stmt_cost (FILE *, int, enum vect_cost_for_stmt,
   1870 			    stmt_vec_info, slp_tree, tree, int, unsigned,
   1871 			    enum vect_cost_model_location);
   1872 
   1873 /* Alias targetm.vectorize.add_stmt_cost.  */
   1874 
   1875 inline unsigned
   1876 add_stmt_cost (vector_costs *costs, int count,
   1877 	       enum vect_cost_for_stmt kind,
   1878 	       stmt_vec_info stmt_info, slp_tree node,
   1879 	       tree vectype, int misalign,
   1880 	       enum vect_cost_model_location where)
   1881 {
   1882   unsigned cost = costs->add_stmt_cost (count, kind, stmt_info, node, vectype,
   1883 					misalign, where);
   1884   if (dump_file && (dump_flags & TDF_DETAILS))
   1885     dump_stmt_cost (dump_file, count, kind, stmt_info, node, vectype, misalign,
   1886 		    cost, where);
   1887   return cost;
   1888 }
   1889 
   1890 inline unsigned
   1891 add_stmt_cost (vector_costs *costs, int count, enum vect_cost_for_stmt kind,
   1892 	       enum vect_cost_model_location where)
   1893 {
   1894   gcc_assert (kind == cond_branch_taken || kind == cond_branch_not_taken
   1895 	      || kind == scalar_stmt);
   1896   return add_stmt_cost (costs, count, kind, NULL, NULL, NULL_TREE, 0, where);
   1897 }
   1898 
   1899 /* Alias targetm.vectorize.add_stmt_cost.  */
   1900 
   1901 inline unsigned
   1902 add_stmt_cost (vector_costs *costs, stmt_info_for_cost *i)
   1903 {
   1904   return add_stmt_cost (costs, i->count, i->kind, i->stmt_info, i->node,
   1905 			i->vectype, i->misalign, i->where);
   1906 }
   1907 
   1908 /* Alias targetm.vectorize.finish_cost.  */
   1909 
   1910 inline void
   1911 finish_cost (vector_costs *costs, const vector_costs *scalar_costs,
   1912 	     unsigned *prologue_cost, unsigned *body_cost,
   1913 	     unsigned *epilogue_cost, unsigned *suggested_unroll_factor = NULL)
   1914 {
   1915   costs->finish_cost (scalar_costs);
   1916   *prologue_cost = costs->prologue_cost ();
   1917   *body_cost = costs->body_cost ();
   1918   *epilogue_cost = costs->epilogue_cost ();
   1919   if (suggested_unroll_factor)
   1920     *suggested_unroll_factor = costs->suggested_unroll_factor ();
   1921 }
   1922 
   1923 inline void
   1924 add_stmt_costs (vector_costs *costs, stmt_vector_for_cost *cost_vec)
   1925 {
   1926   stmt_info_for_cost *cost;
   1927   unsigned i;
   1928   FOR_EACH_VEC_ELT (*cost_vec, i, cost)
   1929     add_stmt_cost (costs, cost->count, cost->kind, cost->stmt_info,
   1930 		   cost->node, cost->vectype, cost->misalign, cost->where);
   1931 }
   1932 
   1933 /*-----------------------------------------------------------------*/
   1934 /* Info on data references alignment.                              */
   1935 /*-----------------------------------------------------------------*/
   1936 #define DR_MISALIGNMENT_UNKNOWN (-1)
   1937 #define DR_MISALIGNMENT_UNINITIALIZED (-2)
   1938 
   1939 inline void
   1940 set_dr_misalignment (dr_vec_info *dr_info, int val)
   1941 {
   1942   dr_info->misalignment = val;
   1943 }
   1944 
   1945 extern int dr_misalignment (dr_vec_info *dr_info, tree vectype,
   1946 			    poly_int64 offset = 0);
   1947 
   1948 #define SET_DR_MISALIGNMENT(DR, VAL) set_dr_misalignment (DR, VAL)
   1949 
   1950 /* Only defined once DR_MISALIGNMENT is defined.  */
   1951 inline const poly_uint64
   1952 dr_target_alignment (dr_vec_info *dr_info)
   1953 {
   1954   if (STMT_VINFO_GROUPED_ACCESS (dr_info->stmt))
   1955     dr_info = STMT_VINFO_DR_INFO (DR_GROUP_FIRST_ELEMENT (dr_info->stmt));
   1956   return dr_info->target_alignment;
   1957 }
   1958 #define DR_TARGET_ALIGNMENT(DR) dr_target_alignment (DR)
   1959 
   1960 inline void
   1961 set_dr_target_alignment (dr_vec_info *dr_info, poly_uint64 val)
   1962 {
   1963   dr_info->target_alignment = val;
   1964 }
   1965 #define SET_DR_TARGET_ALIGNMENT(DR, VAL) set_dr_target_alignment (DR, VAL)
   1966 
   1967 /* Return true if data access DR_INFO is aligned to the targets
   1968    preferred alignment for VECTYPE (which may be less than a full vector).  */
   1969 
   1970 inline bool
   1971 aligned_access_p (dr_vec_info *dr_info, tree vectype)
   1972 {
   1973   return (dr_misalignment (dr_info, vectype) == 0);
   1974 }
   1975 
   1976 /* Return TRUE if the (mis-)alignment of the data access is known with
   1977    respect to the targets preferred alignment for VECTYPE, and FALSE
   1978    otherwise.  */
   1979 
   1980 inline bool
   1981 known_alignment_for_access_p (dr_vec_info *dr_info, tree vectype)
   1982 {
   1983   return (dr_misalignment (dr_info, vectype) != DR_MISALIGNMENT_UNKNOWN);
   1984 }
   1985 
   1986 /* Return the minimum alignment in bytes that the vectorized version
   1987    of DR_INFO is guaranteed to have.  */
   1988 
   1989 inline unsigned int
   1990 vect_known_alignment_in_bytes (dr_vec_info *dr_info, tree vectype)
   1991 {
   1992   int misalignment = dr_misalignment (dr_info, vectype);
   1993   if (misalignment == DR_MISALIGNMENT_UNKNOWN)
   1994     return TYPE_ALIGN_UNIT (TREE_TYPE (DR_REF (dr_info->dr)));
   1995   else if (misalignment == 0)
   1996     return known_alignment (DR_TARGET_ALIGNMENT (dr_info));
   1997   return misalignment & -misalignment;
   1998 }
   1999 
   2000 /* Return the behavior of DR_INFO with respect to the vectorization context
   2001    (which for outer loop vectorization might not be the behavior recorded
   2002    in DR_INFO itself).  */
   2003 
   2004 inline innermost_loop_behavior *
   2005 vect_dr_behavior (vec_info *vinfo, dr_vec_info *dr_info)
   2006 {
   2007   stmt_vec_info stmt_info = dr_info->stmt;
   2008   loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (vinfo);
   2009   if (loop_vinfo == NULL
   2010       || !nested_in_vect_loop_p (LOOP_VINFO_LOOP (loop_vinfo), stmt_info))
   2011     return &DR_INNERMOST (dr_info->dr);
   2012   else
   2013     return &STMT_VINFO_DR_WRT_VEC_LOOP (stmt_info);
   2014 }
   2015 
   2016 /* Return the offset calculated by adding the offset of this DR_INFO to the
   2017    corresponding data_reference's offset.  If CHECK_OUTER then use
   2018    vect_dr_behavior to select the appropriate data_reference to use.  */
   2019 
   2020 inline tree
   2021 get_dr_vinfo_offset (vec_info *vinfo,
   2022 		     dr_vec_info *dr_info, bool check_outer = false)
   2023 {
   2024   innermost_loop_behavior *base;
   2025   if (check_outer)
   2026     base = vect_dr_behavior (vinfo, dr_info);
   2027   else
   2028     base = &dr_info->dr->innermost;
   2029 
   2030   tree offset = base->offset;
   2031 
   2032   if (!dr_info->offset)
   2033     return offset;
   2034 
   2035   offset = fold_convert (sizetype, offset);
   2036   return fold_build2 (PLUS_EXPR, TREE_TYPE (dr_info->offset), offset,
   2037 		      dr_info->offset);
   2038 }
   2039 
   2040 
   2041 /* Return the vect cost model for LOOP.  */
   2042 inline enum vect_cost_model
   2043 loop_cost_model (loop_p loop)
   2044 {
   2045   if (loop != NULL
   2046       && loop->force_vectorize
   2047       && flag_simd_cost_model != VECT_COST_MODEL_DEFAULT)
   2048     return flag_simd_cost_model;
   2049   return flag_vect_cost_model;
   2050 }
   2051 
   2052 /* Return true if the vect cost model is unlimited.  */
   2053 inline bool
   2054 unlimited_cost_model (loop_p loop)
   2055 {
   2056   return loop_cost_model (loop) == VECT_COST_MODEL_UNLIMITED;
   2057 }
   2058 
   2059 /* Return true if the loop described by LOOP_VINFO is fully-masked and
   2060    if the first iteration should use a partial mask in order to achieve
   2061    alignment.  */
   2062 
   2063 inline bool
   2064 vect_use_loop_mask_for_alignment_p (loop_vec_info loop_vinfo)
   2065 {
   2066   return (LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)
   2067 	  && LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo));
   2068 }
   2069 
   2070 /* Return the number of vectors of type VECTYPE that are needed to get
   2071    NUNITS elements.  NUNITS should be based on the vectorization factor,
   2072    so it is always a known multiple of the number of elements in VECTYPE.  */
   2073 
   2074 inline unsigned int
   2075 vect_get_num_vectors (poly_uint64 nunits, tree vectype)
   2076 {
   2077   return exact_div (nunits, TYPE_VECTOR_SUBPARTS (vectype)).to_constant ();
   2078 }
   2079 
   2080 /* Return the number of copies needed for loop vectorization when
   2081    a statement operates on vectors of type VECTYPE.  This is the
   2082    vectorization factor divided by the number of elements in
   2083    VECTYPE and is always known at compile time.  */
   2084 
   2085 inline unsigned int
   2086 vect_get_num_copies (loop_vec_info loop_vinfo, tree vectype)
   2087 {
   2088   return vect_get_num_vectors (LOOP_VINFO_VECT_FACTOR (loop_vinfo), vectype);
   2089 }
   2090 
   2091 /* Update maximum unit count *MAX_NUNITS so that it accounts for
   2092    NUNITS.  *MAX_NUNITS can be 1 if we haven't yet recorded anything.  */
   2093 
   2094 inline void
   2095 vect_update_max_nunits (poly_uint64 *max_nunits, poly_uint64 nunits)
   2096 {
   2097   /* All unit counts have the form vec_info::vector_size * X for some
   2098      rational X, so two unit sizes must have a common multiple.
   2099      Everything is a multiple of the initial value of 1.  */
   2100   *max_nunits = force_common_multiple (*max_nunits, nunits);
   2101 }
   2102 
   2103 /* Update maximum unit count *MAX_NUNITS so that it accounts for
   2104    the number of units in vector type VECTYPE.  *MAX_NUNITS can be 1
   2105    if we haven't yet recorded any vector types.  */
   2106 
   2107 inline void
   2108 vect_update_max_nunits (poly_uint64 *max_nunits, tree vectype)
   2109 {
   2110   vect_update_max_nunits (max_nunits, TYPE_VECTOR_SUBPARTS (vectype));
   2111 }
   2112 
   2113 /* Return the vectorization factor that should be used for costing
   2114    purposes while vectorizing the loop described by LOOP_VINFO.
   2115    Pick a reasonable estimate if the vectorization factor isn't
   2116    known at compile time.  */
   2117 
   2118 inline unsigned int
   2119 vect_vf_for_cost (loop_vec_info loop_vinfo)
   2120 {
   2121   return estimated_poly_value (LOOP_VINFO_VECT_FACTOR (loop_vinfo));
   2122 }
   2123 
   2124 /* Estimate the number of elements in VEC_TYPE for costing purposes.
   2125    Pick a reasonable estimate if the exact number isn't known at
   2126    compile time.  */
   2127 
   2128 inline unsigned int
   2129 vect_nunits_for_cost (tree vec_type)
   2130 {
   2131   return estimated_poly_value (TYPE_VECTOR_SUBPARTS (vec_type));
   2132 }
   2133 
   2134 /* Return the maximum possible vectorization factor for LOOP_VINFO.  */
   2135 
   2136 inline unsigned HOST_WIDE_INT
   2137 vect_max_vf (loop_vec_info loop_vinfo)
   2138 {
   2139   unsigned HOST_WIDE_INT vf;
   2140   if (LOOP_VINFO_VECT_FACTOR (loop_vinfo).is_constant (&vf))
   2141     return vf;
   2142   return MAX_VECTORIZATION_FACTOR;
   2143 }
   2144 
   2145 /* Return the size of the value accessed by unvectorized data reference
   2146    DR_INFO.  This is only valid once STMT_VINFO_VECTYPE has been calculated
   2147    for the associated gimple statement, since that guarantees that DR_INFO
   2148    accesses either a scalar or a scalar equivalent.  ("Scalar equivalent"
   2149    here includes things like V1SI, which can be vectorized in the same way
   2150    as a plain SI.)  */
   2151 
   2152 inline unsigned int
   2153 vect_get_scalar_dr_size (dr_vec_info *dr_info)
   2154 {
   2155   return tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr_info->dr))));
   2156 }
   2157 
   2158 /* Return true if LOOP_VINFO requires a runtime check for whether the
   2159    vector loop is profitable.  */
   2160 
   2161 inline bool
   2162 vect_apply_runtime_profitability_check_p (loop_vec_info loop_vinfo)
   2163 {
   2164   unsigned int th = LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo);
   2165   return (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
   2166 	  && th >= vect_vf_for_cost (loop_vinfo));
   2167 }
   2168 
   2169 /* Source location + hotness information. */
   2170 extern dump_user_location_t vect_location;
   2171 
   2172 /* A macro for calling:
   2173      dump_begin_scope (MSG, vect_location);
   2174    via an RAII object, thus printing "=== MSG ===\n" to the dumpfile etc,
   2175    and then calling
   2176      dump_end_scope ();
   2177    once the object goes out of scope, thus capturing the nesting of
   2178    the scopes.
   2179 
   2180    These scopes affect dump messages within them: dump messages at the
   2181    top level implicitly default to MSG_PRIORITY_USER_FACING, whereas those
   2182    in a nested scope implicitly default to MSG_PRIORITY_INTERNALS.  */
   2183 
   2184 #define DUMP_VECT_SCOPE(MSG) \
   2185   AUTO_DUMP_SCOPE (MSG, vect_location)
   2186 
   2187 /* A sentinel class for ensuring that the "vect_location" global gets
   2188    reset at the end of a scope.
   2189 
   2190    The "vect_location" global is used during dumping and contains a
   2191    location_t, which could contain references to a tree block via the
   2192    ad-hoc data.  This data is used for tracking inlining information,
   2193    but it's not a GC root; it's simply assumed that such locations never
   2194    get accessed if the blocks are optimized away.
   2195 
   2196    Hence we need to ensure that such locations are purged at the end
   2197    of any operations using them (e.g. via this class).  */
   2198 
   2199 class auto_purge_vect_location
   2200 {
   2201  public:
   2202   ~auto_purge_vect_location ();
   2203 };
   2204 
   2205 /*-----------------------------------------------------------------*/
   2206 /* Function prototypes.                                            */
   2207 /*-----------------------------------------------------------------*/
   2208 
   2209 /* Simple loop peeling and versioning utilities for vectorizer's purposes -
   2210    in tree-vect-loop-manip.cc.  */
   2211 extern void vect_set_loop_condition (class loop *, edge, loop_vec_info,
   2212 				     tree, tree, tree, bool);
   2213 extern bool slpeel_can_duplicate_loop_p (const class loop *, const_edge,
   2214 					 const_edge);
   2215 class loop *slpeel_tree_duplicate_loop_to_edge_cfg (class loop *, edge,
   2216 						    class loop *, edge,
   2217 						    edge, edge *, bool = true,
   2218 						    vec<basic_block> * = NULL);
   2219 class loop *vect_loop_versioning (loop_vec_info, gimple *);
   2220 extern class loop *vect_do_peeling (loop_vec_info, tree, tree,
   2221 				    tree *, tree *, tree *, int, bool, bool,
   2222 				    tree *);
   2223 extern tree vect_get_main_loop_result (loop_vec_info, tree, tree);
   2224 extern void vect_prepare_for_masked_peels (loop_vec_info);
   2225 extern dump_user_location_t find_loop_location (class loop *);
   2226 extern bool vect_can_advance_ivs_p (loop_vec_info);
   2227 extern void vect_update_inits_of_drs (loop_vec_info, tree, tree_code);
   2228 extern edge vec_init_loop_exit_info (class loop *);
   2229 extern void vect_iv_increment_position (edge, gimple_stmt_iterator *, bool *);
   2230 
   2231 /* In tree-vect-stmts.cc.  */
   2232 extern tree get_related_vectype_for_scalar_type (machine_mode, tree,
   2233 						 poly_uint64 = 0);
   2234 extern tree get_vectype_for_scalar_type (vec_info *, tree, unsigned int = 0);
   2235 extern tree get_vectype_for_scalar_type (vec_info *, tree, slp_tree);
   2236 extern tree get_mask_type_for_scalar_type (vec_info *, tree, unsigned int = 0);
   2237 extern tree get_mask_type_for_scalar_type (vec_info *, tree, slp_tree);
   2238 extern tree get_same_sized_vectype (tree, tree);
   2239 extern bool vect_chooses_same_modes_p (vec_info *, machine_mode);
   2240 extern bool vect_get_loop_mask_type (loop_vec_info);
   2241 extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *,
   2242 				stmt_vec_info * = NULL, gimple ** = NULL);
   2243 extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *,
   2244 				tree *, stmt_vec_info * = NULL,
   2245 				gimple ** = NULL);
   2246 extern bool vect_is_simple_use (vec_info *, stmt_vec_info, slp_tree,
   2247 				unsigned, tree *, slp_tree *,
   2248 				enum vect_def_type *,
   2249 				tree *, stmt_vec_info * = NULL);
   2250 extern bool vect_maybe_update_slp_op_vectype (slp_tree, tree);
   2251 extern tree perm_mask_for_reverse (tree);
   2252 extern bool supportable_widening_operation (vec_info*, code_helper,
   2253 					    stmt_vec_info, tree, tree,
   2254 					    code_helper*, code_helper*,
   2255 					    int*, vec<tree> *);
   2256 extern bool supportable_narrowing_operation (code_helper, tree, tree,
   2257 					     code_helper *, int *,
   2258 					     vec<tree> *);
   2259 
   2260 extern unsigned record_stmt_cost (stmt_vector_for_cost *, int,
   2261 				  enum vect_cost_for_stmt, stmt_vec_info,
   2262 				  tree, int, enum vect_cost_model_location);
   2263 extern unsigned record_stmt_cost (stmt_vector_for_cost *, int,
   2264 				  enum vect_cost_for_stmt, slp_tree,
   2265 				  tree, int, enum vect_cost_model_location);
   2266 extern unsigned record_stmt_cost (stmt_vector_for_cost *, int,
   2267 				  enum vect_cost_for_stmt,
   2268 				  enum vect_cost_model_location);
   2269 
   2270 /* Overload of record_stmt_cost with VECTYPE derived from STMT_INFO.  */
   2271 
   2272 inline unsigned
   2273 record_stmt_cost (stmt_vector_for_cost *body_cost_vec, int count,
   2274 		  enum vect_cost_for_stmt kind, stmt_vec_info stmt_info,
   2275 		  int misalign, enum vect_cost_model_location where)
   2276 {
   2277   return record_stmt_cost (body_cost_vec, count, kind, stmt_info,
   2278 			   STMT_VINFO_VECTYPE (stmt_info), misalign, where);
   2279 }
   2280 
   2281 extern void vect_finish_replace_stmt (vec_info *, stmt_vec_info, gimple *);
   2282 extern void vect_finish_stmt_generation (vec_info *, stmt_vec_info, gimple *,
   2283 					 gimple_stmt_iterator *);
   2284 extern opt_result vect_mark_stmts_to_be_vectorized (loop_vec_info, bool *);
   2285 extern tree vect_get_store_rhs (stmt_vec_info);
   2286 void vect_get_vec_defs_for_operand (vec_info *vinfo, stmt_vec_info, unsigned,
   2287 				    tree op, vec<tree> *, tree = NULL);
   2288 void vect_get_vec_defs (vec_info *, stmt_vec_info, slp_tree, unsigned,
   2289 			tree, vec<tree> *,
   2290 			tree = NULL, vec<tree> * = NULL,
   2291 			tree = NULL, vec<tree> * = NULL,
   2292 			tree = NULL, vec<tree> * = NULL);
   2293 void vect_get_vec_defs (vec_info *, stmt_vec_info, slp_tree, unsigned,
   2294 			tree, tree, vec<tree> *,
   2295 			tree = NULL, tree = NULL, vec<tree> * = NULL,
   2296 			tree = NULL, tree = NULL, vec<tree> * = NULL,
   2297 			tree = NULL, tree = NULL, vec<tree> * = NULL);
   2298 extern tree vect_init_vector (vec_info *, stmt_vec_info, tree, tree,
   2299                               gimple_stmt_iterator *);
   2300 extern tree vect_get_slp_vect_def (slp_tree, unsigned);
   2301 extern bool vect_transform_stmt (vec_info *, stmt_vec_info,
   2302 				 gimple_stmt_iterator *,
   2303 				 slp_tree, slp_instance);
   2304 extern void vect_remove_stores (vec_info *, stmt_vec_info);
   2305 extern bool vect_nop_conversion_p (stmt_vec_info);
   2306 extern opt_result vect_analyze_stmt (vec_info *, stmt_vec_info, bool *,
   2307 				     slp_tree,
   2308 				     slp_instance, stmt_vector_for_cost *);
   2309 extern void vect_get_load_cost (vec_info *, stmt_vec_info, int,
   2310 				dr_alignment_support, int, bool,
   2311 				unsigned int *, unsigned int *,
   2312 				stmt_vector_for_cost *,
   2313 				stmt_vector_for_cost *, bool);
   2314 extern void vect_get_store_cost (vec_info *, stmt_vec_info, int,
   2315 				 dr_alignment_support, int,
   2316 				 unsigned int *, stmt_vector_for_cost *);
   2317 extern bool vect_supportable_shift (vec_info *, enum tree_code, tree);
   2318 extern tree vect_gen_perm_mask_any (tree, const vec_perm_indices &);
   2319 extern tree vect_gen_perm_mask_checked (tree, const vec_perm_indices &);
   2320 extern void optimize_mask_stores (class loop*);
   2321 extern tree vect_gen_while (gimple_seq *, tree, tree, tree,
   2322 			    const char * = nullptr);
   2323 extern tree vect_gen_while_not (gimple_seq *, tree, tree, tree);
   2324 extern opt_result vect_get_vector_types_for_stmt (vec_info *,
   2325 						  stmt_vec_info, tree *,
   2326 						  tree *, unsigned int = 0);
   2327 extern opt_tree vect_get_mask_type_for_stmt (stmt_vec_info, unsigned int = 0);
   2328 
   2329 /* In tree-if-conv.cc.  */
   2330 extern bool ref_within_array_bound (gimple *, tree);
   2331 
   2332 /* In tree-vect-data-refs.cc.  */
   2333 extern bool vect_can_force_dr_alignment_p (const_tree, poly_uint64);
   2334 extern enum dr_alignment_support vect_supportable_dr_alignment
   2335 				   (vec_info *, dr_vec_info *, tree, int);
   2336 extern tree vect_get_smallest_scalar_type (stmt_vec_info, tree);
   2337 extern opt_result vect_analyze_data_ref_dependences (loop_vec_info, unsigned int *);
   2338 extern bool vect_slp_analyze_instance_dependence (vec_info *, slp_instance);
   2339 extern opt_result vect_enhance_data_refs_alignment (loop_vec_info);
   2340 extern opt_result vect_analyze_data_refs_alignment (loop_vec_info);
   2341 extern bool vect_slp_analyze_instance_alignment (vec_info *, slp_instance);
   2342 extern opt_result vect_analyze_data_ref_accesses (vec_info *, vec<int> *);
   2343 extern opt_result vect_prune_runtime_alias_test_list (loop_vec_info);
   2344 extern bool vect_gather_scatter_fn_p (vec_info *, bool, bool, tree, tree,
   2345 				      tree, int, internal_fn *, tree *);
   2346 extern bool vect_check_gather_scatter (stmt_vec_info, loop_vec_info,
   2347 				       gather_scatter_info *);
   2348 extern opt_result vect_find_stmt_data_reference (loop_p, gimple *,
   2349 						 vec<data_reference_p> *,
   2350 						 vec<int> *, int);
   2351 extern opt_result vect_analyze_data_refs (vec_info *, poly_uint64 *, bool *);
   2352 extern void vect_record_base_alignments (vec_info *);
   2353 extern tree vect_create_data_ref_ptr (vec_info *,
   2354 				      stmt_vec_info, tree, class loop *, tree,
   2355 				      tree *, gimple_stmt_iterator *,
   2356 				      gimple **, bool,
   2357 				      tree = NULL_TREE);
   2358 extern tree bump_vector_ptr (vec_info *, tree, gimple *, gimple_stmt_iterator *,
   2359 			     stmt_vec_info, tree);
   2360 extern void vect_copy_ref_info (tree, tree);
   2361 extern tree vect_create_destination_var (tree, tree);
   2362 extern bool vect_grouped_store_supported (tree, unsigned HOST_WIDE_INT);
   2363 extern internal_fn vect_store_lanes_supported (tree, unsigned HOST_WIDE_INT, bool);
   2364 extern bool vect_grouped_load_supported (tree, bool, unsigned HOST_WIDE_INT);
   2365 extern internal_fn vect_load_lanes_supported (tree, unsigned HOST_WIDE_INT, bool);
   2366 extern void vect_permute_store_chain (vec_info *, vec<tree> &,
   2367 				      unsigned int, stmt_vec_info,
   2368 				      gimple_stmt_iterator *, vec<tree> *);
   2369 extern tree vect_setup_realignment (vec_info *,
   2370 				    stmt_vec_info, gimple_stmt_iterator *,
   2371 				    tree *, enum dr_alignment_support, tree,
   2372 	                            class loop **);
   2373 extern void vect_transform_grouped_load (vec_info *, stmt_vec_info, vec<tree>,
   2374 					 int, gimple_stmt_iterator *);
   2375 extern void vect_record_grouped_load_vectors (vec_info *,
   2376 					      stmt_vec_info, vec<tree>);
   2377 extern tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *);
   2378 extern tree vect_get_new_ssa_name (tree, enum vect_var_kind,
   2379 				   const char * = NULL);
   2380 extern tree vect_create_addr_base_for_vector_ref (vec_info *,
   2381 						  stmt_vec_info, gimple_seq *,
   2382 						  tree);
   2383 
   2384 /* In tree-vect-loop.cc.  */
   2385 extern tree neutral_op_for_reduction (tree, code_helper, tree, bool = true);
   2386 extern widest_int vect_iv_limit_for_partial_vectors (loop_vec_info loop_vinfo);
   2387 bool vect_rgroup_iv_might_wrap_p (loop_vec_info, rgroup_controls *);
   2388 /* Used in tree-vect-loop-manip.cc */
   2389 extern opt_result vect_determine_partial_vectors_and_peeling (loop_vec_info);
   2390 /* Used in gimple-loop-interchange.c and tree-parloops.cc.  */
   2391 extern bool check_reduction_path (dump_user_location_t, loop_p, gphi *, tree,
   2392 				  enum tree_code);
   2393 extern bool needs_fold_left_reduction_p (tree, code_helper);
   2394 /* Drive for loop analysis stage.  */
   2395 extern opt_loop_vec_info vect_analyze_loop (class loop *, gimple *,
   2396 					    vec_info_shared *);
   2397 extern tree vect_build_loop_niters (loop_vec_info, bool * = NULL);
   2398 extern void vect_gen_vector_loop_niters (loop_vec_info, tree, tree *,
   2399 					 tree *, bool);
   2400 extern tree vect_halve_mask_nunits (tree, machine_mode);
   2401 extern tree vect_double_mask_nunits (tree, machine_mode);
   2402 extern void vect_record_loop_mask (loop_vec_info, vec_loop_masks *,
   2403 				   unsigned int, tree, tree);
   2404 extern tree vect_get_loop_mask (loop_vec_info, gimple_stmt_iterator *,
   2405 				vec_loop_masks *,
   2406 				unsigned int, tree, unsigned int);
   2407 extern void vect_record_loop_len (loop_vec_info, vec_loop_lens *, unsigned int,
   2408 				  tree, unsigned int);
   2409 extern tree vect_get_loop_len (loop_vec_info, gimple_stmt_iterator *,
   2410 			       vec_loop_lens *, unsigned int, tree,
   2411 			       unsigned int, unsigned int);
   2412 extern gimple_seq vect_gen_len (tree, tree, tree, tree);
   2413 extern stmt_vec_info info_for_reduction (vec_info *, stmt_vec_info);
   2414 extern bool reduction_fn_for_scalar_code (code_helper, internal_fn *);
   2415 
   2416 /* Drive for loop transformation stage.  */
   2417 extern class loop *vect_transform_loop (loop_vec_info, gimple *);
   2418 struct vect_loop_form_info
   2419 {
   2420   tree number_of_iterations;
   2421   tree number_of_iterationsm1;
   2422   tree assumptions;
   2423   auto_vec<gcond *> conds;
   2424   gcond *inner_loop_cond;
   2425   edge loop_exit;
   2426 };
   2427 extern opt_result vect_analyze_loop_form (class loop *, gimple *,
   2428 					  vect_loop_form_info *);
   2429 extern loop_vec_info vect_create_loop_vinfo (class loop *, vec_info_shared *,
   2430 					     const vect_loop_form_info *,
   2431 					     loop_vec_info = nullptr);
   2432 extern bool vectorizable_live_operation (vec_info *, stmt_vec_info,
   2433 					 slp_tree, slp_instance, int,
   2434 					 bool, stmt_vector_for_cost *);
   2435 extern bool vectorizable_reduction (loop_vec_info, stmt_vec_info,
   2436 				    slp_tree, slp_instance,
   2437 				    stmt_vector_for_cost *);
   2438 extern bool vectorizable_induction (loop_vec_info, stmt_vec_info,
   2439 				    gimple **, slp_tree,
   2440 				    stmt_vector_for_cost *);
   2441 extern bool vect_transform_reduction (loop_vec_info, stmt_vec_info,
   2442 				      gimple_stmt_iterator *,
   2443 				      gimple **, slp_tree);
   2444 extern bool vect_transform_cycle_phi (loop_vec_info, stmt_vec_info,
   2445 				      gimple **,
   2446 				      slp_tree, slp_instance);
   2447 extern bool vectorizable_lc_phi (loop_vec_info, stmt_vec_info,
   2448 				 gimple **, slp_tree);
   2449 extern bool vectorizable_phi (vec_info *, stmt_vec_info, gimple **, slp_tree,
   2450 			      stmt_vector_for_cost *);
   2451 extern bool vectorizable_recurr (loop_vec_info, stmt_vec_info,
   2452 				  gimple **, slp_tree, stmt_vector_for_cost *);
   2453 extern bool vect_emulated_vector_p (tree);
   2454 extern bool vect_can_vectorize_without_simd_p (tree_code);
   2455 extern bool vect_can_vectorize_without_simd_p (code_helper);
   2456 extern int vect_get_known_peeling_cost (loop_vec_info, int, int *,
   2457 					stmt_vector_for_cost *,
   2458 					stmt_vector_for_cost *,
   2459 					stmt_vector_for_cost *);
   2460 extern tree cse_and_gimplify_to_preheader (loop_vec_info, tree);
   2461 
   2462 /* Nonlinear induction.  */
   2463 extern tree vect_peel_nonlinear_iv_init (gimple_seq*, tree, tree,
   2464 					 tree, enum vect_induction_op_type);
   2465 
   2466 /* In tree-vect-slp.cc.  */
   2467 extern void vect_slp_init (void);
   2468 extern void vect_slp_fini (void);
   2469 extern void vect_free_slp_instance (slp_instance);
   2470 extern bool vect_transform_slp_perm_load (vec_info *, slp_tree, const vec<tree> &,
   2471 					  gimple_stmt_iterator *, poly_uint64,
   2472 					  bool, unsigned *,
   2473 					  unsigned * = nullptr, bool = false);
   2474 extern bool vect_slp_analyze_operations (vec_info *);
   2475 extern void vect_schedule_slp (vec_info *, const vec<slp_instance> &);
   2476 extern opt_result vect_analyze_slp (vec_info *, unsigned);
   2477 extern bool vect_make_slp_decision (loop_vec_info);
   2478 extern void vect_detect_hybrid_slp (loop_vec_info);
   2479 extern void vect_optimize_slp (vec_info *);
   2480 extern void vect_gather_slp_loads (vec_info *);
   2481 extern void vect_get_slp_defs (slp_tree, vec<tree> *);
   2482 extern void vect_get_slp_defs (vec_info *, slp_tree, vec<vec<tree> > *,
   2483 			       unsigned n = -1U);
   2484 extern bool vect_slp_if_converted_bb (basic_block bb, loop_p orig_loop);
   2485 extern bool vect_slp_function (function *);
   2486 extern stmt_vec_info vect_find_last_scalar_stmt_in_slp (slp_tree);
   2487 extern stmt_vec_info vect_find_first_scalar_stmt_in_slp (slp_tree);
   2488 extern bool is_simple_and_all_uses_invariant (stmt_vec_info, loop_vec_info);
   2489 extern bool can_duplicate_and_interleave_p (vec_info *, unsigned int, tree,
   2490 					    unsigned int * = NULL,
   2491 					    tree * = NULL, tree * = NULL);
   2492 extern void duplicate_and_interleave (vec_info *, gimple_seq *, tree,
   2493 				      const vec<tree> &, unsigned int, vec<tree> &);
   2494 extern int vect_get_place_in_interleaving_chain (stmt_vec_info, stmt_vec_info);
   2495 extern slp_tree vect_create_new_slp_node (unsigned, tree_code);
   2496 extern void vect_free_slp_tree (slp_tree);
   2497 extern bool compatible_calls_p (gcall *, gcall *);
   2498 extern int vect_slp_child_index_for_operand (const gimple *, int op, bool);
   2499 
   2500 extern tree prepare_vec_mask (loop_vec_info, tree, tree, tree,
   2501 			      gimple_stmt_iterator *);
   2502 
   2503 /* In tree-vect-patterns.cc.  */
   2504 extern void
   2505 vect_mark_pattern_stmts (vec_info *, stmt_vec_info, gimple *, tree);
   2506 extern bool vect_get_range_info (tree, wide_int*, wide_int*);
   2507 
   2508 /* Pattern recognition functions.
   2509    Additional pattern recognition functions can (and will) be added
   2510    in the future.  */
   2511 void vect_pattern_recog (vec_info *);
   2512 
   2513 /* In tree-vectorizer.cc.  */
   2514 unsigned vectorize_loops (void);
   2515 void vect_free_loop_info_assumptions (class loop *);
   2516 gimple *vect_loop_vectorized_call (class loop *, gcond **cond = NULL);
   2517 bool vect_stmt_dominates_stmt_p (gimple *, gimple *);
   2518 
   2519 /* SLP Pattern matcher types, tree-vect-slp-patterns.cc.  */
   2520 
   2521 /* Forward declaration of possible two operands operation that can be matched
   2522    by the complex numbers pattern matchers.  */
   2523 enum _complex_operation : unsigned;
   2524 
   2525 /* All possible load permute values that could result from the partial data-flow
   2526    analysis.  */
   2527 typedef enum _complex_perm_kinds {
   2528    PERM_UNKNOWN,
   2529    PERM_EVENODD,
   2530    PERM_ODDEVEN,
   2531    PERM_ODDODD,
   2532    PERM_EVENEVEN,
   2533    /* Can be combined with any other PERM values.  */
   2534    PERM_TOP
   2535 } complex_perm_kinds_t;
   2536 
   2537 /* Cache from nodes to the load permutation they represent.  */
   2538 typedef hash_map <slp_tree, complex_perm_kinds_t>
   2539   slp_tree_to_load_perm_map_t;
   2540 
   2541 /* Cache from nodes pair to being compatible or not.  */
   2542 typedef pair_hash <nofree_ptr_hash <_slp_tree>,
   2543 		   nofree_ptr_hash <_slp_tree>> slp_node_hash;
   2544 typedef hash_map <slp_node_hash, bool> slp_compat_nodes_map_t;
   2545 
   2546 
   2547 /* Vector pattern matcher base class.  All SLP pattern matchers must inherit
   2548    from this type.  */
   2549 
   2550 class vect_pattern
   2551 {
   2552   protected:
   2553     /* The number of arguments that the IFN requires.  */
   2554     unsigned m_num_args;
   2555 
   2556     /* The internal function that will be used when a pattern is created.  */
   2557     internal_fn m_ifn;
   2558 
   2559     /* The current node being inspected.  */
   2560     slp_tree *m_node;
   2561 
   2562     /* The list of operands to be the children for the node produced when the
   2563        internal function is created.  */
   2564     vec<slp_tree> m_ops;
   2565 
   2566     /* Default constructor where NODE is the root of the tree to inspect.  */
   2567     vect_pattern (slp_tree *node, vec<slp_tree> *m_ops, internal_fn ifn)
   2568     {
   2569       this->m_ifn = ifn;
   2570       this->m_node = node;
   2571       this->m_ops.create (0);
   2572       if (m_ops)
   2573 	this->m_ops.safe_splice (*m_ops);
   2574     }
   2575 
   2576   public:
   2577 
   2578     /* Create a new instance of the pattern matcher class of the given type.  */
   2579     static vect_pattern* recognize (slp_tree_to_load_perm_map_t *,
   2580 				    slp_compat_nodes_map_t *, slp_tree *);
   2581 
   2582     /* Build the pattern from the data collected so far.  */
   2583     virtual void build (vec_info *) = 0;
   2584 
   2585     /* Default destructor.  */
   2586     virtual ~vect_pattern ()
   2587     {
   2588 	this->m_ops.release ();
   2589     }
   2590 };
   2591 
   2592 /* Function pointer to create a new pattern matcher from a generic type.  */
   2593 typedef vect_pattern* (*vect_pattern_decl_t) (slp_tree_to_load_perm_map_t *,
   2594 					      slp_compat_nodes_map_t *,
   2595 					      slp_tree *);
   2596 
   2597 /* List of supported pattern matchers.  */
   2598 extern vect_pattern_decl_t slp_patterns[];
   2599 
   2600 /* Number of supported pattern matchers.  */
   2601 extern size_t num__slp_patterns;
   2602 
   2603 /* ----------------------------------------------------------------------
   2604    Target support routines
   2605    -----------------------------------------------------------------------
   2606    The following routines are provided to simplify costing decisions in
   2607    target code.  Please add more as needed.  */
   2608 
   2609 /* Return true if an operaton of kind KIND for STMT_INFO represents
   2610    the extraction of an element from a vector in preparation for
   2611    storing the element to memory.  */
   2612 inline bool
   2613 vect_is_store_elt_extraction (vect_cost_for_stmt kind, stmt_vec_info stmt_info)
   2614 {
   2615   return (kind == vec_to_scalar
   2616 	  && STMT_VINFO_DATA_REF (stmt_info)
   2617 	  && DR_IS_WRITE (STMT_VINFO_DATA_REF (stmt_info)));
   2618 }
   2619 
   2620 /* Return true if STMT_INFO represents part of a reduction.  */
   2621 inline bool
   2622 vect_is_reduction (stmt_vec_info stmt_info)
   2623 {
   2624   return STMT_VINFO_REDUC_IDX (stmt_info) >= 0;
   2625 }
   2626 
   2627 /* If STMT_INFO describes a reduction, return the vect_reduction_type
   2628    of the reduction it describes, otherwise return -1.  */
   2629 inline int
   2630 vect_reduc_type (vec_info *vinfo, stmt_vec_info stmt_info)
   2631 {
   2632   if (loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (vinfo))
   2633     if (STMT_VINFO_REDUC_DEF (stmt_info))
   2634       {
   2635 	stmt_vec_info reduc_info = info_for_reduction (loop_vinfo, stmt_info);
   2636 	return int (STMT_VINFO_REDUC_TYPE (reduc_info));
   2637       }
   2638   return -1;
   2639 }
   2640 
   2641 /* If STMT_INFO is a COND_EXPR that includes an embedded comparison, return the
   2642    scalar type of the values being compared.  Return null otherwise.  */
   2643 inline tree
   2644 vect_embedded_comparison_type (stmt_vec_info stmt_info)
   2645 {
   2646   if (auto *assign = dyn_cast<gassign *> (stmt_info->stmt))
   2647     if (gimple_assign_rhs_code (assign) == COND_EXPR)
   2648       {
   2649 	tree cond = gimple_assign_rhs1 (assign);
   2650 	if (COMPARISON_CLASS_P (cond))
   2651 	  return TREE_TYPE (TREE_OPERAND (cond, 0));
   2652       }
   2653   return NULL_TREE;
   2654 }
   2655 
   2656 /* If STMT_INFO is a comparison or contains an embedded comparison, return the
   2657    scalar type of the values being compared.  Return null otherwise.  */
   2658 inline tree
   2659 vect_comparison_type (stmt_vec_info stmt_info)
   2660 {
   2661   if (auto *assign = dyn_cast<gassign *> (stmt_info->stmt))
   2662     if (TREE_CODE_CLASS (gimple_assign_rhs_code (assign)) == tcc_comparison)
   2663       return TREE_TYPE (gimple_assign_rhs1 (assign));
   2664   return vect_embedded_comparison_type (stmt_info);
   2665 }
   2666 
   2667 /* Return true if STMT_INFO extends the result of a load.  */
   2668 inline bool
   2669 vect_is_extending_load (class vec_info *vinfo, stmt_vec_info stmt_info)
   2670 {
   2671   /* Although this is quite large for an inline function, this part
   2672      at least should be inline.  */
   2673   gassign *assign = dyn_cast <gassign *> (stmt_info->stmt);
   2674   if (!assign || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (assign)))
   2675     return false;
   2676 
   2677   tree rhs = gimple_assign_rhs1 (stmt_info->stmt);
   2678   tree lhs_type = TREE_TYPE (gimple_assign_lhs (assign));
   2679   tree rhs_type = TREE_TYPE (rhs);
   2680   if (!INTEGRAL_TYPE_P (lhs_type)
   2681       || !INTEGRAL_TYPE_P (rhs_type)
   2682       || TYPE_PRECISION (lhs_type) <= TYPE_PRECISION (rhs_type))
   2683     return false;
   2684 
   2685   stmt_vec_info def_stmt_info = vinfo->lookup_def (rhs);
   2686   return (def_stmt_info
   2687 	  && STMT_VINFO_DATA_REF (def_stmt_info)
   2688 	  && DR_IS_READ (STMT_VINFO_DATA_REF (def_stmt_info)));
   2689 }
   2690 
   2691 /* Return true if STMT_INFO is an integer truncation.  */
   2692 inline bool
   2693 vect_is_integer_truncation (stmt_vec_info stmt_info)
   2694 {
   2695   gassign *assign = dyn_cast <gassign *> (stmt_info->stmt);
   2696   if (!assign || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (assign)))
   2697     return false;
   2698 
   2699   tree lhs_type = TREE_TYPE (gimple_assign_lhs (assign));
   2700   tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (assign));
   2701   return (INTEGRAL_TYPE_P (lhs_type)
   2702 	  && INTEGRAL_TYPE_P (rhs_type)
   2703 	  && TYPE_PRECISION (lhs_type) < TYPE_PRECISION (rhs_type));
   2704 }
   2705 
   2706 /* Build a GIMPLE_ASSIGN or GIMPLE_CALL with the tree_code,
   2707    or internal_fn contained in ch, respectively.  */
   2708 gimple * vect_gimple_build (tree, code_helper, tree, tree = NULL_TREE);
   2709 #endif  /* GCC_TREE_VECTORIZER_H  */
   2710