LCOV - code coverage report
Current view: top level - gcc - gimple-ssa-strength-reduction.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.3 % 1657 1480
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 77 77
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Straight-line strength reduction.
       2              :    Copyright (C) 2012-2026 Free Software Foundation, Inc.
       3              :    Contributed by Bill Schmidt, IBM <wschmidt@linux.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              : /* There are many algorithms for performing strength reduction on
      22              :    loops.  This is not one of them.  IVOPTS handles strength reduction
      23              :    of induction variables just fine.  This pass is intended to pick
      24              :    up the crumbs it leaves behind, by considering opportunities for
      25              :    strength reduction along dominator paths.
      26              : 
      27              :    Strength reduction addresses explicit multiplies, and certain
      28              :    multiplies implicit in addressing expressions.  It would also be
      29              :    possible to apply strength reduction to divisions and modulos,
      30              :    but such opportunities are relatively uncommon.
      31              : 
      32              :    Strength reduction is also currently restricted to integer operations.
      33              :    If desired, it could be extended to floating-point operations under
      34              :    control of something like -funsafe-math-optimizations.  */
      35              : 
      36              : #include "config.h"
      37              : #include "system.h"
      38              : #include "coretypes.h"
      39              : #include "backend.h"
      40              : #include "rtl.h"
      41              : #include "tree.h"
      42              : #include "gimple.h"
      43              : #include "cfghooks.h"
      44              : #include "tree-pass.h"
      45              : #include "ssa.h"
      46              : #include "expmed.h"
      47              : #include "gimple-pretty-print.h"
      48              : #include "fold-const.h"
      49              : #include "gimple-iterator.h"
      50              : #include "gimplify-me.h"
      51              : #include "stor-layout.h"
      52              : #include "cfgloop.h"
      53              : #include "tree-cfg.h"
      54              : #include "domwalk.h"
      55              : #include "tree-ssa-address.h"
      56              : #include "tree-affine.h"
      57              : #include "tree-eh.h"
      58              : #include "builtins.h"
      59              : #include "tree-ssa-dce.h"
      60              : #include "gimple-fold.h"
      61              : 
      62              : /* Information about a strength reduction candidate.  Each statement
      63              :    in the candidate table represents an expression of one of the
      64              :    following forms (the special case of CAND_REF will be described
      65              :    later):
      66              : 
      67              :    (CAND_MULT)  S1:  X = (B + i) * S
      68              :    (CAND_ADD)   S1:  X = B + (i * S)
      69              : 
      70              :    Here X and B are SSA names, i is an integer constant, and S is
      71              :    either an SSA name or a constant.  We call B the "base," i the
      72              :    "index", and S the "stride."
      73              : 
      74              :    Any statement S0 that dominates S1 and is of the form:
      75              : 
      76              :    (CAND_MULT)  S0:  Y = (B + i') * S
      77              :    (CAND_ADD)   S0:  Y = B + (i' * S)
      78              : 
      79              :    is called a "basis" for S1.  In both cases, S1 may be replaced by
      80              : 
      81              :                 S1':  X = Y + (i - i') * S,
      82              : 
      83              :    where (i - i') * S is folded to the extent possible.
      84              : 
      85              :    All gimple statements are visited in dominator order, and each
      86              :    statement that may contribute to one of the forms of S1 above is
      87              :    given at least one entry in the candidate table.  Such statements
      88              :    include addition, pointer addition, subtraction, multiplication,
      89              :    negation, copies, and nontrivial type casts.  If a statement may
      90              :    represent more than one expression of the forms of S1 above,
      91              :    multiple "interpretations" are stored in the table and chained
      92              :    together.  Examples:
      93              : 
      94              :    * An add of two SSA names may treat either operand as the base.
      95              :    * A multiply of two SSA names, likewise.
      96              :    * A copy or cast may be thought of as either a CAND_MULT with
      97              :      i = 0 and S = 1, or as a CAND_ADD with i = 0 or S = 0.
      98              : 
      99              :    Candidate records are allocated from an obstack.  They are addressed
     100              :    both from a hash table keyed on S1, and from a vector of candidate
     101              :    pointers arranged in predominator order.
     102              : 
     103              :    Opportunity note
     104              :    ----------------
     105              :    Currently we don't recognize:
     106              : 
     107              :      S0: Y = (S * i') - B
     108              :      S1: X = (S * i) - B
     109              : 
     110              :    as a strength reduction opportunity, even though this S1 would
     111              :    also be replaceable by the S1' above.  This can be added if it
     112              :    comes up in practice.
     113              : 
     114              :    Strength reduction in addressing
     115              :    --------------------------------
     116              :    There is another kind of candidate known as CAND_REF.  A CAND_REF
     117              :    describes a statement containing a memory reference having
     118              :    complex addressing that might benefit from strength reduction.
     119              :    Specifically, we are interested in references for which
     120              :    get_inner_reference returns a base address, offset, and bitpos as
     121              :    follows:
     122              : 
     123              :      base:    MEM_REF (T1, C1)
     124              :      offset:  MULT_EXPR (PLUS_EXPR (T2, C2), C3)
     125              :      bitpos:  C4 * BITS_PER_UNIT
     126              : 
     127              :    Here T1 and T2 are arbitrary trees, and C1, C2, C3, C4 are
     128              :    arbitrary integer constants.  Note that C2 may be zero, in which
     129              :    case the offset will be MULT_EXPR (T2, C3).
     130              : 
     131              :    When this pattern is recognized, the original memory reference
     132              :    can be replaced with:
     133              : 
     134              :      MEM_REF (POINTER_PLUS_EXPR (T1, MULT_EXPR (T2, C3)),
     135              :               C1 + (C2 * C3) + C4)
     136              : 
     137              :    which distributes the multiply to allow constant folding.  When
     138              :    two or more addressing expressions can be represented by MEM_REFs
     139              :    of this form, differing only in the constants C1, C2, and C4,
     140              :    making this substitution produces more efficient addressing during
     141              :    the RTL phases.  When there are not at least two expressions with
     142              :    the same values of T1, T2, and C3, there is nothing to be gained
     143              :    by the replacement.
     144              : 
     145              :    Strength reduction of CAND_REFs uses the same infrastructure as
     146              :    that used by CAND_MULTs and CAND_ADDs.  We record T1 in the base (B)
     147              :    field, MULT_EXPR (T2, C3) in the stride (S) field, and
     148              :    C1 + (C2 * C3) + C4 in the index (i) field.  A basis for a CAND_REF
     149              :    is thus another CAND_REF with the same B and S values.  When at
     150              :    least two CAND_REFs are chained together using the basis relation,
     151              :    each of them is replaced as above, resulting in improved code
     152              :    generation for addressing.
     153              : 
     154              :    Conditional candidates
     155              :    ======================
     156              : 
     157              :    Conditional candidates are best illustrated with an example.
     158              :    Consider the code sequence:
     159              : 
     160              :    (1)  x_0 = ...;
     161              :    (2)  a_0 = x_0 * 5;          MULT (B: x_0; i: 0; S: 5)
     162              :         if (...)
     163              :    (3)    x_1 = x_0 + 1;        ADD  (B: x_0, i: 1; S: 1)
     164              :    (4)  x_2 = PHI <x_0, x_1>;   PHI  (B: x_0, i: 0, S: 1)
     165              :    (5)  x_3 = x_2 + 1;          ADD  (B: x_2, i: 1, S: 1)
     166              :    (6)  a_1 = x_3 * 5;          MULT (B: x_2, i: 1; S: 5)
     167              : 
     168              :    Here strength reduction is complicated by the uncertain value of x_2.
     169              :    A legitimate transformation is:
     170              : 
     171              :    (1)  x_0 = ...;
     172              :    (2)  a_0 = x_0 * 5;
     173              :         if (...)
     174              :           {
     175              :    (3)      [x_1 = x_0 + 1;]
     176              :    (3a)     t_1 = a_0 + 5;
     177              :           }
     178              :    (4)  [x_2 = PHI <x_0, x_1>;]
     179              :    (4a) t_2 = PHI <a_0, t_1>;
     180              :    (5)  [x_3 = x_2 + 1;]
     181              :    (6r) a_1 = t_2 + 5;
     182              : 
     183              :    where the bracketed instructions may go dead.
     184              : 
     185              :    To recognize this opportunity, we have to observe that statement (6)
     186              :    has a "hidden basis" (2).  The hidden basis is unlike a normal basis
     187              :    in that the statement and the hidden basis have different base SSA
     188              :    names (x_2 and x_0, respectively).  The relationship is established
     189              :    when a statement's base name (x_2) is defined by a phi statement (4),
     190              :    each argument of which (x_0, x_1) has an identical "derived base name."
     191              :    If the argument is defined by a candidate (as x_1 is by (3)) that is a
     192              :    CAND_ADD having a stride of 1, the derived base name of the argument is
     193              :    the base name of the candidate (x_0).  Otherwise, the argument itself
     194              :    is its derived base name (as is the case with argument x_0).
     195              : 
     196              :    The hidden basis for statement (6) is the nearest dominating candidate
     197              :    whose base name is the derived base name (x_0) of the feeding phi (4),
     198              :    and whose stride is identical to that of the statement.  We can then
     199              :    create the new "phi basis" (4a) and feeding adds along incoming arcs (3a),
     200              :    allowing the final replacement of (6) by the strength-reduced (6r).
     201              : 
     202              :    To facilitate this, a new kind of candidate (CAND_PHI) is introduced.
     203              :    A CAND_PHI is not a candidate for replacement, but is maintained in the
     204              :    candidate table to ease discovery of hidden bases.  Any phi statement
     205              :    whose arguments share a common derived base name is entered into the
     206              :    table with the derived base name, an (arbitrary) index of zero, and a
     207              :    stride of 1.  A statement with a hidden basis can then be detected by
     208              :    simply looking up its feeding phi definition in the candidate table,
     209              :    extracting the derived base name, and searching for a basis in the
     210              :    usual manner after substituting the derived base name.
     211              : 
     212              :    Note that the transformation is only valid when the original phi and
     213              :    the statements that define the phi's arguments are all at the same
     214              :    position in the loop hierarchy.  */
     215              : 
     216              : 
     217              : /* Index into the candidate vector, offset by 1.  VECs are zero-based,
     218              :    while cand_idx's are one-based, with zero indicating null.  */
     219              : typedef unsigned cand_idx;
     220              : 
     221              : /* The kind of candidate.  */
     222              : enum cand_kind
     223              : {
     224              :   CAND_MULT,
     225              :   CAND_ADD,
     226              :   CAND_REF,
     227              :   CAND_PHI
     228              : };
     229              : 
     230              : class slsr_cand_d
     231              : {
     232              : public:
     233              :   /* The candidate statement S1.  */
     234              :   gimple *cand_stmt;
     235              : 
     236              :   /* The base expression B:  often an SSA name, but not always.  */
     237              :   tree base_expr;
     238              : 
     239              :   /* The stride S.  */
     240              :   tree stride;
     241              : 
     242              :   /* The index constant i.  */
     243              :   offset_int index;
     244              : 
     245              :   /* The type of the candidate.  This is normally the type of base_expr,
     246              :      but casts may have occurred when combining feeding instructions.
     247              :      A candidate can only be a basis for candidates of the same final type.
     248              :      (For CAND_REFs, this is the type to be used for operand 1 of the
     249              :      replacement MEM_REF.)  */
     250              :   tree cand_type;
     251              : 
     252              :   /* The type to be used to interpret the stride field when the stride
     253              :      is not a constant.  Normally the same as the type of the recorded
     254              :      stride, but when the stride has been cast we need to maintain that
     255              :      knowledge in order to make legal substitutions without losing
     256              :      precision.  When the stride is a constant, this will be sizetype.  */
     257              :   tree stride_type;
     258              : 
     259              :   /* The kind of candidate (CAND_MULT, etc.).  */
     260              :   enum cand_kind kind;
     261              : 
     262              :   /* Index of this candidate in the candidate vector.  */
     263              :   cand_idx cand_num;
     264              : 
     265              :   /* Index of the next candidate record for the same statement.
     266              :      A statement may be useful in more than one way (e.g., due to
     267              :      commutativity).  So we can have multiple "interpretations"
     268              :      of a statement.  */
     269              :   cand_idx next_interp;
     270              : 
     271              :   /* Index of the first candidate record in a chain for the same
     272              :      statement.  */
     273              :   cand_idx first_interp;
     274              : 
     275              :   /* Index of the basis statement S0, if any, in the candidate vector.  */
     276              :   cand_idx basis;
     277              : 
     278              :   /* First candidate for which this candidate is a basis, if one exists.  */
     279              :   cand_idx dependent;
     280              : 
     281              :   /* Next candidate having the same basis as this one.  */
     282              :   cand_idx sibling;
     283              : 
     284              :   /* If this is a conditional candidate, the CAND_PHI candidate
     285              :      that defines the base SSA name B.  */
     286              :   cand_idx def_phi;
     287              : 
     288              :   /* Savings that can be expected from eliminating dead code if this
     289              :      candidate is replaced.  */
     290              :   int dead_savings;
     291              : 
     292              :   /* For PHI candidates, use a visited flag to keep from processing the
     293              :      same PHI twice from multiple paths.  */
     294              :   int visited;
     295              : 
     296              :   /* We sometimes have to cache a phi basis with a phi candidate to
     297              :      avoid processing it twice.  Valid only if visited==1.  */
     298              :   tree cached_basis;
     299              : };
     300              : 
     301              : typedef class slsr_cand_d slsr_cand, *slsr_cand_t;
     302              : typedef const class slsr_cand_d *const_slsr_cand_t;
     303              : 
     304              : /* Pointers to candidates are chained together as part of a mapping
     305              :    from base expressions to the candidates that use them.  */
     306              : 
     307              : struct cand_chain_d
     308              : {
     309              :   /* Base expression for the chain of candidates:  often, but not
     310              :      always, an SSA name.  */
     311              :   tree base_expr;
     312              : 
     313              :   /* Pointer to a candidate.  */
     314              :   slsr_cand_t cand;
     315              : 
     316              :   /* Chain pointer.  */
     317              :   struct cand_chain_d *next;
     318              : 
     319              : };
     320              : 
     321              : typedef struct cand_chain_d cand_chain, *cand_chain_t;
     322              : typedef const struct cand_chain_d *const_cand_chain_t;
     323              : 
     324              : /* Information about a unique "increment" associated with candidates
     325              :    having an SSA name for a stride.  An increment is the difference
     326              :    between the index of the candidate and the index of its basis,
     327              :    i.e., (i - i') as discussed in the module commentary.
     328              : 
     329              :    When we are not going to generate address arithmetic we treat
     330              :    increments that differ only in sign as the same, allowing sharing
     331              :    of the cost of initializers.  The absolute value of the increment
     332              :    is stored in the incr_info.  */
     333              : 
     334              : class incr_info_d
     335              : {
     336              : public:
     337              :   /* The increment that relates a candidate to its basis.  */
     338              :   offset_int incr;
     339              : 
     340              :   /* How many times the increment occurs in the candidate tree.  */
     341              :   unsigned count;
     342              : 
     343              :   /* Cost of replacing candidates using this increment.  Negative and
     344              :      zero costs indicate replacement should be performed.  */
     345              :   int cost;
     346              : 
     347              :   /* If this increment is profitable but is not -1, 0, or 1, it requires
     348              :      an initializer T_0 = stride * incr to be found or introduced in the
     349              :      nearest common dominator of all candidates.  This field holds T_0
     350              :      for subsequent use.  */
     351              :   tree initializer;
     352              : 
     353              :   /* If the initializer was found to already exist, this is the block
     354              :      where it was found.  */
     355              :   basic_block init_bb;
     356              : };
     357              : 
     358              : typedef class incr_info_d incr_info, *incr_info_t;
     359              : 
     360              : /* Candidates are maintained in a vector.  If candidate X dominates
     361              :    candidate Y, then X appears before Y in the vector; but the
     362              :    converse does not necessarily hold.  */
     363              : static vec<slsr_cand_t> cand_vec;
     364              : 
     365              : enum cost_consts
     366              : {
     367              :   COST_NEUTRAL = 0,
     368              :   COST_INFINITE = 1000
     369              : };
     370              : 
     371              : enum stride_status
     372              : {
     373              :   UNKNOWN_STRIDE = 0,
     374              :   KNOWN_STRIDE = 1
     375              : };
     376              : 
     377              : enum phi_adjust_status
     378              : {
     379              :   NOT_PHI_ADJUST = 0,
     380              :   PHI_ADJUST = 1
     381              : };
     382              : 
     383              : enum count_phis_status
     384              : {
     385              :   DONT_COUNT_PHIS = 0,
     386              :   COUNT_PHIS = 1
     387              : };
     388              : 
     389              : /* Constrain how many PHI nodes we will visit for a conditional
     390              :    candidate (depth and breadth).  */
     391              : const int MAX_SPREAD = 16;
     392              : 
     393              : /* Pointer map embodying a mapping from statements to candidates.  */
     394              : static hash_map<gimple *, slsr_cand_t> *stmt_cand_map;
     395              : 
     396              : /* Obstack for candidates.  */
     397              : static struct obstack cand_obstack;
     398              : 
     399              : /* Obstack for candidate chains.  */
     400              : static struct obstack chain_obstack;
     401              : 
     402              : /* An array INCR_VEC of incr_infos is used during analysis of related
     403              :    candidates having an SSA name for a stride.  INCR_VEC_LEN describes
     404              :    its current length.  MAX_INCR_VEC_LEN is used to avoid costly
     405              :    pathological cases. */
     406              : static incr_info_t incr_vec;
     407              : static unsigned incr_vec_len;
     408              : const int MAX_INCR_VEC_LEN = 16;
     409              : 
     410              : /* For a chain of candidates with unknown stride, indicates whether or not
     411              :    we must generate pointer arithmetic when replacing statements.  */
     412              : static bool address_arithmetic_p;
     413              : 
     414              : /* Forward function declarations.  */
     415              : static slsr_cand_t base_cand_from_table (tree);
     416              : static tree introduce_cast_before_cand (slsr_cand_t, tree, tree);
     417              : static bool legal_cast_p_1 (tree, tree);
     418              : 
     419              : /* Produce a pointer to the IDX'th candidate in the candidate vector.  */
     420              : 
     421              : static slsr_cand_t
     422      8074878 : lookup_cand (cand_idx idx)
     423              : {
     424            0 :   return cand_vec[idx];
     425              : }
     426              : 
     427              : /* Helper for hashing a candidate chain header.  */
     428              : 
     429              : struct cand_chain_hasher : nofree_ptr_hash <cand_chain>
     430              : {
     431              :   static inline hashval_t hash (const cand_chain *);
     432              :   static inline bool equal (const cand_chain *, const cand_chain *);
     433              : };
     434              : 
     435              : inline hashval_t
     436     32076131 : cand_chain_hasher::hash (const cand_chain *p)
     437              : {
     438     32076131 :   tree base_expr = p->base_expr;
     439     32076131 :   return iterative_hash_expr (base_expr, 0);
     440              : }
     441              : 
     442              : inline bool
     443     25779963 : cand_chain_hasher::equal (const cand_chain *chain1, const cand_chain *chain2)
     444              : {
     445     25779963 :   return operand_equal_p (chain1->base_expr, chain2->base_expr, 0);
     446              : }
     447              : 
     448              : /* Hash table embodying a mapping from base exprs to chains of candidates.  */
     449              : static hash_table<cand_chain_hasher> *base_cand_map;
     450              : 
     451              : /* Pointer map used by tree_to_aff_combination_expand.  */
     452              : static hash_map<tree, name_expansion *> *name_expansions;
     453              : /* Pointer map embodying a mapping from bases to alternative bases.  */
     454              : static hash_map<tree, tree> *alt_base_map;
     455              : 
     456              : /* Given BASE, use the tree affine combiniation facilities to
     457              :    find the underlying tree expression for BASE, with any
     458              :    immediate offset excluded.
     459              : 
     460              :    N.B. we should eliminate this backtracking with better forward
     461              :    analysis in a future release.  */
     462              : 
     463              : static tree
     464        60856 : get_alternative_base (tree base)
     465              : {
     466        60856 :   tree *result = alt_base_map->get (base);
     467              : 
     468        60856 :   if (result == NULL)
     469              :     {
     470        10229 :       tree expr;
     471        10229 :       aff_tree aff;
     472              : 
     473        10229 :       tree_to_aff_combination_expand (base, TREE_TYPE (base),
     474              :                                       &aff, &name_expansions);
     475        10229 :       aff.offset = 0;
     476        10229 :       expr = aff_combination_to_tree (&aff);
     477              : 
     478        20322 :       bool existed = alt_base_map->put (base, base == expr ? NULL : expr);
     479        10229 :       gcc_assert (!existed);
     480              : 
     481        10229 :       return expr == base ? NULL : expr;
     482        10229 :     }
     483              : 
     484        50627 :   return *result;
     485              : }
     486              : 
     487              : /* Look in the candidate table for a CAND_PHI that defines BASE and
     488              :    return it if found; otherwise return NULL.  */
     489              : 
     490              : static cand_idx
     491      2456850 : find_phi_def (tree base)
     492              : {
     493      2456850 :   slsr_cand_t c;
     494              : 
     495      2456850 :   if (TREE_CODE (base) != SSA_NAME)
     496              :     return 0;
     497              : 
     498      2456850 :   c = base_cand_from_table (base);
     499              : 
     500       173401 :   if (!c || c->kind != CAND_PHI
     501      2457743 :       || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (c->cand_stmt)))
     502              :     return 0;
     503              : 
     504          888 :   return c->cand_num;
     505              : }
     506              : 
     507              : /* Determine whether all uses of NAME are directly or indirectly
     508              :    used by STMT.  That is, we want to know whether if STMT goes
     509              :    dead, the definition of NAME also goes dead.  */
     510              : static bool
     511       203705 : uses_consumed_by_stmt (tree name, gimple *stmt, unsigned recurse = 0)
     512              : {
     513       203705 :   gimple *use_stmt;
     514       203705 :   imm_use_iterator iter;
     515       203705 :   bool retval = true;
     516              : 
     517       594681 :   FOR_EACH_IMM_USE_STMT (use_stmt, iter, name)
     518              :     {
     519       294697 :       if (use_stmt == stmt || is_gimple_debug (use_stmt))
     520       184363 :         continue;
     521              : 
     522       110334 :       if (!is_gimple_assign (use_stmt)
     523        38750 :           || !gimple_get_lhs (use_stmt)
     524        38750 :           || !is_gimple_reg (gimple_get_lhs (use_stmt))
     525        32961 :           || recurse >= 10
     526       143255 :           || !uses_consumed_by_stmt (gimple_get_lhs (use_stmt), stmt,
     527              :                                      recurse + 1))
     528              :         {
     529              :           retval = false;
     530              :           break;
     531              :         }
     532       203705 :     }
     533              : 
     534       203705 :   return retval;
     535              : }
     536              : 
     537              : /* Helper routine for find_basis_for_candidate.  May be called twice:
     538              :    once for the candidate's base expr, and optionally again either for
     539              :    the candidate's phi definition or for a CAND_REF's alternative base
     540              :    expression.  */
     541              : 
     542              : static slsr_cand_t
     543      7951100 : find_basis_for_base_expr (slsr_cand_t c, tree base_expr)
     544              : {
     545      7951100 :   cand_chain mapping_key;
     546      7951100 :   cand_chain_t chain;
     547      7951100 :   slsr_cand_t basis = NULL;
     548              : 
     549              :   // Limit potential of N^2 behavior for long candidate chains.
     550      7951100 :   int iters = 0;
     551      7951100 :   int max_iters = param_max_slsr_candidate_scan;
     552              : 
     553      7951100 :   mapping_key.base_expr = base_expr;
     554      7951100 :   chain = base_cand_map->find (&mapping_key);
     555              : 
     556     31836321 :   for (; chain && iters < max_iters; chain = chain->next, ++iters)
     557              :     {
     558     23885221 :       slsr_cand_t one_basis = chain->cand;
     559              : 
     560     42991157 :       if (one_basis->kind != c->kind
     561     14150242 :           || one_basis->cand_stmt == c->cand_stmt
     562     14149532 :           || !operand_equal_p (one_basis->stride, c->stride, 0)
     563      7915245 :           || !types_compatible_p (one_basis->cand_type, c->cand_type)
     564      6651018 :           || !types_compatible_p (one_basis->stride_type, c->stride_type)
     565     30536227 :           || !dominated_by_p (CDI_DOMINATORS,
     566      6651006 :                               gimple_bb (c->cand_stmt),
     567      6651006 :                               gimple_bb (one_basis->cand_stmt)))
     568     19105936 :         continue;
     569              : 
     570      4779285 :       tree lhs = gimple_assign_lhs (one_basis->cand_stmt);
     571      4779285 :       if (lhs && TREE_CODE (lhs) == SSA_NAME
     572      9538741 :           && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
     573           34 :         continue;
     574              : 
     575      4779251 :       if (!basis || basis->cand_num < one_basis->cand_num)
     576     23885221 :         basis = one_basis;
     577              :     }
     578              : 
     579      7951100 :   return basis;
     580              : }
     581              : 
     582              : /* Use the base expr from candidate C to look for possible candidates
     583              :    that can serve as a basis for C.  Each potential basis must also
     584              :    appear in a block that dominates the candidate statement and have
     585              :    the same stride and type.  If more than one possible basis exists,
     586              :    the one with highest index in the vector is chosen; this will be
     587              :    the most immediately dominating basis.  */
     588              : 
     589              : static int
     590      7950167 : find_basis_for_candidate (slsr_cand_t c)
     591              : {
     592      7950167 :   slsr_cand_t basis = find_basis_for_base_expr (c, c->base_expr);
     593              : 
     594              :   /* If a candidate doesn't have a basis using its base expression,
     595              :      it may have a basis hidden by one or more intervening phis.  */
     596      7950167 :   if (!basis && c->def_phi)
     597              :     {
     598          769 :       basic_block basis_bb, phi_bb;
     599          769 :       slsr_cand_t phi_cand = lookup_cand (c->def_phi);
     600          769 :       basis = find_basis_for_base_expr (c, phi_cand->base_expr);
     601              : 
     602          769 :       if (basis)
     603              :         {
     604              :           /* A hidden basis must dominate the phi-definition of the
     605              :              candidate's base name.  */
     606           71 :           phi_bb = gimple_bb (phi_cand->cand_stmt);
     607           71 :           basis_bb = gimple_bb (basis->cand_stmt);
     608              : 
     609           71 :           if (phi_bb == basis_bb
     610           71 :               || !dominated_by_p (CDI_DOMINATORS, phi_bb, basis_bb))
     611              :             {
     612            8 :               basis = NULL;
     613            8 :               c->basis = 0;
     614              :             }
     615              : 
     616              :           /* If we found a hidden basis, estimate additional dead-code
     617              :              savings if the phi and its feeding statements can be removed.  */
     618           71 :           tree feeding_var = gimple_phi_result (phi_cand->cand_stmt);
     619           71 :           if (basis && uses_consumed_by_stmt (feeding_var, c->cand_stmt))
     620           26 :             c->dead_savings += phi_cand->dead_savings;
     621              :         }
     622              :     }
     623              : 
     624      7950167 :   if (flag_expensive_optimizations && !basis && c->kind == CAND_REF)
     625              :     {
     626        23304 :       tree alt_base_expr = get_alternative_base (c->base_expr);
     627        23304 :       if (alt_base_expr)
     628          164 :         basis = find_basis_for_base_expr (c, alt_base_expr);
     629              :     }
     630              : 
     631      6791842 :   if (basis)
     632              :     {
     633      1282959 :       c->sibling = basis->dependent;
     634      1282959 :       basis->dependent = c->cand_num;
     635      1282959 :       return basis->cand_num;
     636              :     }
     637              : 
     638              :   return 0;
     639              : }
     640              : 
     641              : /* Record a mapping from BASE to C, indicating that C may potentially serve
     642              :    as a basis using that base expression.  BASE may be the same as
     643              :    C->BASE_EXPR; alternatively BASE can be a different tree that share the
     644              :    underlining expression of C->BASE_EXPR.  */
     645              : 
     646              : static void
     647      7962045 : record_potential_basis (slsr_cand_t c, tree base)
     648              : {
     649      7962045 :   cand_chain_t node;
     650      7962045 :   cand_chain **slot;
     651              : 
     652      7962045 :   gcc_assert (base);
     653              : 
     654      7962045 :   node = (cand_chain_t) obstack_alloc (&chain_obstack, sizeof (cand_chain));
     655      7962045 :   node->base_expr = base;
     656      7962045 :   node->cand = c;
     657      7962045 :   node->next = NULL;
     658      7962045 :   slot = base_cand_map->find_slot (node, INSERT);
     659              : 
     660      7962045 :   if (*slot)
     661              :     {
     662      3881488 :       cand_chain_t head = (cand_chain_t) (*slot);
     663      3881488 :       node->next = head->next;
     664      3881488 :       head->next = node;
     665              :     }
     666              :   else
     667      4080557 :     *slot = node;
     668      7962045 : }
     669              : 
     670              : /* Allocate storage for a new candidate and initialize its fields.
     671              :    Attempt to find a basis for the candidate.
     672              : 
     673              :    For CAND_REF, an alternative base may also be recorded and used
     674              :    to find a basis.  This helps cases where the expression hidden
     675              :    behind BASE (which is usually an SSA_NAME) has immediate offset,
     676              :    e.g.
     677              : 
     678              :      a2[i][j] = 1;
     679              :      a2[i + 20][j] = 2;  */
     680              : 
     681              : static slsr_cand_t
     682      7961821 : alloc_cand_and_find_basis (enum cand_kind kind, gimple *gs, tree base,
     683              :                            const offset_int &index, tree stride, tree ctype,
     684              :                            tree stype, unsigned savings)
     685              : {
     686      7961821 :   slsr_cand_t c = (slsr_cand_t) obstack_alloc (&cand_obstack,
     687              :                                                sizeof (slsr_cand));
     688      7961821 :   c->cand_stmt = gs;
     689      7961821 :   c->base_expr = base;
     690      7961821 :   c->stride = stride;
     691      7961821 :   c->index = index;
     692      7961821 :   c->cand_type = ctype;
     693      7961821 :   c->stride_type = stype;
     694      7961821 :   c->kind = kind;
     695      7961821 :   c->cand_num = cand_vec.length ();
     696      7961821 :   c->next_interp = 0;
     697      7961821 :   c->first_interp = c->cand_num;
     698      7961821 :   c->dependent = 0;
     699      7961821 :   c->sibling = 0;
     700      7961821 :   c->def_phi = kind == CAND_MULT ? find_phi_def (base) : 0;
     701      7961821 :   c->dead_savings = savings;
     702      7961821 :   c->visited = 0;
     703      7961821 :   c->cached_basis = NULL_TREE;
     704              : 
     705      7961821 :   cand_vec.safe_push (c);
     706              : 
     707      7961821 :   if (kind == CAND_PHI)
     708        11654 :     c->basis = 0;
     709              :   else
     710      7950167 :     c->basis = find_basis_for_candidate (c);
     711              : 
     712      7961821 :   record_potential_basis (c, base);
     713      7961821 :   if (flag_expensive_optimizations && kind == CAND_REF)
     714              :     {
     715        37552 :       tree alt_base = get_alternative_base (base);
     716        37552 :       if (alt_base)
     717          224 :         record_potential_basis (c, alt_base);
     718              :     }
     719              : 
     720      7961821 :   return c;
     721              : }
     722              : 
     723              : /* Determine the target cost of statement GS when compiling according
     724              :    to SPEED.  */
     725              : 
     726              : static int
     727      1350724 : stmt_cost (gimple *gs, bool speed)
     728              : {
     729      1350724 :   tree lhs, rhs1, rhs2;
     730      1350724 :   machine_mode lhs_mode;
     731              : 
     732      1350724 :   gcc_assert (is_gimple_assign (gs));
     733      1350724 :   lhs = gimple_assign_lhs (gs);
     734      1350724 :   rhs1 = gimple_assign_rhs1 (gs);
     735      1350724 :   lhs_mode = TYPE_MODE (TREE_TYPE (lhs));
     736              : 
     737      1350724 :   switch (gimple_assign_rhs_code (gs))
     738              :     {
     739       388028 :     case MULT_EXPR:
     740       388028 :       rhs2 = gimple_assign_rhs2 (gs);
     741              : 
     742       388028 :       if (tree_fits_shwi_p (rhs2))
     743       318595 :         return mult_by_coeff_cost (tree_to_shwi (rhs2), lhs_mode, speed);
     744              : 
     745        69433 :       gcc_assert (TREE_CODE (rhs1) != INTEGER_CST);
     746        69433 :       return mul_cost (speed, lhs_mode);
     747              : 
     748       240991 :     case PLUS_EXPR:
     749       240991 :     case POINTER_PLUS_EXPR:
     750       240991 :     case MINUS_EXPR:
     751       240991 :       return add_cost (speed, lhs_mode);
     752              : 
     753        10657 :     case NEGATE_EXPR:
     754        10657 :       return neg_cost (speed, lhs_mode);
     755              : 
     756       676449 :     CASE_CONVERT:
     757      1352898 :       return convert_cost (lhs_mode, TYPE_MODE (TREE_TYPE (rhs1)), speed);
     758              : 
     759              :     /* Note that we don't assign costs to copies that in most cases
     760              :        will go away.  */
     761              :     case SSA_NAME:
     762              :       return 0;
     763              : 
     764            0 :     default:
     765            0 :       ;
     766              :     }
     767              : 
     768            0 :   gcc_unreachable ();
     769              : }
     770              : 
     771              : /* Look up the defining statement for BASE_IN and return a pointer
     772              :    to its candidate in the candidate table, if any; otherwise NULL.
     773              :    Only CAND_ADD and CAND_MULT candidates are returned.  */
     774              : 
     775              : static slsr_cand_t
     776     15249721 : base_cand_from_table (tree base_in)
     777              : {
     778     15249721 :   slsr_cand_t *result;
     779              : 
     780     15249721 :   gimple *def = SSA_NAME_DEF_STMT (base_in);
     781     15249721 :   if (!def)
     782              :     return (slsr_cand_t) NULL;
     783              : 
     784     15249721 :   result = stmt_cand_map->get (def);
     785              : 
     786     15249721 :   if (result && (*result)->kind != CAND_REF)
     787              :     return *result;
     788              : 
     789              :   return (slsr_cand_t) NULL;
     790              : }
     791              : 
     792              : /* Add an entry to the statement-to-candidate mapping.  */
     793              : 
     794              : static void
     795      5764641 : add_cand_for_stmt (gimple *gs, slsr_cand_t c)
     796              : {
     797      5764641 :   bool existed = stmt_cand_map->put (gs, c);
     798      5764641 :   gcc_assert (!existed);
     799      5764641 : }
     800              : 
     801              : /* Given PHI which contains a phi statement, determine whether it
     802              :    satisfies all the requirements of a phi candidate.  If so, create
     803              :    a candidate.  Note that a CAND_PHI never has a basis itself, but
     804              :    is used to help find a basis for subsequent candidates.  */
     805              : 
     806              : static void
     807      4435189 : slsr_process_phi (gphi *phi, bool speed)
     808              : {
     809      4435189 :   unsigned i;
     810      4435189 :   tree arg0_base = NULL_TREE, base_type;
     811      4435189 :   slsr_cand_t c;
     812      4435189 :   class loop *cand_loop = gimple_bb (phi)->loop_father;
     813      4435189 :   unsigned savings = 0;
     814              : 
     815              :   /* A CAND_PHI requires each of its arguments to have the same
     816              :      derived base name.  (See the module header commentary for a
     817              :      definition of derived base names.)  Furthermore, all feeding
     818              :      definitions must be in the same position in the loop hierarchy
     819              :      as PHI.  */
     820              : 
     821      4700690 :   for (i = 0; i < gimple_phi_num_args (phi); i++)
     822              :     {
     823      4689036 :       slsr_cand_t arg_cand;
     824      4689036 :       tree arg = gimple_phi_arg_def (phi, i);
     825      4689036 :       tree derived_base_name = NULL_TREE;
     826      4689036 :       gimple *arg_stmt = NULL;
     827      4689036 :       basic_block arg_bb = NULL;
     828              : 
     829      4689036 :       if (TREE_CODE (arg) != SSA_NAME)
     830              :         return;
     831              : 
     832      4267527 :       arg_cand = base_cand_from_table (arg);
     833              : 
     834      4267527 :       if (arg_cand)
     835              :         {
     836       317419 :           while (arg_cand->kind != CAND_ADD && arg_cand->kind != CAND_PHI)
     837              :             {
     838        30557 :               if (!arg_cand->next_interp)
     839              :                 return;
     840              : 
     841         4019 :               arg_cand = lookup_cand (arg_cand->next_interp);
     842              :             }
     843              : 
     844       286862 :           if (!integer_onep (arg_cand->stride))
     845              :             return;
     846              : 
     847       170692 :           derived_base_name = arg_cand->base_expr;
     848       170692 :           arg_stmt = arg_cand->cand_stmt;
     849       170692 :           arg_bb = gimple_bb (arg_stmt);
     850              : 
     851              :           /* Gather potential dead code savings if the phi statement
     852              :              can be removed later on.  */
     853       170692 :           if (uses_consumed_by_stmt (arg, phi))
     854              :             {
     855        93322 :               if (gimple_code (arg_stmt) == GIMPLE_PHI)
     856         2442 :                 savings += arg_cand->dead_savings;
     857              :               else
     858        90880 :                 savings += stmt_cost (arg_stmt, speed);
     859              :             }
     860              :         }
     861      3954127 :       else if (SSA_NAME_IS_DEFAULT_DEF (arg))
     862              :         {
     863       184496 :           derived_base_name = arg;
     864       184496 :           arg_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
     865              :         }
     866              : 
     867       355188 :       if (!arg_bb || arg_bb->loop_father != cand_loop)
     868      3843755 :         return;
     869              : 
     870       281064 :       if (i == 0)
     871              :         arg0_base = derived_base_name;
     872        47538 :       else if (!operand_equal_p (derived_base_name, arg0_base, 0))
     873              :         return;
     874              :     }
     875              : 
     876              :   /* Create the candidate.  "alloc_cand_and_find_basis" is named
     877              :      misleadingly for this case, as no basis will be sought for a
     878              :      CAND_PHI.  */
     879        11654 :   base_type = TREE_TYPE (arg0_base);
     880              : 
     881        34962 :   c = alloc_cand_and_find_basis (CAND_PHI, phi, arg0_base,
     882        11654 :                                  0, integer_one_node, base_type,
     883              :                                  sizetype, savings);
     884              : 
     885              :   /* Add the candidate to the statement-candidate mapping.  */
     886        11654 :   add_cand_for_stmt (phi, c);
     887              : }
     888              : 
     889              : /* Given PBASE which is a pointer to tree, look up the defining
     890              :    statement for it and check whether the candidate is in the
     891              :    form of:
     892              : 
     893              :      X = B + (1 * S), S is integer constant
     894              :      X = B + (i * S), S is integer one
     895              : 
     896              :    If so, set PBASE to the candidate's base_expr and return double
     897              :    int (i * S).
     898              :    Otherwise, just return double int zero.  */
     899              : 
     900              : static offset_int
     901        49675 : backtrace_base_for_ref (tree *pbase)
     902              : {
     903        49675 :   tree base_in = *pbase;
     904        49675 :   slsr_cand_t base_cand;
     905              : 
     906        49675 :   STRIP_NOPS (base_in);
     907              : 
     908              :   /* Strip off widening conversion(s) to handle cases where
     909              :      e.g. 'B' is widened from an 'int' in order to calculate
     910              :      a 64-bit address.  */
     911        46908 :   if (CONVERT_EXPR_P (base_in)
     912        52442 :       && legal_cast_p_1 (TREE_TYPE (base_in),
     913         2767 :                          TREE_TYPE (TREE_OPERAND (base_in, 0))))
     914         2115 :     base_in = get_unwidened (base_in, NULL_TREE);
     915              : 
     916        49675 :   if (TREE_CODE (base_in) != SSA_NAME)
     917         1803 :     return 0;
     918              : 
     919        47872 :   base_cand = base_cand_from_table (base_in);
     920              : 
     921       121397 :   while (base_cand && base_cand->kind != CAND_PHI)
     922              :     {
     923        50433 :       if (base_cand->kind == CAND_ADD
     924        49258 :           && base_cand->index == 1
     925        79690 :           && TREE_CODE (base_cand->stride) == INTEGER_CST)
     926              :         {
     927              :           /* X = B + (1 * S), S is integer constant.  */
     928         5281 :           *pbase = base_cand->base_expr;
     929         5281 :           return wi::to_offset (base_cand->stride);
     930              :         }
     931        45152 :       else if (base_cand->kind == CAND_ADD
     932        43977 :                && TREE_CODE (base_cand->stride) == INTEGER_CST
     933        64651 :                && integer_onep (base_cand->stride))
     934              :         {
     935              :           /* X = B + (i * S), S is integer one.  */
     936        19499 :           *pbase = base_cand->base_expr;
     937        19499 :           return base_cand->index;
     938              :         }
     939              : 
     940        25653 :       base_cand = lookup_cand (base_cand->next_interp);
     941              :     }
     942              : 
     943        23092 :   return 0;
     944              : }
     945              : 
     946              : /* Look for the following pattern:
     947              : 
     948              :     *PBASE:    MEM_REF (T1, C1)
     949              : 
     950              :     *POFFSET:  MULT_EXPR (T2, C3)        [C2 is zero]
     951              :                      or
     952              :                MULT_EXPR (PLUS_EXPR (T2, C2), C3)
     953              :                      or
     954              :                MULT_EXPR (MINUS_EXPR (T2, -C2), C3)
     955              : 
     956              :     *PINDEX:   C4 * BITS_PER_UNIT
     957              : 
     958              :    If not present, leave the input values unchanged and return FALSE.
     959              :    Otherwise, modify the input values as follows and return TRUE:
     960              : 
     961              :     *PBASE:    T1
     962              :     *POFFSET:  MULT_EXPR (T2, C3)
     963              :     *PINDEX:   C1 + (C2 * C3) + C4
     964              : 
     965              :    When T2 is recorded by a CAND_ADD in the form of (T2' + C5), it
     966              :    will be further restructured to:
     967              : 
     968              :     *PBASE:    T1
     969              :     *POFFSET:  MULT_EXPR (T2', C3)
     970              :     *PINDEX:   C1 + (C2 * C3) + C4 + (C5 * C3)  */
     971              : 
     972              : static bool
     973      5505545 : restructure_reference (tree *pbase, tree *poffset, offset_int *pindex,
     974              :                        tree *ptype)
     975              : {
     976      5505545 :   tree base = *pbase, offset = *poffset;
     977      5505545 :   offset_int index = *pindex;
     978      5505545 :   tree mult_op0, t1, t2, type;
     979      5505545 :   offset_int c1, c2, c3, c4, c5;
     980      5505545 :   offset_int mem_offset;
     981              : 
     982      5505545 :   if (!base
     983      5505545 :       || !offset
     984       202460 :       || TREE_CODE (base) != MEM_REF
     985        79148 :       || !mem_ref_offset (base).is_constant (&mem_offset)
     986        79148 :       || TREE_CODE (offset) != MULT_EXPR
     987        50269 :       || TREE_CODE (TREE_OPERAND (offset, 1)) != INTEGER_CST
     988      5555812 :       || wi::umod_floor (index, BITS_PER_UNIT) != 0)
     989      5455278 :     return false;
     990              : 
     991        50267 :   t1 = TREE_OPERAND (base, 0);
     992        50267 :   c1 = offset_int::from (mem_offset, SIGNED);
     993        50267 :   type = TREE_TYPE (TREE_OPERAND (base, 1));
     994              : 
     995        50267 :   mult_op0 = TREE_OPERAND (offset, 0);
     996        50267 :   c3 = wi::to_offset (TREE_OPERAND (offset, 1));
     997              : 
     998        50267 :   if (TREE_CODE (mult_op0) == PLUS_EXPR)
     999              : 
    1000         3716 :     if (TREE_CODE (TREE_OPERAND (mult_op0, 1)) == INTEGER_CST)
    1001              :       {
    1002         3124 :         t2 = TREE_OPERAND (mult_op0, 0);
    1003         3124 :         c2 = wi::to_offset (TREE_OPERAND (mult_op0, 1));
    1004              :       }
    1005              :     else
    1006              :       return false;
    1007              : 
    1008        46551 :   else if (TREE_CODE (mult_op0) == MINUS_EXPR)
    1009              : 
    1010            0 :     if (TREE_CODE (TREE_OPERAND (mult_op0, 1)) == INTEGER_CST)
    1011              :       {
    1012            0 :         t2 = TREE_OPERAND (mult_op0, 0);
    1013            0 :         c2 = -wi::to_offset (TREE_OPERAND (mult_op0, 1));
    1014              :       }
    1015              :     else
    1016              :       return false;
    1017              : 
    1018              :   else
    1019              :     {
    1020        46551 :       t2 = mult_op0;
    1021        46551 :       c2 = 0;
    1022              :     }
    1023              : 
    1024        49675 :   c4 = index >> LOG2_BITS_PER_UNIT;
    1025        49675 :   c5 = backtrace_base_for_ref (&t2);
    1026              : 
    1027        49675 :   *pbase = t1;
    1028        49675 :   *poffset = fold_build2 (MULT_EXPR, sizetype, fold_convert (sizetype, t2),
    1029              :                           wide_int_to_tree (sizetype, c3));
    1030        49675 :   *pindex = c1 + c2 * c3 + c4 + c5 * c3;
    1031        49675 :   *ptype = type;
    1032              : 
    1033        49675 :   return true;
    1034              : }
    1035              : 
    1036              : /* Given GS which contains a data reference, create a CAND_REF entry in
    1037              :    the candidate table and attempt to find a basis.  */
    1038              : 
    1039              : static void
    1040     12241872 : slsr_process_ref (gimple *gs)
    1041              : {
    1042     12241872 :   tree ref_expr, base, offset, type;
    1043     12241872 :   poly_int64 bitsize, bitpos;
    1044     12241872 :   machine_mode mode;
    1045     12241872 :   int unsignedp, reversep, volatilep;
    1046     12241872 :   slsr_cand_t c;
    1047              : 
    1048     24483744 :   if (gimple_vdef (gs))
    1049      6883677 :     ref_expr = gimple_assign_lhs (gs);
    1050              :   else
    1051      5358195 :     ref_expr = gimple_assign_rhs1 (gs);
    1052              : 
    1053     12241872 :   if (!handled_component_p (ref_expr)
    1054      5605132 :       || TREE_CODE (ref_expr) == BIT_FIELD_REF
    1055      5577460 :       || (TREE_CODE (ref_expr) == COMPONENT_REF
    1056      4826440 :           && DECL_BIT_FIELD (TREE_OPERAND (ref_expr, 1))))
    1057     12192197 :     return;
    1058              : 
    1059      5506184 :   base = get_inner_reference (ref_expr, &bitsize, &bitpos, &offset, &mode,
    1060              :                               &unsignedp, &reversep, &volatilep);
    1061      5506184 :   HOST_WIDE_INT cbitpos;
    1062      5506184 :   if (reversep || !bitpos.is_constant (&cbitpos))
    1063              :     return;
    1064      5505545 :   offset_int index = cbitpos;
    1065              : 
    1066      5505545 :   if (!restructure_reference (&base, &offset, &index, &type))
    1067              :     return;
    1068              : 
    1069        49675 :   c = alloc_cand_and_find_basis (CAND_REF, gs, base, index, offset,
    1070              :                                  type, sizetype, 0);
    1071              : 
    1072              :   /* Add the candidate to the statement-candidate mapping.  */
    1073        49675 :   add_cand_for_stmt (gs, c);
    1074              : }
    1075              : 
    1076              : /* Create a candidate entry for a statement GS, where GS multiplies
    1077              :    two SSA names BASE_IN and STRIDE_IN.  Propagate any known information
    1078              :    about the two SSA names into the new candidate.  Return the new
    1079              :    candidate.  */
    1080              : 
    1081              : static slsr_cand_t
    1082       293778 : create_mul_ssa_cand (gimple *gs, tree base_in, tree stride_in, bool speed)
    1083              : {
    1084       293778 :   tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
    1085       293778 :   tree stype = NULL_TREE;
    1086       293778 :   offset_int index;
    1087       293778 :   unsigned savings = 0;
    1088       293778 :   slsr_cand_t c;
    1089       293778 :   slsr_cand_t base_cand = base_cand_from_table (base_in);
    1090              : 
    1091              :   /* Look at all interpretations of the base candidate, if necessary,
    1092              :      to find information to propagate into this candidate.  */
    1093       700267 :   while (base_cand && !base && base_cand->kind != CAND_PHI)
    1094              :     {
    1095              : 
    1096       112711 :       if (base_cand->kind == CAND_MULT && integer_onep (base_cand->stride))
    1097              :         {
    1098              :           /* Y = (B + i') * 1
    1099              :              X = Y * Z
    1100              :              ================
    1101              :              X = (B + i') * Z  */
    1102          263 :           base = base_cand->base_expr;
    1103          263 :           index = base_cand->index;
    1104          263 :           stride = stride_in;
    1105          263 :           ctype = base_cand->cand_type;
    1106          263 :           stype = TREE_TYPE (stride_in);
    1107          263 :           if (has_single_use (base_in))
    1108          482 :             savings = (base_cand->dead_savings
    1109          241 :                        + stmt_cost (base_cand->cand_stmt, speed));
    1110              :         }
    1111       112448 :       else if (base_cand->kind == CAND_ADD
    1112        96318 :                && TREE_CODE (base_cand->stride) == INTEGER_CST)
    1113              :         {
    1114              :           /* Y = B + (i' * S), S constant
    1115              :              X = Y * Z
    1116              :              ============================
    1117              :              X = B + ((i' * S) * Z)  */
    1118        68243 :           base = base_cand->base_expr;
    1119        68243 :           index = base_cand->index * wi::to_offset (base_cand->stride);
    1120        68243 :           stride = stride_in;
    1121        68243 :           ctype = base_cand->cand_type;
    1122        68243 :           stype = TREE_TYPE (stride_in);
    1123        68243 :           if (has_single_use (base_in))
    1124        92454 :             savings = (base_cand->dead_savings
    1125        46227 :                        + stmt_cost (base_cand->cand_stmt, speed));
    1126              :         }
    1127              : 
    1128       112711 :       base_cand = lookup_cand (base_cand->next_interp);
    1129              :     }
    1130              : 
    1131       293778 :   if (!base)
    1132              :     {
    1133              :       /* No interpretations had anything useful to propagate, so
    1134              :          produce X = (Y + 0) * Z.  */
    1135       225272 :       base = base_in;
    1136       225272 :       index = 0;
    1137       225272 :       stride = stride_in;
    1138       225272 :       ctype = TREE_TYPE (base_in);
    1139       225272 :       stype = TREE_TYPE (stride_in);
    1140              :     }
    1141              : 
    1142       293778 :   c = alloc_cand_and_find_basis (CAND_MULT, gs, base, index, stride,
    1143              :                                  ctype, stype, savings);
    1144       293778 :   return c;
    1145              : }
    1146              : 
    1147              : /* Create a candidate entry for a statement GS, where GS multiplies
    1148              :    SSA name BASE_IN by constant STRIDE_IN.  Propagate any known
    1149              :    information about BASE_IN into the new candidate.  Return the new
    1150              :    candidate.  */
    1151              : 
    1152              : static slsr_cand_t
    1153       687165 : create_mul_imm_cand (gimple *gs, tree base_in, tree stride_in, bool speed)
    1154              : {
    1155       687165 :   tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
    1156       687165 :   offset_int index, temp;
    1157       687165 :   unsigned savings = 0;
    1158       687165 :   slsr_cand_t c;
    1159       687165 :   slsr_cand_t base_cand = base_cand_from_table (base_in);
    1160              : 
    1161              :   /* Look at all interpretations of the base candidate, if necessary,
    1162              :      to find information to propagate into this candidate.  */
    1163      1779258 :   while (base_cand && !base && base_cand->kind != CAND_PHI)
    1164              :     {
    1165       404928 :       if (base_cand->kind == CAND_MULT
    1166        35325 :           && TREE_CODE (base_cand->stride) == INTEGER_CST)
    1167              :         {
    1168              :           /* Y = (B + i') * S, S constant
    1169              :              X = Y * c
    1170              :              ============================
    1171              :              X = (B + i') * (S * c)  */
    1172        14242 :           temp = wi::to_offset (base_cand->stride) * wi::to_offset (stride_in);
    1173        14242 :           if (wi::fits_to_tree_p (temp, TREE_TYPE (stride_in)))
    1174              :             {
    1175        13589 :               base = base_cand->base_expr;
    1176        13589 :               index = base_cand->index;
    1177        13589 :               stride = wide_int_to_tree (TREE_TYPE (stride_in), temp);
    1178        13589 :               ctype = base_cand->cand_type;
    1179        13589 :               if (has_single_use (base_in))
    1180        14114 :                 savings = (base_cand->dead_savings
    1181         7057 :                            + stmt_cost (base_cand->cand_stmt, speed));
    1182              :             }
    1183              :         }
    1184       390686 :       else if (base_cand->kind == CAND_ADD && integer_onep (base_cand->stride))
    1185              :         {
    1186              :           /* Y = B + (i' * 1)
    1187              :              X = Y * c
    1188              :              ===========================
    1189              :              X = (B + i') * c  */
    1190       264451 :           base = base_cand->base_expr;
    1191       264451 :           index = base_cand->index;
    1192       264451 :           stride = stride_in;
    1193       264451 :           ctype = base_cand->cand_type;
    1194       264451 :           if (has_single_use (base_in))
    1195       426122 :             savings = (base_cand->dead_savings
    1196       213061 :                        + stmt_cost (base_cand->cand_stmt, speed));
    1197              :         }
    1198       126235 :       else if (base_cand->kind == CAND_ADD
    1199       209116 :                && base_cand->index == 1
    1200       209116 :                && TREE_CODE (base_cand->stride) == INTEGER_CST)
    1201              :         {
    1202              :           /* Y = B + (1 * S), S constant
    1203              :              X = Y * c
    1204              :              ===========================
    1205              :              X = (B + S) * c  */
    1206            0 :           base = base_cand->base_expr;
    1207            0 :           index = wi::to_offset (base_cand->stride);
    1208            0 :           stride = stride_in;
    1209            0 :           ctype = base_cand->cand_type;
    1210            0 :           if (has_single_use (base_in))
    1211            0 :             savings = (base_cand->dead_savings
    1212            0 :                        + stmt_cost (base_cand->cand_stmt, speed));
    1213              :         }
    1214              : 
    1215       404928 :       base_cand = lookup_cand (base_cand->next_interp);
    1216              :     }
    1217              : 
    1218       687165 :   if (!base)
    1219              :     {
    1220              :       /* No interpretations had anything useful to propagate, so
    1221              :          produce X = (Y + 0) * c.  */
    1222       409125 :       base = base_in;
    1223       409125 :       index = 0;
    1224       409125 :       stride = stride_in;
    1225       409125 :       ctype = TREE_TYPE (base_in);
    1226              :     }
    1227              : 
    1228       687165 :   c = alloc_cand_and_find_basis (CAND_MULT, gs, base, index, stride,
    1229              :                                  ctype, sizetype, savings);
    1230       687165 :   return c;
    1231              : }
    1232              : 
    1233              : /* Given GS which is a multiply of scalar integers, make an appropriate
    1234              :    entry in the candidate table.  If this is a multiply of two SSA names,
    1235              :    create two CAND_MULT interpretations and attempt to find a basis for
    1236              :    each of them.  Otherwise, create a single CAND_MULT and attempt to
    1237              :    find a basis.  */
    1238              : 
    1239              : static void
    1240       743248 : slsr_process_mul (gimple *gs, tree rhs1, tree rhs2, bool speed)
    1241              : {
    1242       743248 :   slsr_cand_t c, c2;
    1243              : 
    1244              :   /* If this is a multiply of an SSA name with itself, it is highly
    1245              :      unlikely that we will get a strength reduction opportunity, so
    1246              :      don't record it as a candidate.  This simplifies the logic for
    1247              :      finding a basis, so if this is removed that must be considered.  */
    1248       743248 :   if (rhs1 == rhs2)
    1249              :     return;
    1250              : 
    1251       735794 :   if (TREE_CODE (rhs2) == SSA_NAME)
    1252              :     {
    1253              :       /* Record an interpretation of this statement in the candidate table
    1254              :          assuming RHS1 is the base expression and RHS2 is the stride.  */
    1255       146889 :       c = create_mul_ssa_cand (gs, rhs1, rhs2, speed);
    1256              : 
    1257              :       /* Add the first interpretation to the statement-candidate mapping.  */
    1258       146889 :       add_cand_for_stmt (gs, c);
    1259              : 
    1260              :       /* Record another interpretation of this statement assuming RHS1
    1261              :          is the stride and RHS2 is the base expression.  */
    1262       146889 :       c2 = create_mul_ssa_cand (gs, rhs2, rhs1, speed);
    1263       146889 :       c->next_interp = c2->cand_num;
    1264       146889 :       c2->first_interp = c->cand_num;
    1265              :     }
    1266       588905 :   else if (TREE_CODE (rhs2) == INTEGER_CST && !integer_zerop (rhs2))
    1267              :     {
    1268              :       /* Record an interpretation for the multiply-immediate.  */
    1269       588905 :       c = create_mul_imm_cand (gs, rhs1, rhs2, speed);
    1270              : 
    1271              :       /* Add the interpretation to the statement-candidate mapping.  */
    1272       588905 :       add_cand_for_stmt (gs, c);
    1273              :     }
    1274              : }
    1275              : 
    1276              : /* Create a candidate entry for a statement GS, where GS adds two
    1277              :    SSA names BASE_IN and ADDEND_IN if SUBTRACT_P is false, and
    1278              :    subtracts ADDEND_IN from BASE_IN otherwise.  Propagate any known
    1279              :    information about the two SSA names into the new candidate.
    1280              :    Return the new candidate.  */
    1281              : 
    1282              : static slsr_cand_t
    1283      1929054 : create_add_ssa_cand (gimple *gs, tree base_in, tree addend_in,
    1284              :                      bool subtract_p, bool speed)
    1285              : {
    1286      1929054 :   tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
    1287      1929054 :   tree stype = NULL_TREE;
    1288      1929054 :   offset_int index;
    1289      1929054 :   unsigned savings = 0;
    1290      1929054 :   slsr_cand_t c;
    1291      1929054 :   slsr_cand_t base_cand = base_cand_from_table (base_in);
    1292      1929054 :   slsr_cand_t addend_cand = base_cand_from_table (addend_in);
    1293              : 
    1294              :   /* The most useful transformation is a multiply-immediate feeding
    1295              :      an add or subtract.  Look for that first.  */
    1296      5499326 :   while (addend_cand && !base && addend_cand->kind != CAND_PHI)
    1297              :     {
    1298      1641218 :       if (addend_cand->kind == CAND_MULT
    1299      1792761 :           && addend_cand->index == 0
    1300      2420349 :           && TREE_CODE (addend_cand->stride) == INTEGER_CST)
    1301              :         {
    1302              :           /* Z = (B + 0) * S, S constant
    1303              :              X = Y +/- Z
    1304              :              ===========================
    1305              :              X = Y + ((+/-1 * S) * B)  */
    1306       627588 :           base = base_in;
    1307       627588 :           index = wi::to_offset (addend_cand->stride);
    1308       627588 :           if (subtract_p)
    1309        50252 :             index = -index;
    1310       627588 :           stride = addend_cand->base_expr;
    1311       627588 :           ctype = TREE_TYPE (base_in);
    1312       627588 :           stype = addend_cand->cand_type;
    1313       627588 :           if (has_single_use (addend_in))
    1314      1003472 :             savings = (addend_cand->dead_savings
    1315       501736 :                        + stmt_cost (addend_cand->cand_stmt, speed));
    1316              :         }
    1317              : 
    1318      1641218 :       addend_cand = lookup_cand (addend_cand->next_interp);
    1319              :     }
    1320              : 
    1321      2694790 :   while (base_cand && !base && base_cand->kind != CAND_PHI)
    1322              :     {
    1323       765736 :       if (base_cand->kind == CAND_ADD
    1324       765736 :           && (base_cand->index == 0
    1325       429910 :               || operand_equal_p (base_cand->stride,
    1326       429910 :                                   integer_zero_node, 0)))
    1327              :         {
    1328              :           /* Y = B + (i' * S), i' * S = 0
    1329              :              X = Y +/- Z
    1330              :              ============================
    1331              :              X = B + (+/-1 * Z)  */
    1332       113872 :           base = base_cand->base_expr;
    1333       215552 :           index = subtract_p ? -1 : 1;
    1334       113872 :           stride = addend_in;
    1335       113872 :           ctype = base_cand->cand_type;
    1336       227744 :           stype = (TREE_CODE (addend_in) == INTEGER_CST ? sizetype
    1337       113872 :                    : TREE_TYPE (addend_in));
    1338       113872 :           if (has_single_use (base_in))
    1339       166476 :             savings = (base_cand->dead_savings
    1340        83238 :                        + stmt_cost (base_cand->cand_stmt, speed));
    1341              :         }
    1342       651864 :       else if (subtract_p)
    1343              :         {
    1344        67189 :           slsr_cand_t subtrahend_cand = base_cand_from_table (addend_in);
    1345              : 
    1346       160157 :           while (subtrahend_cand && !base && subtrahend_cand->kind != CAND_PHI)
    1347              :             {
    1348        25779 :               if (subtrahend_cand->kind == CAND_MULT
    1349        33433 :                   && subtrahend_cand->index == 0
    1350        33433 :                   && TREE_CODE (subtrahend_cand->stride) == INTEGER_CST)
    1351              :                 {
    1352              :                   /* Z = (B + 0) * S, S constant
    1353              :                      X = Y - Z
    1354              :                      ===========================
    1355              :                      Value:  X = Y + ((-1 * S) * B)  */
    1356            0 :                   base = base_in;
    1357            0 :                   index = wi::to_offset (subtrahend_cand->stride);
    1358            0 :                   index = -index;
    1359            0 :                   stride = subtrahend_cand->base_expr;
    1360            0 :                   ctype = TREE_TYPE (base_in);
    1361            0 :                   stype = subtrahend_cand->cand_type;
    1362            0 :                   if (has_single_use (addend_in))
    1363            0 :                     savings = (subtrahend_cand->dead_savings
    1364            0 :                                + stmt_cost (subtrahend_cand->cand_stmt, speed));
    1365              :                 }
    1366              : 
    1367        25779 :               subtrahend_cand = lookup_cand (subtrahend_cand->next_interp);
    1368              :             }
    1369              :         }
    1370              : 
    1371       765736 :       base_cand = lookup_cand (base_cand->next_interp);
    1372              :     }
    1373              : 
    1374      1929054 :   if (!base)
    1375              :     {
    1376              :       /* No interpretations had anything useful to propagate, so
    1377              :          produce X = Y + (1 * Z).  */
    1378      1187594 :       base = base_in;
    1379      2204684 :       index = subtract_p ? -1 : 1;
    1380      1187594 :       stride = addend_in;
    1381      1187594 :       ctype = TREE_TYPE (base_in);
    1382      2375188 :       stype = (TREE_CODE (addend_in) == INTEGER_CST ? sizetype
    1383      1187594 :                : TREE_TYPE (addend_in));
    1384              :     }
    1385              : 
    1386      1929054 :   c = alloc_cand_and_find_basis (CAND_ADD, gs, base, index, stride,
    1387              :                                  ctype, stype, savings);
    1388      1929054 :   return c;
    1389              : }
    1390              : 
    1391              : /* Create a candidate entry for a statement GS, where GS adds SSA
    1392              :    name BASE_IN to constant INDEX_IN.  Propagate any known information
    1393              :    about BASE_IN into the new candidate.  Return the new candidate.  */
    1394              : 
    1395              : static slsr_cand_t
    1396      1942576 : create_add_imm_cand (gimple *gs, tree base_in, const offset_int &index_in,
    1397              :                      bool speed)
    1398              : {
    1399      1942576 :   enum cand_kind kind = CAND_ADD;
    1400      1942576 :   tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
    1401      1942576 :   tree stype = NULL_TREE;
    1402      1942576 :   offset_int index, multiple;
    1403      1942576 :   unsigned savings = 0;
    1404      1942576 :   slsr_cand_t c;
    1405      1942576 :   slsr_cand_t base_cand = base_cand_from_table (base_in);
    1406              : 
    1407      4337639 :   while (base_cand && !base && base_cand->kind != CAND_PHI)
    1408              :     {
    1409       452487 :       signop sign = TYPE_SIGN (TREE_TYPE (base_cand->stride));
    1410              : 
    1411       452487 :       if (TREE_CODE (base_cand->stride) == INTEGER_CST
    1412       452487 :           && wi::multiple_of_p (index_in, wi::to_offset (base_cand->stride),
    1413              :                                 sign, &multiple))
    1414              :         {
    1415              :           /* Y = (B + i') * S, S constant, c = kS for some integer k
    1416              :              X = Y + c
    1417              :              ============================
    1418              :              X = (B + (i'+ k)) * S
    1419              :           OR
    1420              :              Y = B + (i' * S), S constant, c = kS for some integer k
    1421              :              X = Y + c
    1422              :              ============================
    1423              :              X = (B + (i'+ k)) * S  */
    1424       267496 :           kind = base_cand->kind;
    1425       267496 :           base = base_cand->base_expr;
    1426       267496 :           index = base_cand->index + multiple;
    1427       267496 :           stride = base_cand->stride;
    1428       267496 :           ctype = base_cand->cand_type;
    1429       267496 :           stype = base_cand->stride_type;
    1430       267496 :           if (has_single_use (base_in))
    1431       323160 :             savings = (base_cand->dead_savings
    1432       161580 :                        + stmt_cost (base_cand->cand_stmt, speed));
    1433              :         }
    1434              : 
    1435       452487 :       base_cand = lookup_cand (base_cand->next_interp);
    1436              :     }
    1437              : 
    1438      1942576 :   if (!base)
    1439              :     {
    1440              :       /* No interpretations had anything useful to propagate, so
    1441              :          produce X = Y + (c * 1).  */
    1442      1675080 :       kind = CAND_ADD;
    1443      1675080 :       base = base_in;
    1444      1675080 :       index = index_in;
    1445      1675080 :       stride = integer_one_node;
    1446      1675080 :       ctype = TREE_TYPE (base_in);
    1447      1675080 :       stype = sizetype;
    1448              :     }
    1449              : 
    1450      1942576 :   c = alloc_cand_and_find_basis (kind, gs, base, index, stride,
    1451              :                                  ctype, stype, savings);
    1452      1942576 :   return c;
    1453              : }
    1454              : 
    1455              : /* Given GS which is an add or subtract of scalar integers or pointers,
    1456              :    make at least one appropriate entry in the candidate table.  */
    1457              : 
    1458              : static void
    1459      3240740 : slsr_process_add (gimple *gs, tree rhs1, tree rhs2, bool speed)
    1460              : {
    1461      3240740 :   bool subtract_p = gimple_assign_rhs_code (gs) == MINUS_EXPR;
    1462      3240740 :   slsr_cand_t c = NULL, c2;
    1463              : 
    1464      3240740 :   if (TREE_CODE (rhs2) == SSA_NAME)
    1465              :     {
    1466              :       /* First record an interpretation assuming RHS1 is the base expression
    1467              :          and RHS2 is the stride.  But it doesn't make sense for the
    1468              :          stride to be a pointer, so don't record a candidate in that case.  */
    1469      1298164 :       if (!POINTER_TYPE_P (TREE_TYPE (rhs2)))
    1470              :         {
    1471      1298164 :           c = create_add_ssa_cand (gs, rhs1, rhs2, subtract_p, speed);
    1472              : 
    1473              :           /* Add the first interpretation to the statement-candidate
    1474              :              mapping.  */
    1475      1298164 :           add_cand_for_stmt (gs, c);
    1476              :         }
    1477              : 
    1478              :       /* If the two RHS operands are identical, or this is a subtract,
    1479              :          we're done.  */
    1480      1298164 :       if (operand_equal_p (rhs1, rhs2, 0) || subtract_p)
    1481              :         return;
    1482              : 
    1483              :       /* Otherwise, record another interpretation assuming RHS2 is the
    1484              :          base expression and RHS1 is the stride, again provided that the
    1485              :          stride is not a pointer.  */
    1486      1065216 :       if (!POINTER_TYPE_P (TREE_TYPE (rhs1)))
    1487              :         {
    1488       630890 :           c2 = create_add_ssa_cand (gs, rhs2, rhs1, false, speed);
    1489       630890 :           if (c)
    1490              :             {
    1491       630890 :               c->next_interp = c2->cand_num;
    1492       630890 :               c2->first_interp = c->cand_num;
    1493              :             }
    1494              :           else
    1495            0 :             add_cand_for_stmt (gs, c2);
    1496              :         }
    1497              :     }
    1498      1942576 :   else if (TREE_CODE (rhs2) == INTEGER_CST)
    1499              :     {
    1500              :       /* Record an interpretation for the add-immediate.  */
    1501      1942576 :       offset_int index = wi::to_offset (rhs2);
    1502      1942576 :       if (subtract_p)
    1503        25686 :         index = -index;
    1504              : 
    1505      1942576 :       c = create_add_imm_cand (gs, rhs1, index, speed);
    1506              : 
    1507              :       /* Add the interpretation to the statement-candidate mapping.  */
    1508      1942576 :       add_cand_for_stmt (gs, c);
    1509              :     }
    1510              : }
    1511              : 
    1512              : /* Given GS which is a negate of a scalar integer, make an appropriate
    1513              :    entry in the candidate table.  A negate is equivalent to a multiply
    1514              :    by -1.  */
    1515              : 
    1516              : static void
    1517        98260 : slsr_process_neg (gimple *gs, tree rhs1, bool speed)
    1518              : {
    1519              :   /* Record a CAND_MULT interpretation for the multiply by -1.  */
    1520        98260 :   slsr_cand_t c = create_mul_imm_cand (gs, rhs1, integer_minus_one_node, speed);
    1521              : 
    1522              :   /* Add the interpretation to the statement-candidate mapping.  */
    1523        98260 :   add_cand_for_stmt (gs, c);
    1524        98260 : }
    1525              : 
    1526              : /* Help function for legal_cast_p, operating on two trees.  Checks
    1527              :    whether it's allowable to cast from RHS to LHS.  See legal_cast_p
    1528              :    for more details.  */
    1529              : 
    1530              : static bool
    1531      2828388 : legal_cast_p_1 (tree lhs_type, tree rhs_type)
    1532              : {
    1533      2828388 :   unsigned lhs_size, rhs_size;
    1534      2828388 :   bool lhs_wraps, rhs_wraps;
    1535              : 
    1536      2828388 :   lhs_size = TYPE_PRECISION (lhs_type);
    1537      2828388 :   rhs_size = TYPE_PRECISION (rhs_type);
    1538      2828388 :   lhs_wraps = ANY_INTEGRAL_TYPE_P (lhs_type) && TYPE_OVERFLOW_WRAPS (lhs_type);
    1539      2828388 :   rhs_wraps = ANY_INTEGRAL_TYPE_P (rhs_type) && TYPE_OVERFLOW_WRAPS (rhs_type);
    1540              : 
    1541      2828388 :   if (lhs_size < rhs_size
    1542      2572225 :       || (rhs_wraps && !lhs_wraps)
    1543      1664797 :       || (rhs_wraps && lhs_wraps && rhs_size != lhs_size))
    1544      1346820 :     return false;
    1545              : 
    1546              :   return true;
    1547              : }
    1548              : 
    1549              : /* Return TRUE if GS is a statement that defines an SSA name from
    1550              :    a conversion and is legal for us to combine with an add and multiply
    1551              :    in the candidate table.  For example, suppose we have:
    1552              : 
    1553              :      A = B + i;
    1554              :      C = (type) A;
    1555              :      D = C * S;
    1556              : 
    1557              :    Without the type-cast, we would create a CAND_MULT for D with base B,
    1558              :    index i, and stride S.  We want to record this candidate only if it
    1559              :    is equivalent to apply the type cast following the multiply:
    1560              : 
    1561              :      A = B + i;
    1562              :      E = A * S;
    1563              :      D = (type) E;
    1564              : 
    1565              :    We will record the type with the candidate for D.  This allows us
    1566              :    to use a similar previous candidate as a basis.  If we have earlier seen
    1567              : 
    1568              :      A' = B + i';
    1569              :      C' = (type) A';
    1570              :      D' = C' * S;
    1571              : 
    1572              :    we can replace D with
    1573              : 
    1574              :      D = D' + (i - i') * S;
    1575              : 
    1576              :    But if moving the type-cast would change semantics, we mustn't do this.
    1577              : 
    1578              :    This is legitimate for casts from a non-wrapping integral type to
    1579              :    any integral type of the same or larger size.  It is not legitimate
    1580              :    to convert a wrapping type to a non-wrapping type, or to a wrapping
    1581              :    type of a different size.  I.e., with a wrapping type, we must
    1582              :    assume that the addition B + i could wrap, in which case performing
    1583              :    the multiply before or after one of the "illegal" type casts will
    1584              :    have different semantics.  */
    1585              : 
    1586              : static bool
    1587      2823585 : legal_cast_p (gimple *gs, tree rhs)
    1588              : {
    1589      2823585 :   if (!is_gimple_assign (gs)
    1590      2823585 :       || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (gs)))
    1591              :     return false;
    1592              : 
    1593      2823585 :   return legal_cast_p_1 (TREE_TYPE (gimple_assign_lhs (gs)), TREE_TYPE (rhs));
    1594              : }
    1595              : 
    1596              : /* Given GS which is a cast to a scalar integer type, determine whether
    1597              :    the cast is legal for strength reduction.  If so, make at least one
    1598              :    appropriate entry in the candidate table.  */
    1599              : 
    1600              : static void
    1601      2823585 : slsr_process_cast (gimple *gs, tree rhs1, bool speed)
    1602              : {
    1603      2823585 :   tree lhs, ctype;
    1604      2823585 :   slsr_cand_t base_cand, c = NULL, c2;
    1605      2823585 :   unsigned savings = 0;
    1606              : 
    1607      2823585 :   if (!legal_cast_p (gs, rhs1))
    1608              :     return;
    1609              : 
    1610      1477471 :   lhs = gimple_assign_lhs (gs);
    1611      1477471 :   base_cand = base_cand_from_table (rhs1);
    1612      1477471 :   ctype = TREE_TYPE (lhs);
    1613              : 
    1614      1477471 :   if (base_cand && base_cand->kind != CAND_PHI)
    1615              :     {
    1616              :       slsr_cand_t first_cand = NULL;
    1617              : 
    1618       617508 :       while (base_cand)
    1619              :         {
    1620              :           /* Propagate all data from the base candidate except the type,
    1621              :              which comes from the cast, and the base candidate's cast,
    1622              :              which is no longer applicable.  */
    1623       351947 :           if (has_single_use (rhs1))
    1624       398416 :             savings = (base_cand->dead_savings
    1625       199208 :                        + stmt_cost (base_cand->cand_stmt, speed));
    1626              : 
    1627       703894 :           c = alloc_cand_and_find_basis (base_cand->kind, gs,
    1628              :                                          base_cand->base_expr,
    1629       351947 :                                          base_cand->index, base_cand->stride,
    1630              :                                          ctype, base_cand->stride_type,
    1631              :                                          savings);
    1632       351947 :           if (!first_cand)
    1633       265561 :             first_cand = c;
    1634              : 
    1635       351947 :           if (first_cand != c)
    1636        86386 :             c->first_interp = first_cand->cand_num;
    1637              : 
    1638       351947 :           base_cand = lookup_cand (base_cand->next_interp);
    1639              :         }
    1640              :     }
    1641              :   else
    1642              :     {
    1643              :       /* If nothing is known about the RHS, create fresh CAND_ADD and
    1644              :          CAND_MULT interpretations:
    1645              : 
    1646              :          X = Y + (0 * 1)
    1647              :          X = (Y + 0) * 1
    1648              : 
    1649              :          The first of these is somewhat arbitrary, but the choice of
    1650              :          1 for the stride simplifies the logic for propagating casts
    1651              :          into their uses.  */
    1652      1211910 :       c = alloc_cand_and_find_basis (CAND_ADD, gs, rhs1, 0,
    1653              :                                      integer_one_node, ctype, sizetype, 0);
    1654      1211910 :       c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1, 0,
    1655              :                                       integer_one_node, ctype, sizetype, 0);
    1656      1211910 :       c->next_interp = c2->cand_num;
    1657      1211910 :       c2->first_interp = c->cand_num;
    1658              :     }
    1659              : 
    1660              :   /* Add the first (or only) interpretation to the statement-candidate
    1661              :      mapping.  */
    1662      1477471 :   add_cand_for_stmt (gs, c);
    1663              : }
    1664              : 
    1665              : /* Given GS which is a copy of a scalar integer type, make at least one
    1666              :    appropriate entry in the candidate table.
    1667              : 
    1668              :    This interface is included for completeness, but is unnecessary
    1669              :    if this pass immediately follows a pass that performs copy
    1670              :    propagation, such as DOM.  */
    1671              : 
    1672              : static void
    1673       151047 : slsr_process_copy (gimple *gs, tree rhs1, bool speed)
    1674              : {
    1675       151047 :   slsr_cand_t base_cand, c = NULL, c2;
    1676       151047 :   unsigned savings = 0;
    1677              : 
    1678       151047 :   base_cand = base_cand_from_table (rhs1);
    1679              : 
    1680       151047 :   if (base_cand && base_cand->kind != CAND_PHI)
    1681              :     {
    1682              :       slsr_cand_t first_cand = NULL;
    1683              : 
    1684        98317 :       while (base_cand)
    1685              :         {
    1686              :           /* Propagate all data from the base candidate.  */
    1687        55564 :           if (has_single_use (rhs1))
    1688        94920 :             savings = (base_cand->dead_savings
    1689        47460 :                        + stmt_cost (base_cand->cand_stmt, speed));
    1690              : 
    1691       111128 :           c = alloc_cand_and_find_basis (base_cand->kind, gs,
    1692              :                                          base_cand->base_expr,
    1693        55564 :                                          base_cand->index, base_cand->stride,
    1694              :                                          base_cand->cand_type,
    1695              :                                          base_cand->stride_type, savings);
    1696        55564 :           if (!first_cand)
    1697        42753 :             first_cand = c;
    1698              : 
    1699        55564 :           if (first_cand != c)
    1700        12811 :             c->first_interp = first_cand->cand_num;
    1701              : 
    1702        55564 :           base_cand = lookup_cand (base_cand->next_interp);
    1703              :         }
    1704              :     }
    1705              :   else
    1706              :     {
    1707              :       /* If nothing is known about the RHS, create fresh CAND_ADD and
    1708              :          CAND_MULT interpretations:
    1709              : 
    1710              :          X = Y + (0 * 1)
    1711              :          X = (Y + 0) * 1
    1712              : 
    1713              :          The first of these is somewhat arbitrary, but the choice of
    1714              :          1 for the stride simplifies the logic for propagating casts
    1715              :          into their uses.  */
    1716       108294 :       c = alloc_cand_and_find_basis (CAND_ADD, gs, rhs1, 0,
    1717       108294 :                                      integer_one_node, TREE_TYPE (rhs1),
    1718              :                                      sizetype, 0);
    1719       108294 :       c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1, 0,
    1720       108294 :                                       integer_one_node, TREE_TYPE (rhs1),
    1721              :                                       sizetype, 0);
    1722       108294 :       c->next_interp = c2->cand_num;
    1723       108294 :       c2->first_interp = c->cand_num;
    1724              :     }
    1725              : 
    1726              :   /* Add the first (or only) interpretation to the statement-candidate
    1727              :      mapping.  */
    1728       151047 :   add_cand_for_stmt (gs, c);
    1729       151047 : }
    1730              : 
    1731      2082932 : class find_candidates_dom_walker : public dom_walker
    1732              : {
    1733              : public:
    1734      1041466 :   find_candidates_dom_walker (cdi_direction direction)
    1735      2082932 :     : dom_walker (direction) {}
    1736              :   edge before_dom_children (basic_block) final override;
    1737              : };
    1738              : 
    1739              : /* Find strength-reduction candidates in block BB.  */
    1740              : 
    1741              : edge
    1742     10986769 : find_candidates_dom_walker::before_dom_children (basic_block bb)
    1743              : {
    1744     10986769 :   bool speed = optimize_bb_for_speed_p (bb);
    1745              : 
    1746     15421958 :   for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
    1747      4435189 :        gsi_next (&gsi))
    1748      4435189 :     slsr_process_phi (gsi.phi (), speed);
    1749              : 
    1750    106671436 :   for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
    1751     84697898 :        gsi_next (&gsi))
    1752              :     {
    1753     84697898 :       gimple *gs = gsi_stmt (gsi);
    1754              : 
    1755     84697898 :       if (stmt_could_throw_p (cfun, gs))
    1756      3227568 :         continue;
    1757              : 
    1758    109106234 :       if (gimple_vuse (gs) && gimple_assign_single_p (gs))
    1759     12241872 :         slsr_process_ref (gs);
    1760              : 
    1761     69228458 :       else if (is_gimple_assign (gs)
    1762     69228458 :                && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (gs)))
    1763      3142128 :                    || POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (gs)))))
    1764              :         {
    1765      9798753 :           tree rhs1 = NULL_TREE, rhs2 = NULL_TREE;
    1766              : 
    1767      9798753 :           switch (gimple_assign_rhs_code (gs))
    1768              :             {
    1769      2984024 :             case MULT_EXPR:
    1770      2984024 :             case PLUS_EXPR:
    1771      2984024 :               rhs1 = gimple_assign_rhs1 (gs);
    1772      2984024 :               rhs2 = gimple_assign_rhs2 (gs);
    1773              :               /* Should never happen, but currently some buggy situations
    1774              :                  in earlier phases put constants in rhs1.  */
    1775      2984024 :               if (TREE_CODE (rhs1) != SSA_NAME)
    1776            1 :                 continue;
    1777              :               break;
    1778              : 
    1779              :             /* Possible future opportunity: rhs1 of a ptr+ can be
    1780              :                an ADDR_EXPR.  */
    1781      1102130 :             case POINTER_PLUS_EXPR:
    1782      1102130 :             case MINUS_EXPR:
    1783      1102130 :               rhs2 = gimple_assign_rhs2 (gs);
    1784      4392553 :               gcc_fallthrough ();
    1785              : 
    1786      4392553 :             CASE_CONVERT:
    1787      4392553 :             case SSA_NAME:
    1788      4392553 :             case NEGATE_EXPR:
    1789      4392553 :               rhs1 = gimple_assign_rhs1 (gs);
    1790      4392553 :               if (TREE_CODE (rhs1) != SSA_NAME)
    1791       319696 :                 continue;
    1792              :               break;
    1793              : 
    1794      9479056 :             default:
    1795      9479056 :               ;
    1796              :             }
    1797              : 
    1798      9479056 :           switch (gimple_assign_rhs_code (gs))
    1799              :             {
    1800       743248 :             case MULT_EXPR:
    1801       743248 :               slsr_process_mul (gs, rhs1, rhs2, speed);
    1802       743248 :               break;
    1803              : 
    1804      3240740 :             case PLUS_EXPR:
    1805      3240740 :             case POINTER_PLUS_EXPR:
    1806      3240740 :             case MINUS_EXPR:
    1807      3240740 :               slsr_process_add (gs, rhs1, rhs2, speed);
    1808      3240740 :               break;
    1809              : 
    1810        98260 :             case NEGATE_EXPR:
    1811        98260 :               slsr_process_neg (gs, rhs1, speed);
    1812        98260 :               break;
    1813              : 
    1814      2823585 :             CASE_CONVERT:
    1815      2823585 :               slsr_process_cast (gs, rhs1, speed);
    1816      2823585 :               break;
    1817              : 
    1818       151047 :             case SSA_NAME:
    1819       151047 :               slsr_process_copy (gs, rhs1, speed);
    1820       151047 :               break;
    1821              : 
    1822              :             default:
    1823              :               ;
    1824              :             }
    1825              :         }
    1826              :     }
    1827     10986769 :   return NULL;
    1828              : }
    1829              : 
    1830              : /* Dump a candidate for debug.  */
    1831              : 
    1832              : static void
    1833           33 : dump_candidate (slsr_cand_t c)
    1834              : {
    1835           33 :   fprintf (dump_file, "%3d  [%d] ", c->cand_num,
    1836           33 :            gimple_bb (c->cand_stmt)->index);
    1837           33 :   print_gimple_stmt (dump_file, c->cand_stmt, 0);
    1838           33 :   switch (c->kind)
    1839              :     {
    1840            5 :     case CAND_MULT:
    1841            5 :       fputs ("     MULT : (", dump_file);
    1842            5 :       print_generic_expr (dump_file, c->base_expr);
    1843            5 :       fputs (" + ", dump_file);
    1844            5 :       print_decs (c->index, dump_file);
    1845            5 :       fputs (") * ", dump_file);
    1846            5 :       if (TREE_CODE (c->stride) != INTEGER_CST
    1847            5 :           && c->stride_type != TREE_TYPE (c->stride))
    1848              :         {
    1849            0 :           fputs ("(", dump_file);
    1850            0 :           print_generic_expr (dump_file, c->stride_type);
    1851            0 :           fputs (")", dump_file);
    1852              :         }
    1853            5 :       print_generic_expr (dump_file, c->stride);
    1854            5 :       fputs (" : ", dump_file);
    1855            5 :       break;
    1856           17 :     case CAND_ADD:
    1857           17 :       fputs ("     ADD  : ", dump_file);
    1858           17 :       print_generic_expr (dump_file, c->base_expr);
    1859           17 :       fputs (" + (", dump_file);
    1860           17 :       print_decs (c->index, dump_file);
    1861           17 :       fputs (" * ", dump_file);
    1862           17 :       if (TREE_CODE (c->stride) != INTEGER_CST
    1863           17 :           && c->stride_type != TREE_TYPE (c->stride))
    1864              :         {
    1865            0 :           fputs ("(", dump_file);
    1866            0 :           print_generic_expr (dump_file, c->stride_type);
    1867            0 :           fputs (")", dump_file);
    1868              :         }
    1869           17 :       print_generic_expr (dump_file, c->stride);
    1870           17 :       fputs (") : ", dump_file);
    1871           17 :       break;
    1872           11 :     case CAND_REF:
    1873           11 :       fputs ("     REF  : ", dump_file);
    1874           11 :       print_generic_expr (dump_file, c->base_expr);
    1875           11 :       fputs (" + (", dump_file);
    1876           11 :       print_generic_expr (dump_file, c->stride);
    1877           11 :       fputs (") + ", dump_file);
    1878           11 :       print_decs (c->index, dump_file);
    1879           11 :       fputs (" : ", dump_file);
    1880           11 :       break;
    1881            0 :     case CAND_PHI:
    1882            0 :       fputs ("     PHI  : ", dump_file);
    1883            0 :       print_generic_expr (dump_file, c->base_expr);
    1884            0 :       fputs (" + (unknown * ", dump_file);
    1885            0 :       print_generic_expr (dump_file, c->stride);
    1886            0 :       fputs (") : ", dump_file);
    1887            0 :       break;
    1888            0 :     default:
    1889            0 :       gcc_unreachable ();
    1890              :     }
    1891           33 :   print_generic_expr (dump_file, c->cand_type);
    1892           33 :   fprintf (dump_file, "\n     basis: %d  dependent: %d  sibling: %d\n",
    1893              :            c->basis, c->dependent, c->sibling);
    1894           33 :   fprintf (dump_file,
    1895              :            "     next-interp: %d  first-interp: %d  dead-savings: %d\n",
    1896              :            c->next_interp, c->first_interp, c->dead_savings);
    1897           33 :   if (c->def_phi)
    1898            0 :     fprintf (dump_file, "     phi:  %d\n", c->def_phi);
    1899           33 :   fputs ("\n", dump_file);
    1900           33 : }
    1901              : 
    1902              : /* Dump the candidate vector for debug.  */
    1903              : 
    1904              : static void
    1905            3 : dump_cand_vec (void)
    1906              : {
    1907            3 :   unsigned i;
    1908            3 :   slsr_cand_t c;
    1909              : 
    1910            3 :   fprintf (dump_file, "\nStrength reduction candidate vector:\n\n");
    1911              : 
    1912           42 :   FOR_EACH_VEC_ELT (cand_vec, i, c)
    1913           36 :     if (c != NULL)
    1914           33 :       dump_candidate (c);
    1915            3 : }
    1916              : 
    1917              : /* Callback used to dump the candidate chains hash table.  */
    1918              : 
    1919              : int
    1920           14 : ssa_base_cand_dump_callback (cand_chain **slot, void *ignored ATTRIBUTE_UNUSED)
    1921              : {
    1922           14 :   const_cand_chain_t chain = *slot;
    1923           14 :   cand_chain_t p;
    1924              : 
    1925           14 :   print_generic_expr (dump_file, chain->base_expr);
    1926           14 :   fprintf (dump_file, " -> %d", chain->cand->cand_num);
    1927              : 
    1928           42 :   for (p = chain->next; p; p = p->next)
    1929           28 :     fprintf (dump_file, " -> %d", p->cand->cand_num);
    1930              : 
    1931           14 :   fputs ("\n", dump_file);
    1932           14 :   return 1;
    1933              : }
    1934              : 
    1935              : /* Dump the candidate chains.  */
    1936              : 
    1937              : static void
    1938            3 : dump_cand_chains (void)
    1939              : {
    1940            3 :   fprintf (dump_file, "\nStrength reduction candidate chains:\n\n");
    1941            3 :   base_cand_map->traverse_noresize <void *, ssa_base_cand_dump_callback>
    1942           17 :     (NULL);
    1943            3 :   fputs ("\n", dump_file);
    1944            3 : }
    1945              : 
    1946              : /* Dump the increment vector for debug.  */
    1947              : 
    1948              : static void
    1949        36348 : dump_incr_vec (void)
    1950              : {
    1951        36348 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1952              :     {
    1953            0 :       unsigned i;
    1954              : 
    1955            0 :       fprintf (dump_file, "\nIncrement vector:\n\n");
    1956              : 
    1957            0 :       for (i = 0; i < incr_vec_len; i++)
    1958              :         {
    1959            0 :           fprintf (dump_file, "%3d  increment:   ", i);
    1960            0 :           print_decs (incr_vec[i].incr, dump_file);
    1961            0 :           fprintf (dump_file, "\n     count:       %d", incr_vec[i].count);
    1962            0 :           fprintf (dump_file, "\n     cost:        %d", incr_vec[i].cost);
    1963            0 :           fputs ("\n     initializer: ", dump_file);
    1964            0 :           print_generic_expr (dump_file, incr_vec[i].initializer);
    1965            0 :           fputs ("\n\n", dump_file);
    1966              :         }
    1967              :     }
    1968        36348 : }
    1969              : 
    1970              : /* Replace *EXPR in candidate C with an equivalent strength-reduced
    1971              :    data reference.  */
    1972              : 
    1973              : static void
    1974        19221 : replace_ref (tree *expr, slsr_cand_t c)
    1975              : {
    1976        19221 :   tree add_expr, mem_ref, acc_type = TREE_TYPE (*expr);
    1977        19221 :   unsigned HOST_WIDE_INT misalign;
    1978        19221 :   unsigned align;
    1979              : 
    1980              :   /* Ensure the memory reference carries the minimum alignment
    1981              :      requirement for the data type.  See PR58041.  */
    1982        19221 :   get_object_alignment_1 (*expr, &align, &misalign);
    1983        19221 :   if (misalign != 0)
    1984          268 :     align = least_bit_hwi (misalign);
    1985        19221 :   if (align < TYPE_ALIGN (acc_type))
    1986          240 :     acc_type = build_aligned_type (acc_type, align);
    1987              : 
    1988        19221 :   add_expr = fold_build2 (POINTER_PLUS_EXPR, c->cand_type,
    1989              :                           c->base_expr, c->stride);
    1990        19221 :   mem_ref = fold_build2 (MEM_REF, acc_type, add_expr,
    1991              :                          wide_int_to_tree (c->cand_type, c->index));
    1992              : 
    1993              :   /* Gimplify the base addressing expression for the new MEM_REF tree.  */
    1994        19221 :   gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
    1995        19221 :   TREE_OPERAND (mem_ref, 0)
    1996        19221 :     = force_gimple_operand_gsi (&gsi, TREE_OPERAND (mem_ref, 0),
    1997              :                                 /*simple_p=*/true, NULL,
    1998              :                                 /*before=*/true, GSI_SAME_STMT);
    1999        19221 :   copy_ref_info (mem_ref, *expr);
    2000        19221 :   *expr = mem_ref;
    2001        19221 :   update_stmt (c->cand_stmt);
    2002        19221 : }
    2003              : 
    2004              : /* Return true if CAND_REF candidate C is a valid memory reference.  */
    2005              : 
    2006              : static bool
    2007         8380 : valid_mem_ref_cand_p (slsr_cand_t c)
    2008              : {
    2009         8380 :   if (TREE_CODE (TREE_OPERAND (c->stride, 1)) != INTEGER_CST)
    2010              :     return false;
    2011              : 
    2012         8380 :   struct mem_address addr
    2013        16760 :     = { NULL_TREE, c->base_expr, TREE_OPERAND (c->stride, 0),
    2014         8380 :         TREE_OPERAND (c->stride, 1), wide_int_to_tree (sizetype, c->index) };
    2015              : 
    2016         8380 :   return
    2017         8380 :     valid_mem_ref_p (TYPE_MODE (c->cand_type), TYPE_ADDR_SPACE (c->cand_type),
    2018              :                      &addr);
    2019              : }
    2020              : 
    2021              : /* Replace CAND_REF candidate C, each sibling of candidate C, and each
    2022              :    dependent of candidate C with an equivalent strength-reduced data
    2023              :    reference.  */
    2024              : 
    2025              : static void
    2026         8388 : replace_refs (slsr_cand_t c)
    2027              : {
    2028              :   /* Replacing a chain of only 2 candidates which are valid memory references
    2029              :      is generally counter-productive because you cannot recoup the additional
    2030              :      calculation added in front of them.  */
    2031        23054 :   if (c->basis == 0
    2032         7906 :       && c->dependent
    2033         7906 :       && !lookup_cand (c->dependent)->dependent
    2034         4547 :       && valid_mem_ref_cand_p (c)
    2035        26887 :       && valid_mem_ref_cand_p (lookup_cand (c->dependent)))
    2036              :     return;
    2037              : 
    2038        19221 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2039              :     {
    2040            9 :       fputs ("Replacing reference: ", dump_file);
    2041            9 :       print_gimple_stmt (dump_file, c->cand_stmt, 0);
    2042              :     }
    2043              : 
    2044        38442 :   if (gimple_vdef (c->cand_stmt))
    2045              :     {
    2046         6786 :       tree *lhs = gimple_assign_lhs_ptr (c->cand_stmt);
    2047         6786 :       replace_ref (lhs, c);
    2048              :     }
    2049              :   else
    2050              :     {
    2051        12435 :       tree *rhs = gimple_assign_rhs1_ptr (c->cand_stmt);
    2052        12435 :       replace_ref (rhs, c);
    2053              :     }
    2054              : 
    2055        19221 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2056              :     {
    2057            9 :       fputs ("With: ", dump_file);
    2058            9 :       print_gimple_stmt (dump_file, c->cand_stmt, 0);
    2059            9 :       fputs ("\n", dump_file);
    2060              :     }
    2061              : 
    2062        19221 :   if (c->sibling)
    2063          482 :     replace_refs (lookup_cand (c->sibling));
    2064              : 
    2065        19221 :   if (c->dependent)
    2066        14666 :     replace_refs (lookup_cand (c->dependent));
    2067              : }
    2068              : 
    2069              : /* Return TRUE if candidate C is dependent upon a PHI.  */
    2070              : 
    2071              : static bool
    2072      2679513 : phi_dependent_cand_p (slsr_cand_t c)
    2073              : {
    2074              :   /* A candidate is not necessarily dependent upon a PHI just because
    2075              :      it has a phi definition for its base name.  It may have a basis
    2076              :      that relies upon the same phi definition, in which case the PHI
    2077              :      is irrelevant to this candidate.  */
    2078      2679513 :   return (c->def_phi
    2079          399 :           && c->basis
    2080      2679910 :           && lookup_cand (c->basis)->def_phi != c->def_phi);
    2081              : }
    2082              : 
    2083              : /* Calculate the increment required for candidate C relative to
    2084              :    its basis.  */
    2085              : 
    2086              : static offset_int
    2087      1394967 : cand_increment (slsr_cand_t c)
    2088              : {
    2089      1394967 :   slsr_cand_t basis;
    2090              : 
    2091              :   /* If the candidate doesn't have a basis, just return its own
    2092              :      index.  This is useful in record_increments to help us find
    2093              :      an existing initializer.  Also, if the candidate's basis is
    2094              :      hidden by a phi, then its own index will be the increment
    2095              :      from the newly introduced phi basis.  */
    2096      1394967 :   if (!c->basis || phi_dependent_cand_p (c))
    2097        36391 :     return c->index;
    2098              : 
    2099      1358576 :   basis = lookup_cand (c->basis);
    2100      1358576 :   gcc_assert (operand_equal_p (c->base_expr, basis->base_expr, 0));
    2101      1358576 :   return c->index - basis->index;
    2102              : }
    2103              : 
    2104              : /* Calculate the increment required for candidate C relative to
    2105              :    its basis.  If we aren't going to generate pointer arithmetic
    2106              :    for this candidate, return the absolute value of that increment
    2107              :    instead.  */
    2108              : 
    2109              : static inline offset_int
    2110        75866 : cand_abs_increment (slsr_cand_t c)
    2111              : {
    2112        75866 :   offset_int increment = cand_increment (c);
    2113              : 
    2114        75866 :   if (!address_arithmetic_p && wi::neg_p (increment))
    2115         2324 :     increment = -increment;
    2116              : 
    2117        75866 :   return increment;
    2118              : }
    2119              : 
    2120              : /* Return TRUE iff candidate C has already been replaced under
    2121              :    another interpretation.  */
    2122              : 
    2123              : static inline bool
    2124      1517999 : cand_already_replaced (slsr_cand_t c)
    2125              : {
    2126          673 :   return (gimple_bb (c->cand_stmt) == 0);
    2127              : }
    2128              : 
    2129              : /* Common logic used by replace_unconditional_candidate and
    2130              :    replace_conditional_candidate.  */
    2131              : 
    2132              : static void
    2133      1193850 : replace_mult_candidate (slsr_cand_t c, tree basis_name, offset_int bump,
    2134              :                         auto_bitmap &sdce_worklist)
    2135              : {
    2136      1193850 :   tree target_type = TREE_TYPE (gimple_assign_lhs (c->cand_stmt));
    2137      1193850 :   enum tree_code cand_code = gimple_assign_rhs_code (c->cand_stmt);
    2138              : 
    2139              :   /* It is not useful to replace casts, copies, negates, or adds of
    2140              :      an SSA name and a constant.  */
    2141      1193850 :   if (cand_code == SSA_NAME
    2142              :       || CONVERT_EXPR_CODE_P (cand_code)
    2143              :       || cand_code == PLUS_EXPR
    2144              :       || cand_code == POINTER_PLUS_EXPR
    2145              :       || cand_code == MINUS_EXPR
    2146              :       || cand_code == NEGATE_EXPR)
    2147              :     return;
    2148              : 
    2149        85067 :   enum tree_code code = PLUS_EXPR;
    2150        85067 :   tree bump_tree;
    2151        85067 :   gimple *stmt_to_print = NULL;
    2152              : 
    2153        85067 :   if (wi::neg_p (bump))
    2154              :     {
    2155         7043 :       code = MINUS_EXPR;
    2156         7043 :       bump = -bump;
    2157              :     }
    2158              : 
    2159              :   /* It is possible that the resulting bump doesn't fit in target_type.
    2160              :      Abandon the replacement in this case.  This does not affect
    2161              :      siblings or dependents of C.  */
    2162        85067 :   if (bump != wi::ext (bump, TYPE_PRECISION (target_type),
    2163        85067 :                        TYPE_SIGN (target_type)))
    2164              :     return;
    2165              : 
    2166        84138 :   bump_tree = wide_int_to_tree (target_type, bump);
    2167              : 
    2168              :   /* If the basis name and the candidate's LHS have incompatible types,
    2169              :      introduce a cast.  */
    2170        84138 :   if (!useless_type_conversion_p (target_type, TREE_TYPE (basis_name)))
    2171         4751 :     basis_name = introduce_cast_before_cand (c, target_type, basis_name);
    2172              : 
    2173        84138 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2174              :     {
    2175            0 :       fputs ("Replacing: ", dump_file);
    2176            0 :       print_gimple_stmt (dump_file, c->cand_stmt, 0);
    2177              :     }
    2178              : 
    2179        84138 :   if (bump == 0)
    2180              :     {
    2181        62946 :       tree lhs = gimple_assign_lhs (c->cand_stmt);
    2182        62946 :       gassign *copy_stmt = gimple_build_assign (lhs, basis_name);
    2183        62946 :       gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
    2184        62946 :       slsr_cand_t cc = lookup_cand (c->first_interp);
    2185        62946 :       gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
    2186        62946 :       gsi_replace (&gsi, copy_stmt, false);
    2187       188838 :       while (cc)
    2188              :         {
    2189        62946 :           cc->cand_stmt = copy_stmt;
    2190        62946 :           cc = lookup_cand (cc->next_interp);
    2191              :         }
    2192        62946 :       if (dump_file && (dump_flags & TDF_DETAILS))
    2193              :         stmt_to_print = copy_stmt;
    2194              :     }
    2195              :   else
    2196              :     {
    2197        21192 :       tree rhs1, rhs2;
    2198        21192 :       if (cand_code != NEGATE_EXPR) {
    2199        21192 :         rhs1 = gimple_assign_rhs1 (c->cand_stmt);
    2200        21192 :         rhs2 = gimple_assign_rhs2 (c->cand_stmt);
    2201              :         /* Mark the 2 original rhs for maybe DCEing.  */
    2202        21192 :         if (TREE_CODE (rhs1) == SSA_NAME)
    2203        21192 :           bitmap_set_bit (sdce_worklist, SSA_NAME_VERSION (rhs1));
    2204        21192 :         if (TREE_CODE (rhs2) == SSA_NAME)
    2205            0 :           bitmap_set_bit (sdce_worklist, SSA_NAME_VERSION (rhs2));
    2206              :       }
    2207        21192 :       if (cand_code != NEGATE_EXPR
    2208        21192 :           && ((operand_equal_p (rhs1, basis_name, 0)
    2209            0 :                && operand_equal_p (rhs2, bump_tree, 0))
    2210        21192 :               || (operand_equal_p (rhs1, bump_tree, 0)
    2211            0 :                   && operand_equal_p (rhs2, basis_name, 0))))
    2212              :         {
    2213            0 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2214              :             {
    2215            0 :               fputs ("(duplicate, not actually replacing)", dump_file);
    2216            0 :               stmt_to_print = c->cand_stmt;
    2217              :             }
    2218              :         }
    2219              :       else
    2220              :         {
    2221        21192 :           gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
    2222        21192 :           slsr_cand_t cc = lookup_cand (c->first_interp);
    2223        21192 :           tree lhs = gimple_assign_lhs (c->cand_stmt);
    2224        21192 :           basis_name = gimple_convert (&gsi, true, GSI_SAME_STMT,
    2225              :                                        UNKNOWN_LOCATION,
    2226        21192 :                                        TREE_TYPE (lhs), basis_name);
    2227        21192 :           bump_tree = gimple_convert (&gsi, true, GSI_SAME_STMT,
    2228              :                                       UNKNOWN_LOCATION,
    2229        21192 :                                       TREE_TYPE (lhs), bump_tree);
    2230        21192 :           gimple_assign_set_rhs_with_ops (&gsi, code, basis_name, bump_tree);
    2231        21192 :           update_stmt (gsi_stmt (gsi));
    2232        63576 :           while (cc)
    2233              :             {
    2234        21192 :               cc->cand_stmt = gsi_stmt (gsi);
    2235        21192 :               cc = lookup_cand (cc->next_interp);
    2236              :             }
    2237        21192 :           if (gimple_needing_rewrite_undefined (gsi_stmt (gsi)))
    2238         7797 :             rewrite_to_defined_unconditional (&gsi);
    2239              : 
    2240        21192 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2241            0 :             stmt_to_print = gsi_stmt (gsi);
    2242              :         }
    2243              :     }
    2244              : 
    2245        84138 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2246              :     {
    2247            0 :       fputs ("With: ", dump_file);
    2248            0 :       print_gimple_stmt (dump_file, stmt_to_print, 0);
    2249            0 :       fputs ("\n", dump_file);
    2250              :     }
    2251              : }
    2252              : 
    2253              : /* Replace candidate C with an add or subtract.   Note that we only
    2254              :    operate on CAND_MULTs with known strides, so we will never generate
    2255              :    a POINTER_PLUS_EXPR.  Each candidate X = (B + i) * S is replaced by
    2256              :    X = Y + ((i - i') * S), as described in the module commentary.  The
    2257              :    folded value ((i - i') * S) is referred to here as the "bump."  */
    2258              : 
    2259              : static void
    2260      1193841 : replace_unconditional_candidate (slsr_cand_t c, auto_bitmap &sdce_worklist)
    2261              : {
    2262      1193841 :   slsr_cand_t basis;
    2263              : 
    2264      1193841 :   if (cand_already_replaced (c))
    2265            0 :     return;
    2266              : 
    2267      1193841 :   basis = lookup_cand (c->basis);
    2268      1193841 :   offset_int bump = cand_increment (c) * wi::to_offset (c->stride);
    2269              : 
    2270      1193841 :   replace_mult_candidate (c, gimple_assign_lhs (basis->cand_stmt), bump,
    2271              :                           sdce_worklist);
    2272              : }
    2273              : 
    2274              : /* Return the index in the increment vector of the given INCREMENT,
    2275              :    or -1 if not found.  The latter can occur if more than
    2276              :    MAX_INCR_VEC_LEN increments have been found.  */
    2277              : 
    2278              : static inline int
    2279        70075 : incr_vec_index (const offset_int &increment)
    2280              : {
    2281        70075 :   unsigned i;
    2282              : 
    2283       126012 :   for (i = 0; i < incr_vec_len && increment != incr_vec[i].incr; i++)
    2284              :     ;
    2285              : 
    2286        70075 :   if (i < incr_vec_len)
    2287              :     return i;
    2288              :   else
    2289            0 :     return -1;
    2290              : }
    2291              : 
    2292              : /* Create a new statement along edge E to add BASIS_NAME to the product
    2293              :    of INCREMENT and the stride of candidate C.  Create and return a new
    2294              :    SSA name from *VAR to be used as the LHS of the new statement.
    2295              :    KNOWN_STRIDE is true iff C's stride is a constant.  */
    2296              : 
    2297              : static tree
    2298           25 : create_add_on_incoming_edge (slsr_cand_t c, tree basis_name,
    2299              :                              offset_int increment, edge e, location_t loc,
    2300              :                              bool known_stride)
    2301              : {
    2302           25 :   tree lhs, basis_type;
    2303           25 :   gassign *new_stmt, *cast_stmt = NULL;
    2304              : 
    2305              :   /* If the add candidate along this incoming edge has the same
    2306              :      index as C's hidden basis, the hidden basis represents this
    2307              :      edge correctly.  */
    2308           25 :   if (increment == 0)
    2309              :     return basis_name;
    2310              : 
    2311           21 :   basis_type = TREE_TYPE (basis_name);
    2312           21 :   lhs = make_temp_ssa_name (basis_type, NULL, "slsr");
    2313              : 
    2314              :   /* Occasionally people convert integers to pointers without a
    2315              :      cast, leading us into trouble if we aren't careful.  */
    2316           21 :   enum tree_code plus_code
    2317           21 :     = POINTER_TYPE_P (basis_type) ? POINTER_PLUS_EXPR : PLUS_EXPR;
    2318              : 
    2319           21 :   if (known_stride)
    2320              :     {
    2321           13 :       tree bump_tree;
    2322           13 :       enum tree_code code = plus_code;
    2323           13 :       offset_int bump = increment * wi::to_offset (c->stride);
    2324           13 :       if (wi::neg_p (bump) && !POINTER_TYPE_P (basis_type))
    2325              :         {
    2326            5 :           code = MINUS_EXPR;
    2327            5 :           bump = -bump;
    2328              :         }
    2329              : 
    2330           13 :       tree stride_type = POINTER_TYPE_P (basis_type) ? sizetype : basis_type;
    2331           13 :       bump_tree = wide_int_to_tree (stride_type, bump);
    2332           13 :       new_stmt = gimple_build_assign (lhs, code, basis_name, bump_tree);
    2333              :     }
    2334              :   else
    2335              :     {
    2336            8 :       int i;
    2337            8 :       bool negate_incr = !POINTER_TYPE_P (basis_type) && wi::neg_p (increment);
    2338            8 :       i = incr_vec_index (negate_incr ? -increment : increment);
    2339            8 :       gcc_assert (i >= 0);
    2340              : 
    2341            8 :       if (incr_vec[i].initializer)
    2342              :         {
    2343            8 :           tree init = incr_vec[i].initializer;
    2344            8 :           tree wanted_type = POINTER_TYPE_P (basis_type) ? c->stride_type : basis_type;
    2345              : 
    2346            8 :           if (!types_compatible_p (TREE_TYPE (c->stride), wanted_type))
    2347              :             {
    2348            2 :               tree cast_stride = make_temp_ssa_name (wanted_type, NULL,
    2349              :                                                      "slsr");
    2350            2 :               cast_stmt = gimple_build_assign (cast_stride, NOP_EXPR,
    2351              :                                                init);
    2352            2 :               init = cast_stride;
    2353              :             }
    2354            8 :           enum tree_code code = negate_incr ? MINUS_EXPR : plus_code;
    2355            8 :           new_stmt = gimple_build_assign (lhs, code, basis_name, init);
    2356              :         }
    2357              :       else {
    2358            0 :         tree stride;
    2359            0 :         tree wanted_type = POINTER_TYPE_P (basis_type) ? c->stride_type : basis_type;
    2360              : 
    2361            0 :         if (!types_compatible_p (TREE_TYPE (c->stride), wanted_type))
    2362              :           {
    2363            0 :             tree cast_stride = make_temp_ssa_name (wanted_type, NULL,
    2364              :                                                    "slsr");
    2365            0 :             cast_stmt = gimple_build_assign (cast_stride, NOP_EXPR,
    2366              :                                              c->stride);
    2367            0 :             stride = cast_stride;
    2368              :           }
    2369              :         else
    2370            0 :           stride = c->stride;
    2371              : 
    2372            0 :         if (increment == 1)
    2373            0 :           new_stmt = gimple_build_assign (lhs, plus_code, basis_name, stride);
    2374            0 :         else if (increment == -1)
    2375            0 :           new_stmt = gimple_build_assign (lhs, MINUS_EXPR, basis_name, stride);
    2376              :         else
    2377            0 :           gcc_unreachable ();
    2378              :       }
    2379              :     }
    2380              : 
    2381           21 :   if (cast_stmt)
    2382              :     {
    2383            2 :       gimple_set_location (cast_stmt, loc);
    2384            2 :       gsi_insert_on_edge (e, cast_stmt);
    2385              :     }
    2386              : 
    2387           21 :   gimple_set_location (new_stmt, loc);
    2388           21 :   if (gimple_needing_rewrite_undefined (new_stmt))
    2389              :     {
    2390            3 :       gimple_seq stmts;
    2391            3 :       stmts = rewrite_to_defined_unconditional (new_stmt);
    2392            3 :       gsi_insert_seq_on_edge (e, stmts);
    2393              :     }
    2394              :   else
    2395           18 :     gsi_insert_on_edge (e, new_stmt);
    2396              : 
    2397           21 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2398              :     {
    2399            0 :       if (cast_stmt)
    2400              :         {
    2401            0 :           fprintf (dump_file, "Inserting cast on edge %d->%d: ",
    2402            0 :                    e->src->index, e->dest->index);
    2403            0 :           print_gimple_stmt (dump_file, cast_stmt, 0);
    2404              :         }
    2405            0 :       fprintf (dump_file, "Inserting on edge %d->%d: ", e->src->index,
    2406            0 :                e->dest->index);
    2407            0 :       print_gimple_stmt (dump_file, new_stmt, 0);
    2408              :     }
    2409              : 
    2410              :   return lhs;
    2411              : }
    2412              : 
    2413              : /* Clear the visited field for a tree of PHI candidates.  */
    2414              : 
    2415              : static void
    2416           80 : clear_visited (gphi *phi)
    2417              : {
    2418           80 :   unsigned i;
    2419           80 :   slsr_cand_t phi_cand = *stmt_cand_map->get (phi);
    2420              : 
    2421           80 :   if (phi_cand->visited)
    2422              :     {
    2423           80 :       phi_cand->visited = 0;
    2424              : 
    2425          242 :       for (i = 0; i < gimple_phi_num_args (phi); i++)
    2426              :         {
    2427          162 :           tree arg = gimple_phi_arg_def (phi, i);
    2428          162 :           gimple *arg_def = SSA_NAME_DEF_STMT (arg);
    2429          162 :           if (gimple_code (arg_def) == GIMPLE_PHI)
    2430            2 :             clear_visited (as_a <gphi *> (arg_def));
    2431              :         }
    2432              :     }
    2433           80 : }
    2434              : 
    2435              : /* Recursive helper function for create_phi_basis.  */
    2436              : 
    2437              : static tree
    2438           18 : create_phi_basis_1 (slsr_cand_t c, gimple *from_phi, tree basis_name,
    2439              :                     location_t loc, bool known_stride)
    2440              : {
    2441           18 :   int i;
    2442           18 :   tree name, phi_arg;
    2443           18 :   gphi *phi;
    2444           18 :   slsr_cand_t basis = lookup_cand (c->basis);
    2445           18 :   int nargs = gimple_phi_num_args (from_phi);
    2446           18 :   basic_block phi_bb = gimple_bb (from_phi);
    2447           18 :   slsr_cand_t phi_cand = *stmt_cand_map->get (from_phi);
    2448           18 :   auto_vec<tree> phi_args (nargs);
    2449              : 
    2450           18 :   if (phi_cand->visited)
    2451            0 :     return phi_cand->cached_basis;
    2452           18 :   phi_cand->visited = 1;
    2453              : 
    2454              :   /* Process each argument of the existing phi that represents
    2455              :      conditionally-executed add candidates.  */
    2456           51 :   for (i = 0; i < nargs; i++)
    2457              :     {
    2458           33 :       edge e = (*phi_bb->preds)[i];
    2459           33 :       tree arg = gimple_phi_arg_def (from_phi, i);
    2460           33 :       tree feeding_def;
    2461              : 
    2462              :       /* If the phi argument is the base name of the CAND_PHI, then
    2463              :          this incoming arc should use the hidden basis.  */
    2464           33 :       if (operand_equal_p (arg, phi_cand->base_expr, 0))
    2465            7 :         if (basis->index == 0)
    2466            7 :           feeding_def = gimple_assign_lhs (basis->cand_stmt);
    2467              :         else
    2468              :           {
    2469            0 :             offset_int incr = -basis->index;
    2470            0 :             feeding_def = create_add_on_incoming_edge (c, basis_name, incr,
    2471              :                                                        e, loc, known_stride);
    2472              :           }
    2473              :       else
    2474              :         {
    2475           26 :           gimple *arg_def = SSA_NAME_DEF_STMT (arg);
    2476              : 
    2477              :           /* If there is another phi along this incoming edge, we must
    2478              :              process it in the same fashion to ensure that all basis
    2479              :              adjustments are made along its incoming edges.  */
    2480           26 :           if (gimple_code (arg_def) == GIMPLE_PHI)
    2481            1 :             feeding_def = create_phi_basis_1 (c, arg_def, basis_name,
    2482              :                                               loc, known_stride);
    2483              :           else
    2484              :             {
    2485           25 :               slsr_cand_t arg_cand = base_cand_from_table (arg);
    2486           25 :               offset_int diff = arg_cand->index - basis->index;
    2487           25 :               feeding_def = create_add_on_incoming_edge (c, basis_name, diff,
    2488              :                                                          e, loc, known_stride);
    2489              :             }
    2490              :         }
    2491              : 
    2492              :       /* Because of recursion, we need to save the arguments in a vector
    2493              :          so we can create the PHI statement all at once.  Otherwise the
    2494              :          storage for the half-created PHI can be reclaimed.  */
    2495           33 :       phi_args.safe_push (feeding_def);
    2496              :     }
    2497              : 
    2498              :   /* Create the new phi basis.  */
    2499           18 :   name = make_temp_ssa_name (TREE_TYPE (basis_name), NULL, "slsr");
    2500           18 :   phi = create_phi_node (name, phi_bb);
    2501           18 :   SSA_NAME_DEF_STMT (name) = phi;
    2502              : 
    2503           51 :   FOR_EACH_VEC_ELT (phi_args, i, phi_arg)
    2504              :     {
    2505           33 :       edge e = (*phi_bb->preds)[i];
    2506           33 :       add_phi_arg (phi, phi_arg, e, loc);
    2507              :     }
    2508              : 
    2509           18 :   update_stmt (phi);
    2510              : 
    2511           18 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2512              :     {
    2513            0 :       fputs ("Introducing new phi basis: ", dump_file);
    2514            0 :       print_gimple_stmt (dump_file, phi, 0);
    2515              :     }
    2516              : 
    2517           18 :   phi_cand->cached_basis = name;
    2518           18 :   return name;
    2519           18 : }
    2520              : 
    2521              : /* Given a candidate C with BASIS_NAME being the LHS of C's basis which
    2522              :    is hidden by the phi node FROM_PHI, create a new phi node in the same
    2523              :    block as FROM_PHI.  The new phi is suitable for use as a basis by C,
    2524              :    with its phi arguments representing conditional adjustments to the
    2525              :    hidden basis along conditional incoming paths.  Those adjustments are
    2526              :    made by creating add statements (and sometimes recursively creating
    2527              :    phis) along those incoming paths.  LOC is the location to attach to
    2528              :    the introduced statements.  KNOWN_STRIDE is true iff C's stride is a
    2529              :    constant.  */
    2530              : 
    2531              : static tree
    2532           17 : create_phi_basis (slsr_cand_t c, gimple *from_phi, tree basis_name,
    2533              :                   location_t loc, bool known_stride)
    2534              : {
    2535           17 :   tree retval = create_phi_basis_1 (c, from_phi, basis_name, loc,
    2536              :                                     known_stride);
    2537           17 :   gcc_assert (retval);
    2538           17 :   clear_visited (as_a <gphi *> (from_phi));
    2539           17 :   return retval;
    2540              : }
    2541              : 
    2542              : /* Given a candidate C whose basis is hidden by at least one intervening
    2543              :    phi, introduce a matching number of new phis to represent its basis
    2544              :    adjusted by conditional increments along possible incoming paths.  Then
    2545              :    replace C as though it were an unconditional candidate, using the new
    2546              :    basis.  */
    2547              : 
    2548              : static void
    2549            9 : replace_conditional_candidate (slsr_cand_t c, auto_bitmap &sdce_worklist)
    2550              : 
    2551              : {
    2552            9 :   tree basis_name, name;
    2553            9 :   slsr_cand_t basis;
    2554            9 :   location_t loc;
    2555              : 
    2556              :   /* Look up the LHS SSA name from C's basis.  This will be the
    2557              :      RHS1 of the adds we will introduce to create new phi arguments.  */
    2558            9 :   basis = lookup_cand (c->basis);
    2559            9 :   basis_name = gimple_assign_lhs (basis->cand_stmt);
    2560              : 
    2561              :   /* Create a new phi statement which will represent C's true basis
    2562              :      after the transformation is complete.  */
    2563            9 :   loc = gimple_location (c->cand_stmt);
    2564            9 :   name = create_phi_basis (c, lookup_cand (c->def_phi)->cand_stmt,
    2565              :                            basis_name, loc, KNOWN_STRIDE);
    2566              : 
    2567              :   /* Replace C with an add of the new basis phi and a constant.  */
    2568            9 :   offset_int bump = c->index * wi::to_offset (c->stride);
    2569              : 
    2570            9 :   replace_mult_candidate (c, name, bump, sdce_worklist);
    2571            9 : }
    2572              : 
    2573              : /* Recursive helper function for phi_add_costs.  SPREAD is a measure of
    2574              :    how many PHI nodes we have visited at this point in the tree walk.  */
    2575              : 
    2576              : static int
    2577           23 : phi_add_costs_1 (gimple *phi, slsr_cand_t c, int one_add_cost, int *spread)
    2578              : {
    2579           23 :   unsigned i;
    2580           23 :   int cost = 0;
    2581           23 :   slsr_cand_t phi_cand = *stmt_cand_map->get (phi);
    2582              : 
    2583           23 :   if (phi_cand->visited)
    2584              :     return 0;
    2585              : 
    2586           23 :   phi_cand->visited = 1;
    2587           23 :   (*spread)++;
    2588              : 
    2589              :   /* If we work our way back to a phi that isn't dominated by the hidden
    2590              :      basis, this isn't a candidate for replacement.  Indicate this by
    2591              :      returning an unreasonably high cost.  It's not easy to detect
    2592              :      these situations when determining the basis, so we defer the
    2593              :      decision until now.  */
    2594           23 :   basic_block phi_bb = gimple_bb (phi);
    2595           23 :   slsr_cand_t basis = lookup_cand (c->basis);
    2596           23 :   basic_block basis_bb = gimple_bb (basis->cand_stmt);
    2597              : 
    2598           23 :   if (phi_bb == basis_bb || !dominated_by_p (CDI_DOMINATORS, phi_bb, basis_bb))
    2599            0 :     return COST_INFINITE;
    2600              : 
    2601           74 :   for (i = 0; i < gimple_phi_num_args (phi); i++)
    2602              :     {
    2603           51 :       tree arg = gimple_phi_arg_def (phi, i);
    2604              : 
    2605           51 :       if (arg != phi_cand->base_expr)
    2606              :         {
    2607           50 :           gimple *arg_def = SSA_NAME_DEF_STMT (arg);
    2608              : 
    2609           50 :           if (gimple_code (arg_def) == GIMPLE_PHI)
    2610              :             {
    2611            1 :               cost += phi_add_costs_1 (arg_def, c, one_add_cost, spread);
    2612              : 
    2613            1 :               if (cost >= COST_INFINITE || *spread > MAX_SPREAD)
    2614              :                 return COST_INFINITE;
    2615              :             }
    2616              :           else
    2617              :             {
    2618           49 :               slsr_cand_t arg_cand = base_cand_from_table (arg);
    2619              : 
    2620           49 :               if (arg_cand->index != c->index)
    2621           46 :                 cost += one_add_cost;
    2622              :             }
    2623              :         }
    2624              :     }
    2625              : 
    2626              :   return cost;
    2627              : }
    2628              : 
    2629              : /* Compute the expected costs of inserting basis adjustments for
    2630              :    candidate C with phi-definition PHI.  The cost of inserting
    2631              :    one adjustment is given by ONE_ADD_COST.  If PHI has arguments
    2632              :    which are themselves phi results, recursively calculate costs
    2633              :    for those phis as well.  */
    2634              : 
    2635              : static int
    2636           22 : phi_add_costs (gimple *phi, slsr_cand_t c, int one_add_cost)
    2637              : {
    2638           22 :   int spread = 0;
    2639           22 :   int retval = phi_add_costs_1 (phi, c, one_add_cost, &spread);
    2640           22 :   clear_visited (as_a <gphi *> (phi));
    2641           22 :   return retval;
    2642              : }
    2643              : /* For candidate C, each sibling of candidate C, and each dependent of
    2644              :    candidate C, determine whether the candidate is dependent upon a
    2645              :    phi that hides its basis.  If not, replace the candidate unconditionally.
    2646              :    Otherwise, determine whether the cost of introducing compensation code
    2647              :    for the candidate is offset by the gains from strength reduction.  If
    2648              :    so, replace the candidate and introduce the compensation code.  */
    2649              : 
    2650              : static void
    2651       622796 : replace_uncond_cands_and_profitable_phis (slsr_cand_t c,
    2652              :                                           auto_bitmap &sdce_worklist)
    2653              : {
    2654      1193892 :   if (phi_dependent_cand_p (c))
    2655              :     {
    2656              :       /* A multiply candidate with a stride of 1 is just an artifice
    2657              :          of a copy or cast; there is no value in replacing it.  */
    2658           51 :       if (c->kind == CAND_MULT && wi::to_offset (c->stride) != 1)
    2659              :         {
    2660              :           /* A candidate dependent upon a phi will replace a multiply by
    2661              :              a constant with an add, and will insert at most one add for
    2662              :              each phi argument.  Add these costs with the potential dead-code
    2663              :              savings to determine profitability.  */
    2664           22 :           bool speed = optimize_bb_for_speed_p (gimple_bb (c->cand_stmt));
    2665           22 :           int mult_savings = stmt_cost (c->cand_stmt, speed);
    2666           22 :           gimple *phi = lookup_cand (c->def_phi)->cand_stmt;
    2667           22 :           tree phi_result = gimple_phi_result (phi);
    2668           88 :           int one_add_cost = add_cost (speed,
    2669           22 :                                        TYPE_MODE (TREE_TYPE (phi_result)));
    2670           22 :           int add_costs = one_add_cost + phi_add_costs (phi, c, one_add_cost);
    2671           22 :           int cost = add_costs - mult_savings - c->dead_savings;
    2672              : 
    2673           22 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2674              :             {
    2675            0 :               fprintf (dump_file, "  Conditional candidate %d:\n", c->cand_num);
    2676            0 :               fprintf (dump_file, "    add_costs = %d\n", add_costs);
    2677            0 :               fprintf (dump_file, "    mult_savings = %d\n", mult_savings);
    2678            0 :               fprintf (dump_file, "    dead_savings = %d\n", c->dead_savings);
    2679            0 :               fprintf (dump_file, "    cost = %d\n", cost);
    2680            0 :               if (cost <= COST_NEUTRAL)
    2681            0 :                 fputs ("  Replacing...\n", dump_file);
    2682              :               else
    2683            0 :                 fputs ("  Not replaced.\n", dump_file);
    2684              :             }
    2685              : 
    2686           22 :           if (cost <= COST_NEUTRAL)
    2687            9 :             replace_conditional_candidate (c, sdce_worklist);
    2688              :         }
    2689              :     }
    2690              :   else
    2691      1193841 :     replace_unconditional_candidate (c, sdce_worklist);
    2692              : 
    2693      1193892 :   if (c->sibling)
    2694        45585 :     replace_uncond_cands_and_profitable_phis (lookup_cand (c->sibling),
    2695              :                                               sdce_worklist);
    2696              : 
    2697      1193892 :   if (c->dependent)
    2698       571096 :     replace_uncond_cands_and_profitable_phis (lookup_cand (c->dependent),
    2699              :                                               sdce_worklist);
    2700       622796 : }
    2701              : 
    2702              : /* Count the number of candidates in the tree rooted at C that have
    2703              :    not already been replaced under other interpretations.  */
    2704              : 
    2705              : static int
    2706        39581 : count_candidates (slsr_cand_t c)
    2707              : {
    2708       106394 :   unsigned count = cand_already_replaced (c) ? 0 : 1;
    2709              : 
    2710       106394 :   if (c->sibling)
    2711         3233 :     count += count_candidates (lookup_cand (c->sibling));
    2712              : 
    2713       106394 :   if (c->dependent)
    2714        66813 :     count += count_candidates (lookup_cand (c->dependent));
    2715              : 
    2716        39581 :   return count;
    2717              : }
    2718              : 
    2719              : /* Increase the count of INCREMENT by one in the increment vector.
    2720              :    INCREMENT is associated with candidate C.  If INCREMENT is to be
    2721              :    conditionally executed as part of a conditional candidate replacement,
    2722              :    IS_PHI_ADJUST is true, otherwise false.  If an initializer
    2723              :    T_0 = stride * I is provided by a candidate that dominates all
    2724              :    candidates with the same increment, also record T_0 for subsequent use.  */
    2725              : 
    2726              : static void
    2727       106418 : record_increment (slsr_cand_t c, offset_int increment, bool is_phi_adjust)
    2728              : {
    2729       106418 :   bool found = false;
    2730       106418 :   unsigned i;
    2731              : 
    2732              :   /* Treat increments that differ only in sign as identical so as to
    2733              :      share initializers, unless we are generating pointer arithmetic.  */
    2734       106418 :   if (!address_arithmetic_p && wi::neg_p (increment))
    2735         6100 :     increment = -increment;
    2736              : 
    2737       162348 :   for (i = 0; i < incr_vec_len; i++)
    2738              :     {
    2739        96454 :       if (incr_vec[i].incr == increment)
    2740              :         {
    2741        40524 :           incr_vec[i].count++;
    2742        40524 :           found = true;
    2743              : 
    2744              :           /* If we previously recorded an initializer that doesn't
    2745              :              dominate this candidate, it's not going to be useful to
    2746              :              us after all.  */
    2747        40524 :           if (incr_vec[i].initializer
    2748        40524 :               && !dominated_by_p (CDI_DOMINATORS,
    2749          918 :                                   gimple_bb (c->cand_stmt),
    2750          918 :                                   incr_vec[i].init_bb))
    2751              :             {
    2752            0 :               incr_vec[i].initializer = NULL_TREE;
    2753            0 :               incr_vec[i].init_bb = NULL;
    2754              :             }
    2755              : 
    2756              :           break;
    2757              :         }
    2758              :     }
    2759              : 
    2760        65894 :   if (!found && incr_vec_len < MAX_INCR_VEC_LEN - 1)
    2761              :     {
    2762              :       /* The first time we see an increment, create the entry for it.
    2763              :          If this is the root candidate which doesn't have a basis, set
    2764              :          the count to zero.  We're only processing it so it can possibly
    2765              :          provide an initializer for other candidates.  */
    2766        65894 :       incr_vec[incr_vec_len].incr = increment;
    2767        65894 :       incr_vec[incr_vec_len].count = c->basis || is_phi_adjust ? 1 : 0;
    2768        65894 :       incr_vec[incr_vec_len].cost = COST_INFINITE;
    2769              : 
    2770              :       /* Optimistically record the first occurrence of this increment
    2771              :          as providing an initializer (if it does); we will revise this
    2772              :          opinion later if it doesn't dominate all other occurrences.
    2773              :          Exception:  increments of 0, 1 never need initializers;
    2774              :          and phi adjustments don't ever provide initializers.  */
    2775        65894 :       if (c->kind == CAND_ADD
    2776        55940 :           && !is_phi_adjust
    2777        55928 :           && c->index == increment
    2778        23815 :           && (increment > 1 || increment < 0)
    2779        71227 :           && (gimple_assign_rhs_code (c->cand_stmt) == PLUS_EXPR
    2780         3356 :               || gimple_assign_rhs_code (c->cand_stmt) == POINTER_PLUS_EXPR))
    2781              :         {
    2782         4007 :           tree t0 = NULL_TREE;
    2783         4007 :           tree rhs1 = gimple_assign_rhs1 (c->cand_stmt);
    2784         4007 :           tree rhs2 = gimple_assign_rhs2 (c->cand_stmt);
    2785         4007 :           if (operand_equal_p (rhs1, c->base_expr, 0))
    2786              :             t0 = rhs2;
    2787          707 :           else if (operand_equal_p (rhs2, c->base_expr, 0))
    2788              :             t0 = rhs1;
    2789         4001 :           if (t0
    2790         4001 :               && SSA_NAME_DEF_STMT (t0)
    2791         8002 :               && gimple_bb (SSA_NAME_DEF_STMT (t0)))
    2792              :             {
    2793         4001 :               incr_vec[incr_vec_len].initializer = t0;
    2794         4001 :               incr_vec[incr_vec_len++].init_bb
    2795         4001 :                 = gimple_bb (SSA_NAME_DEF_STMT (t0));
    2796              :             }
    2797              :           else
    2798              :             {
    2799            6 :               incr_vec[incr_vec_len].initializer = NULL_TREE;
    2800            6 :               incr_vec[incr_vec_len++].init_bb = NULL;
    2801              :             }
    2802              :         }
    2803              :       else
    2804              :         {
    2805        61887 :           incr_vec[incr_vec_len].initializer = NULL_TREE;
    2806        61887 :           incr_vec[incr_vec_len++].init_bb = NULL;
    2807              :         }
    2808              :     }
    2809       106418 : }
    2810              : 
    2811              : /* Recursive helper function for record_phi_increments.  */
    2812              : 
    2813              : static void
    2814           12 : record_phi_increments_1 (slsr_cand_t basis, gimple *phi)
    2815              : {
    2816           12 :   unsigned i;
    2817           12 :   slsr_cand_t phi_cand = *stmt_cand_map->get (phi);
    2818              : 
    2819           12 :   if (phi_cand->visited)
    2820              :     return;
    2821           12 :   phi_cand->visited = 1;
    2822              : 
    2823           36 :   for (i = 0; i < gimple_phi_num_args (phi); i++)
    2824              :     {
    2825           24 :       tree arg = gimple_phi_arg_def (phi, i);
    2826           24 :       gimple *arg_def = SSA_NAME_DEF_STMT (arg);
    2827              : 
    2828           24 :       if (gimple_code (arg_def) == GIMPLE_PHI)
    2829            0 :         record_phi_increments_1 (basis, arg_def);
    2830              :       else
    2831              :         {
    2832           24 :           offset_int diff;
    2833              : 
    2834           24 :           if (operand_equal_p (arg, phi_cand->base_expr, 0))
    2835              :             {
    2836            7 :               diff = -basis->index;
    2837            7 :               record_increment (phi_cand, diff, PHI_ADJUST);
    2838              :             }
    2839              :           else
    2840              :             {
    2841           17 :               slsr_cand_t arg_cand = base_cand_from_table (arg);
    2842           17 :               diff = arg_cand->index - basis->index;
    2843           17 :               record_increment (arg_cand, diff, PHI_ADJUST);
    2844              :             }
    2845              :         }
    2846              :     }
    2847              : }
    2848              : 
    2849              : /* Given phi statement PHI that hides a candidate from its BASIS, find
    2850              :    the increments along each incoming arc (recursively handling additional
    2851              :    phis that may be present) and record them.  These increments are the
    2852              :    difference in index between the index-adjusting statements and the
    2853              :    index of the basis.  */
    2854              : 
    2855              : static void
    2856           12 : record_phi_increments (slsr_cand_t basis, gimple *phi)
    2857              : {
    2858           12 :   record_phi_increments_1 (basis, phi);
    2859           12 :   clear_visited (as_a <gphi *> (phi));
    2860           12 : }
    2861              : 
    2862              : /* Determine how many times each unique increment occurs in the set
    2863              :    of candidates rooted at C's parent, recording the data in the
    2864              :    increment vector.  For each unique increment I, if an initializer
    2865              :    T_0 = stride * I is provided by a candidate that dominates all
    2866              :    candidates with the same increment, also record T_0 for subsequent
    2867              :    use.  */
    2868              : 
    2869              : static void
    2870        39581 : record_increments (slsr_cand_t c)
    2871              : {
    2872       106394 :   if (!cand_already_replaced (c))
    2873              :     {
    2874       106394 :       if (!phi_dependent_cand_p (c))
    2875       106382 :         record_increment (c, cand_increment (c), NOT_PHI_ADJUST);
    2876              :       else
    2877              :         {
    2878              :           /* A candidate with a basis hidden by a phi will have one
    2879              :              increment for its relationship to the index represented by
    2880              :              the phi, and potentially additional increments along each
    2881              :              incoming edge.  For the root of the dependency tree (which
    2882              :              has no basis), process just the initial index in case it has
    2883              :              an initializer that can be used by subsequent candidates.  */
    2884           12 :           record_increment (c, c->index, NOT_PHI_ADJUST);
    2885              : 
    2886           12 :           if (c->basis)
    2887           12 :             record_phi_increments (lookup_cand (c->basis),
    2888           12 :                                    lookup_cand (c->def_phi)->cand_stmt);
    2889              :         }
    2890              :     }
    2891              : 
    2892       106394 :   if (c->sibling)
    2893         3233 :     record_increments (lookup_cand (c->sibling));
    2894              : 
    2895       106394 :   if (c->dependent)
    2896        66813 :     record_increments (lookup_cand (c->dependent));
    2897        39581 : }
    2898              : 
    2899              : /* Recursive helper function for phi_incr_cost.  */
    2900              : 
    2901              : static int
    2902           15 : phi_incr_cost_1 (slsr_cand_t c, const offset_int &incr, gimple *phi,
    2903              :                  int *savings)
    2904              : {
    2905           15 :   unsigned i;
    2906           15 :   int cost = 0;
    2907           15 :   slsr_cand_t basis = lookup_cand (c->basis);
    2908           15 :   slsr_cand_t phi_cand = *stmt_cand_map->get (phi);
    2909              : 
    2910           15 :   if (phi_cand->visited)
    2911              :     return 0;
    2912           15 :   phi_cand->visited = 1;
    2913              : 
    2914           45 :   for (i = 0; i < gimple_phi_num_args (phi); i++)
    2915              :     {
    2916           30 :       tree arg = gimple_phi_arg_def (phi, i);
    2917           30 :       gimple *arg_def = SSA_NAME_DEF_STMT (arg);
    2918              : 
    2919           30 :       if (gimple_code (arg_def) == GIMPLE_PHI)
    2920              :         {
    2921            0 :           int feeding_savings = 0;
    2922            0 :           tree feeding_var = gimple_phi_result (arg_def);
    2923            0 :           cost += phi_incr_cost_1 (c, incr, arg_def, &feeding_savings);
    2924            0 :           if (uses_consumed_by_stmt (feeding_var, phi))
    2925            0 :             *savings += feeding_savings;
    2926              :         }
    2927              :       else
    2928              :         {
    2929           30 :           offset_int diff;
    2930           30 :           slsr_cand_t arg_cand;
    2931              : 
    2932              :           /* When the PHI argument is just a pass-through to the base
    2933              :              expression of the hidden basis, the difference is zero minus
    2934              :              the index of the basis.  There is no potential savings by
    2935              :              eliminating a statement in this case.  */
    2936           30 :           if (operand_equal_p (arg, phi_cand->base_expr, 0))
    2937              :             {
    2938            7 :               arg_cand = (slsr_cand_t)NULL;
    2939            7 :               diff = -basis->index;
    2940              :             }
    2941              :           else
    2942              :             {
    2943           23 :               arg_cand = base_cand_from_table (arg);
    2944           23 :               diff = arg_cand->index - basis->index;
    2945              :             }
    2946              : 
    2947           30 :           if (incr == diff)
    2948              :             {
    2949           14 :               tree basis_lhs = gimple_assign_lhs (basis->cand_stmt);
    2950           14 :               cost += add_cost (true, TYPE_MODE (TREE_TYPE (basis_lhs)));
    2951           14 :               if (arg_cand)
    2952              :                 {
    2953           14 :                   tree lhs = gimple_assign_lhs (arg_cand->cand_stmt);
    2954           14 :                   if (uses_consumed_by_stmt (lhs, phi))
    2955           14 :                     *savings += stmt_cost (arg_cand->cand_stmt, true);
    2956              :                 }
    2957              :             }
    2958              :         }
    2959              :     }
    2960              : 
    2961              :   return cost;
    2962              : }
    2963              : 
    2964              : /* Add up and return the costs of introducing add statements that
    2965              :    require the increment INCR on behalf of candidate C and phi
    2966              :    statement PHI.  Accumulate into *SAVINGS the potential savings
    2967              :    from removing existing statements that feed PHI and have no other
    2968              :    uses.  */
    2969              : 
    2970              : static int
    2971           15 : phi_incr_cost (slsr_cand_t c, const offset_int &incr, gimple *phi,
    2972              :                int *savings)
    2973              : {
    2974           15 :   int retval = phi_incr_cost_1 (c, incr, phi, savings);
    2975           15 :   clear_visited (as_a <gphi *> (phi));
    2976           15 :   return retval;
    2977              : }
    2978              : 
    2979              : /* Return the first candidate in the tree rooted at C that has not
    2980              :    already been replaced, favoring siblings over dependents.  */
    2981              : 
    2982              : static slsr_cand_t
    2983        36348 : unreplaced_cand_in_tree (slsr_cand_t c)
    2984              : {
    2985        36348 :   if (!cand_already_replaced (c))
    2986              :     return c;
    2987              : 
    2988            0 :   if (c->sibling)
    2989              :     {
    2990            0 :       slsr_cand_t sib = unreplaced_cand_in_tree (lookup_cand (c->sibling));
    2991            0 :       if (sib)
    2992              :         return sib;
    2993              :     }
    2994              : 
    2995            0 :   if (c->dependent)
    2996              :     {
    2997            0 :       slsr_cand_t dep = unreplaced_cand_in_tree (lookup_cand (c->dependent));
    2998            0 :       if (dep)
    2999              :         return dep;
    3000              :     }
    3001              : 
    3002              :   return NULL;
    3003              : }
    3004              : 
    3005              : /* Return TRUE if the candidates in the tree rooted at C should be
    3006              :    optimized for speed, else FALSE.  We estimate this based on the block
    3007              :    containing the most dominant candidate in the tree that has not yet
    3008              :    been replaced.  */
    3009              : 
    3010              : static bool
    3011        36348 : optimize_cands_for_speed_p (slsr_cand_t c)
    3012              : {
    3013        36348 :   slsr_cand_t c2 = unreplaced_cand_in_tree (c);
    3014        36348 :   gcc_assert (c2);
    3015        36348 :   return optimize_bb_for_speed_p (gimple_bb (c2->cand_stmt));
    3016              : }
    3017              : 
    3018              : /* Add COST_IN to the lowest cost of any dependent path starting at
    3019              :    candidate C or any of its siblings, counting only candidates along
    3020              :    such paths with increment INCR.  Assume that replacing a candidate
    3021              :    reduces cost by REPL_SAVINGS.  Also account for savings from any
    3022              :    statements that would go dead.  If COUNT_PHIS is true, include
    3023              :    costs of introducing feeding statements for conditional candidates.  */
    3024              : 
    3025              : static int
    3026         4303 : lowest_cost_path (int cost_in, int repl_savings, slsr_cand_t c,
    3027              :                   const offset_int &incr, bool count_phis)
    3028              : {
    3029         4303 :   int local_cost, sib_cost, savings = 0;
    3030         4303 :   offset_int cand_incr = cand_abs_increment (c);
    3031              : 
    3032         4303 :   if (cand_already_replaced (c))
    3033              :     local_cost = cost_in;
    3034         4303 :   else if (incr == cand_incr)
    3035         3009 :     local_cost = cost_in - repl_savings - c->dead_savings;
    3036              :   else
    3037         1294 :     local_cost = cost_in - c->dead_savings;
    3038              : 
    3039         4303 :   if (count_phis
    3040          292 :       && phi_dependent_cand_p (c)
    3041         4317 :       && !cand_already_replaced (c))
    3042              :     {
    3043           14 :       gimple *phi = lookup_cand (c->def_phi)->cand_stmt;
    3044           14 :       local_cost += phi_incr_cost (c, incr, phi, &savings);
    3045              : 
    3046           14 :       if (uses_consumed_by_stmt (gimple_phi_result (phi), c->cand_stmt))
    3047            8 :         local_cost -= savings;
    3048              :     }
    3049              : 
    3050         4303 :   if (c->dependent)
    3051         1802 :     local_cost = lowest_cost_path (local_cost, repl_savings,
    3052              :                                    lookup_cand (c->dependent), incr,
    3053              :                                    count_phis);
    3054              : 
    3055         4303 :   if (c->sibling)
    3056              :     {
    3057           86 :       sib_cost = lowest_cost_path (cost_in, repl_savings,
    3058              :                                    lookup_cand (c->sibling), incr,
    3059              :                                    count_phis);
    3060           86 :       local_cost = MIN (local_cost, sib_cost);
    3061              :     }
    3062              : 
    3063         4303 :   return local_cost;
    3064              : }
    3065              : 
    3066              : /* Compute the total savings that would accrue from all replacements
    3067              :    in the candidate tree rooted at C, counting only candidates with
    3068              :    increment INCR.  Assume that replacing a candidate reduces cost
    3069              :    by REPL_SAVINGS.  Also account for savings from statements that
    3070              :    would go dead.  */
    3071              : 
    3072              : static int
    3073          185 : total_savings (int repl_savings, slsr_cand_t c, const offset_int &incr,
    3074              :                bool count_phis)
    3075              : {
    3076          185 :   int savings = 0;
    3077          185 :   offset_int cand_incr = cand_abs_increment (c);
    3078              : 
    3079          185 :   if (incr == cand_incr && !cand_already_replaced (c))
    3080          140 :     savings += repl_savings + c->dead_savings;
    3081              : 
    3082          185 :   if (count_phis
    3083          102 :       && phi_dependent_cand_p (c)
    3084          186 :       && !cand_already_replaced (c))
    3085              :     {
    3086            1 :       int phi_savings = 0;
    3087            1 :       gimple *phi = lookup_cand (c->def_phi)->cand_stmt;
    3088            1 :       savings -= phi_incr_cost (c, incr, phi, &phi_savings);
    3089              : 
    3090            1 :       if (uses_consumed_by_stmt (gimple_phi_result (phi), c->cand_stmt))
    3091            1 :         savings += phi_savings;
    3092              :     }
    3093              : 
    3094          185 :   if (c->dependent)
    3095          106 :     savings += total_savings (repl_savings, lookup_cand (c->dependent), incr,
    3096              :                               count_phis);
    3097              : 
    3098          185 :   if (c->sibling)
    3099            0 :     savings += total_savings (repl_savings, lookup_cand (c->sibling), incr,
    3100              :                               count_phis);
    3101              : 
    3102          185 :   return savings;
    3103              : }
    3104              : 
    3105              : /* Use target-specific costs to determine and record which increments
    3106              :    in the current candidate tree are profitable to replace, assuming
    3107              :    MODE and SPEED.  FIRST_DEP is the first dependent of the root of
    3108              :    the candidate tree.
    3109              : 
    3110              :    One slight limitation here is that we don't account for the possible
    3111              :    introduction of casts in some cases.  See replace_one_candidate for
    3112              :    the cases where these are introduced.  This should probably be cleaned
    3113              :    up sometime.  */
    3114              : 
    3115              : static void
    3116        36348 : analyze_increments (slsr_cand_t first_dep, machine_mode mode, bool speed)
    3117              : {
    3118        36348 :   unsigned i;
    3119              : 
    3120       102242 :   for (i = 0; i < incr_vec_len; i++)
    3121              :     {
    3122        65894 :       HOST_WIDE_INT incr = incr_vec[i].incr.to_shwi ();
    3123              : 
    3124              :       /* If somehow this increment is bigger than a HWI, we won't
    3125              :          be optimizing candidates that use it.  And if the increment
    3126              :          has a count of zero, nothing will be done with it.  */
    3127        65894 :       if (!wi::fits_shwi_p (incr_vec[i].incr) || !incr_vec[i].count)
    3128        29021 :         incr_vec[i].cost = COST_INFINITE;
    3129              : 
    3130              :       /* Increments of 0, 1, and -1 are always profitable to replace,
    3131              :          because they always replace a multiply or add with an add or
    3132              :          copy, and may cause one or more existing instructions to go
    3133              :          dead.  Exception:  -1 can't be assumed to be profitable for
    3134              :          pointer addition.  */
    3135        36873 :       else if (incr == 0
    3136        36873 :                || incr == 1
    3137         2548 :                || (incr == -1
    3138            6 :                    && !POINTER_TYPE_P (first_dep->cand_type)))
    3139        34325 :         incr_vec[i].cost = COST_NEUTRAL;
    3140              : 
    3141              :       /* If we need to add an initializer, give up if a cast from the
    3142              :          candidate's type to its stride's type can lose precision.
    3143              :          Note that this already takes into account that the stride may
    3144              :          have been cast to a wider type, in which case this test won't
    3145              :          fire.  Example:
    3146              : 
    3147              :            short int _1;
    3148              :            _2 = (int) _1;
    3149              :            _3 = _2 * 10;
    3150              :            _4 = x + _3;    ADD: x + (10 * (int)_1) : int
    3151              :            _5 = _2 * 15;
    3152              :            _6 = x + _5;    ADD: x + (15 * (int)_1) : int
    3153              : 
    3154              :          Although the stride was a short int initially, the stride
    3155              :          used in the analysis has been widened to an int, and such
    3156              :          widening will be done in the initializer as well.  */
    3157         2548 :       else if (!incr_vec[i].initializer
    3158         2036 :                && TREE_CODE (first_dep->stride) != INTEGER_CST
    3159         4584 :                && !legal_cast_p_1 (first_dep->stride_type,
    3160         2036 :                                    TREE_TYPE (gimple_assign_lhs
    3161              :                                               (first_dep->cand_stmt))))
    3162           54 :         incr_vec[i].cost = COST_INFINITE;
    3163              : 
    3164              :       /* If we need to add an initializer, make sure we don't introduce
    3165              :          a multiply by a pointer type, which can happen in certain cast
    3166              :          scenarios.  */
    3167         2494 :       else if (!incr_vec[i].initializer
    3168         1982 :                && TREE_CODE (first_dep->stride) != INTEGER_CST
    3169         1982 :                && POINTER_TYPE_P (first_dep->stride_type))
    3170            0 :         incr_vec[i].cost = COST_INFINITE;
    3171              : 
    3172              :       /* For any other increment, if this is a multiply candidate, we
    3173              :          must introduce a temporary T and initialize it with
    3174              :          T_0 = stride * increment.  When optimizing for speed, walk the
    3175              :          candidate tree to calculate the best cost reduction along any
    3176              :          path; if it offsets the fixed cost of inserting the initializer,
    3177              :          replacing the increment is profitable.  When optimizing for
    3178              :          size, instead calculate the total cost reduction from replacing
    3179              :          all candidates with this increment.  */
    3180         2494 :       else if (first_dep->kind == CAND_MULT)
    3181              :         {
    3182          113 :           int cost = mult_by_coeff_cost (incr, mode, speed);
    3183          113 :           int repl_savings;
    3184              : 
    3185          113 :           if (tree_fits_shwi_p (first_dep->stride))
    3186              :             {
    3187            0 :               HOST_WIDE_INT hwi_stride = tree_to_shwi (first_dep->stride);
    3188            0 :               repl_savings = mult_by_coeff_cost (hwi_stride, mode, speed);
    3189              :             }
    3190              :           else
    3191          113 :             repl_savings = mul_cost (speed, mode);
    3192          113 :           repl_savings -= add_cost (speed, mode);
    3193              : 
    3194          113 :           if (speed)
    3195          107 :             cost = lowest_cost_path (cost, repl_savings, first_dep,
    3196          107 :                                      incr_vec[i].incr, COUNT_PHIS);
    3197              :           else
    3198            6 :             cost -= total_savings (repl_savings, first_dep, incr_vec[i].incr,
    3199              :                                    COUNT_PHIS);
    3200              : 
    3201          113 :           incr_vec[i].cost = cost;
    3202              :         }
    3203              : 
    3204              :       /* If this is an add candidate, the initializer may already
    3205              :          exist, so only calculate the cost of the initializer if it
    3206              :          doesn't.  We are replacing one add with another here, so the
    3207              :          known replacement savings is zero.  We will account for removal
    3208              :          of dead instructions in lowest_cost_path or total_savings.  */
    3209              :       else
    3210              :         {
    3211         2381 :           int cost = 0;
    3212         2381 :           if (!incr_vec[i].initializer)
    3213         1869 :             cost = mult_by_coeff_cost (incr, mode, speed);
    3214              : 
    3215         2381 :           if (speed)
    3216         2308 :             cost = lowest_cost_path (cost, 0, first_dep, incr_vec[i].incr,
    3217              :                                      DONT_COUNT_PHIS);
    3218              :           else
    3219           73 :             cost -= total_savings (0, first_dep, incr_vec[i].incr,
    3220              :                                    DONT_COUNT_PHIS);
    3221              : 
    3222         2381 :           incr_vec[i].cost = cost;
    3223              :         }
    3224              :     }
    3225        36348 : }
    3226              : 
    3227              : /* Return the nearest common dominator of BB1 and BB2.  If the blocks
    3228              :    are identical, return the earlier of C1 and C2 in *WHERE.  Otherwise,
    3229              :    if the NCD matches BB1, return C1 in *WHERE; if the NCD matches BB2,
    3230              :    return C2 in *WHERE; and if the NCD matches neither, return NULL in
    3231              :    *WHERE.  Note: It is possible for one of C1 and C2 to be NULL.  */
    3232              : 
    3233              : static basic_block
    3234          540 : ncd_for_two_cands (basic_block bb1, basic_block bb2,
    3235              :                    slsr_cand_t c1, slsr_cand_t c2, slsr_cand_t *where)
    3236              : {
    3237          540 :   basic_block ncd;
    3238              : 
    3239          540 :   if (!bb1)
    3240              :     {
    3241          298 :       *where = c2;
    3242          298 :       return bb2;
    3243              :     }
    3244              : 
    3245          242 :   if (!bb2)
    3246              :     {
    3247            0 :       *where = c1;
    3248            0 :       return bb1;
    3249              :     }
    3250              : 
    3251          242 :   ncd = nearest_common_dominator (CDI_DOMINATORS, bb1, bb2);
    3252              : 
    3253              :   /* If both candidates are in the same block, the earlier
    3254              :      candidate wins.  */
    3255          242 :   if (bb1 == ncd && bb2 == ncd)
    3256              :     {
    3257          213 :       if (!c1 || (c2 && c2->cand_num < c1->cand_num))
    3258          213 :         *where = c2;
    3259              :       else
    3260            0 :         *where = c1;
    3261              :     }
    3262              : 
    3263              :   /* Otherwise, if one of them produced a candidate in the
    3264              :      dominator, that one wins.  */
    3265           29 :   else if (bb1 == ncd)
    3266            6 :     *where = c1;
    3267              : 
    3268           23 :   else if (bb2 == ncd)
    3269           12 :     *where = c2;
    3270              : 
    3271              :   /* If neither matches the dominator, neither wins.  */
    3272              :   else
    3273           11 :     *where = NULL;
    3274              : 
    3275              :   return ncd;
    3276              : }
    3277              : 
    3278              : /* Consider all candidates that feed PHI.  Find the nearest common
    3279              :    dominator of those candidates requiring the given increment INCR.
    3280              :    Further find and return the nearest common dominator of this result
    3281              :    with block NCD.  If the returned block contains one or more of the
    3282              :    candidates, return the earliest candidate in the block in *WHERE.  */
    3283              : 
    3284              : static basic_block
    3285            8 : ncd_with_phi (slsr_cand_t c, const offset_int &incr, gphi *phi,
    3286              :               basic_block ncd, slsr_cand_t *where)
    3287              : {
    3288            8 :   unsigned i;
    3289            8 :   slsr_cand_t basis = lookup_cand (c->basis);
    3290            8 :   slsr_cand_t phi_cand = *stmt_cand_map->get (phi);
    3291              : 
    3292           24 :   for (i = 0; i < gimple_phi_num_args (phi); i++)
    3293              :     {
    3294           16 :       tree arg = gimple_phi_arg_def (phi, i);
    3295           16 :       gimple *arg_def = SSA_NAME_DEF_STMT (arg);
    3296              : 
    3297           16 :       if (gimple_code (arg_def) == GIMPLE_PHI)
    3298            0 :         ncd = ncd_with_phi (c, incr, as_a <gphi *> (arg_def), ncd, where);
    3299              :       else
    3300              :         {
    3301           16 :           offset_int diff;
    3302              : 
    3303           16 :           if (operand_equal_p (arg, phi_cand->base_expr, 0))
    3304            6 :             diff = -basis->index;
    3305              :           else
    3306              :             {
    3307           10 :               slsr_cand_t arg_cand = base_cand_from_table (arg);
    3308           10 :               diff = arg_cand->index - basis->index;
    3309              :             }
    3310              : 
    3311           16 :           basic_block pred = gimple_phi_arg_edge (phi, i)->src;
    3312              : 
    3313           25 :           if ((incr == diff) || (!address_arithmetic_p && incr == -diff))
    3314            8 :             ncd = ncd_for_two_cands (ncd, pred, *where, NULL, where);
    3315              :         }
    3316              :     }
    3317              : 
    3318            8 :   return ncd;
    3319              : }
    3320              : 
    3321              : /* Consider the candidate C together with any candidates that feed
    3322              :    C's phi dependence (if any).  Find and return the nearest common
    3323              :    dominator of those candidates requiring the given increment INCR.
    3324              :    If the returned block contains one or more of the candidates,
    3325              :    return the earliest candidate in the block in *WHERE.  */
    3326              : 
    3327              : static basic_block
    3328         1332 : ncd_of_cand_and_phis (slsr_cand_t c, const offset_int &incr, slsr_cand_t *where)
    3329              : {
    3330         1332 :   basic_block ncd = NULL;
    3331              : 
    3332         1332 :   if (cand_abs_increment (c) == incr)
    3333              :     {
    3334          527 :       ncd = gimple_bb (c->cand_stmt);
    3335          527 :       *where = c;
    3336              :     }
    3337              : 
    3338         1332 :   if (phi_dependent_cand_p (c))
    3339            8 :     ncd = ncd_with_phi (c, incr,
    3340            8 :                         as_a <gphi *> (lookup_cand (c->def_phi)->cand_stmt),
    3341              :                         ncd, where);
    3342              : 
    3343         1332 :   return ncd;
    3344              : }
    3345              : 
    3346              : /* Consider all candidates in the tree rooted at C for which INCR
    3347              :    represents the required increment of C relative to its basis.
    3348              :    Find and return the basic block that most nearly dominates all
    3349              :    such candidates.  If the returned block contains one or more of
    3350              :    the candidates, return the earliest candidate in the block in
    3351              :    *WHERE.  */
    3352              : 
    3353              : static basic_block
    3354         1332 : nearest_common_dominator_for_cands (slsr_cand_t c, const offset_int &incr,
    3355              :                                     slsr_cand_t *where)
    3356              : {
    3357         1332 :   basic_block sib_ncd = NULL, dep_ncd = NULL, this_ncd = NULL, ncd;
    3358         1332 :   slsr_cand_t sib_where = NULL, dep_where = NULL, this_where = NULL, new_where;
    3359              : 
    3360              :   /* First find the NCD of all siblings and dependents.  */
    3361         1332 :   if (c->sibling)
    3362           49 :     sib_ncd = nearest_common_dominator_for_cands (lookup_cand (c->sibling),
    3363              :                                                   incr, &sib_where);
    3364         1332 :   if (c->dependent)
    3365          990 :     dep_ncd = nearest_common_dominator_for_cands (lookup_cand (c->dependent),
    3366              :                                                   incr, &dep_where);
    3367         1332 :   if (!sib_ncd && !dep_ncd)
    3368              :     {
    3369          541 :       new_where = NULL;
    3370          541 :       ncd = NULL;
    3371              :     }
    3372          791 :   else if (sib_ncd && !dep_ncd)
    3373              :     {
    3374           45 :       new_where = sib_where;
    3375           45 :       ncd = sib_ncd;
    3376              :     }
    3377          746 :   else if (dep_ncd && !sib_ncd)
    3378              :     {
    3379          746 :       new_where = dep_where;
    3380          746 :       ncd = dep_ncd;
    3381              :     }
    3382              :   else
    3383            0 :     ncd = ncd_for_two_cands (sib_ncd, dep_ncd, sib_where,
    3384              :                              dep_where, &new_where);
    3385              : 
    3386              :   /* If the candidate's increment doesn't match the one we're interested
    3387              :      in (and nor do any increments for feeding defs of a phi-dependence),
    3388              :      then the result depends only on siblings and dependents.  */
    3389         1332 :   this_ncd = ncd_of_cand_and_phis (c, incr, &this_where);
    3390              : 
    3391         1332 :   if (!this_ncd || cand_already_replaced (c))
    3392              :     {
    3393          800 :       *where = new_where;
    3394          800 :       return ncd;
    3395              :     }
    3396              : 
    3397              :   /* Otherwise, compare this candidate with the result from all siblings
    3398              :      and dependents.  */
    3399          532 :   ncd = ncd_for_two_cands (ncd, this_ncd, new_where, this_where, where);
    3400              : 
    3401          532 :   return ncd;
    3402              : }
    3403              : 
    3404              : /* Return TRUE if the increment indexed by INDEX is profitable to replace.  */
    3405              : 
    3406              : static inline bool
    3407       135961 : profitable_increment_p (unsigned index)
    3408              : {
    3409       135961 :   return (incr_vec[index].cost <= COST_NEUTRAL);
    3410              : }
    3411              : 
    3412              : /* For each profitable increment in the increment vector not equal to
    3413              :    0 or 1 (or -1, for non-pointer arithmetic), find the nearest common
    3414              :    dominator of all statements in the candidate chain rooted at C
    3415              :    that require that increment, and insert an initializer
    3416              :    T_0 = stride * increment at that location.  Record T_0 with the
    3417              :    increment record.  */
    3418              : 
    3419              : static void
    3420        36348 : insert_initializers (slsr_cand_t c)
    3421              : {
    3422        36348 :   unsigned i;
    3423              : 
    3424       102242 :   for (i = 0; i < incr_vec_len; i++)
    3425              :     {
    3426        65894 :       basic_block bb;
    3427        65894 :       slsr_cand_t where = NULL;
    3428        65894 :       gassign *init_stmt;
    3429        65894 :       gassign *cast_stmt = NULL;
    3430        65894 :       tree new_name, incr_tree, init_stride;
    3431        65894 :       offset_int incr = incr_vec[i].incr;
    3432              : 
    3433       130983 :       if (!profitable_increment_p (i)
    3434        35130 :           || incr == 1
    3435        31622 :           || (incr == -1
    3436            2 :               && (!POINTER_TYPE_P (lookup_cand (c->basis)->cand_type)))
    3437        97516 :           || incr == 0)
    3438        65601 :         continue;
    3439              : 
    3440              :       /* We may have already identified an existing initializer that
    3441              :          will suffice.  */
    3442          805 :       if (incr_vec[i].initializer)
    3443              :         {
    3444          512 :           if (dump_file && (dump_flags & TDF_DETAILS))
    3445              :             {
    3446            0 :               fputs ("Using existing initializer: ", dump_file);
    3447            0 :               print_gimple_stmt (dump_file,
    3448            0 :                                  SSA_NAME_DEF_STMT (incr_vec[i].initializer),
    3449              :                                  0, TDF_NONE);
    3450              :             }
    3451          512 :           continue;
    3452              :         }
    3453              : 
    3454              :       /* Find the block that most closely dominates all candidates
    3455              :          with this increment.  If there is at least one candidate in
    3456              :          that block, the earliest one will be returned in WHERE.  */
    3457          293 :       bb = nearest_common_dominator_for_cands (c, incr, &where);
    3458              : 
    3459              :       /* If the NCD is not dominated by the block containing the
    3460              :          definition of the stride, we can't legally insert a
    3461              :          single initializer.  Mark the increment as unprofitable
    3462              :          so we don't make any replacements.  FIXME: Multiple
    3463              :          initializers could be placed with more analysis.  */
    3464          293 :       gimple *stride_def = SSA_NAME_DEF_STMT (c->stride);
    3465          293 :       basic_block stride_bb = gimple_bb (stride_def);
    3466              : 
    3467          293 :       if (stride_bb && !dominated_by_p (CDI_DOMINATORS, bb, stride_bb))
    3468              :         {
    3469            0 :           if (dump_file && (dump_flags & TDF_DETAILS))
    3470            0 :             fprintf (dump_file,
    3471              :                      "Initializer #%d cannot be legally placed\n", i);
    3472            0 :           incr_vec[i].cost = COST_INFINITE;
    3473            0 :           continue;
    3474              :         }
    3475              : 
    3476              :       /* If the nominal stride has a different type than the recorded
    3477              :          stride type, build a cast from the nominal stride to that type.  */
    3478          293 :       if (!types_compatible_p (TREE_TYPE (c->stride), c->stride_type))
    3479              :         {
    3480          152 :           init_stride = make_temp_ssa_name (c->stride_type, NULL, "slsr");
    3481          152 :           cast_stmt = gimple_build_assign (init_stride, NOP_EXPR, c->stride);
    3482              :         }
    3483              :       else
    3484          141 :         init_stride = c->stride;
    3485              : 
    3486              :       /* Create a new SSA name to hold the initializer's value.  */
    3487          293 :       new_name = make_temp_ssa_name (c->stride_type, NULL, "slsr");
    3488          293 :       incr_vec[i].initializer = new_name;
    3489              : 
    3490              :       /* Create the initializer and insert it in the latest possible
    3491              :          dominating position.  */
    3492          293 :       incr_tree = wide_int_to_tree (c->stride_type, incr);
    3493          293 :       init_stmt = gimple_build_assign (new_name, MULT_EXPR,
    3494              :                                        init_stride, incr_tree);
    3495          293 :       if (where)
    3496              :         {
    3497          279 :           gimple_stmt_iterator gsi = gsi_for_stmt (where->cand_stmt);
    3498          279 :           location_t loc = gimple_location (where->cand_stmt);
    3499              : 
    3500          279 :           if (cast_stmt)
    3501              :             {
    3502          152 :               gsi_insert_before (&gsi, cast_stmt, GSI_SAME_STMT);
    3503          152 :               gimple_set_location (cast_stmt, loc);
    3504              :             }
    3505              : 
    3506          279 :           gimple_set_location (init_stmt, loc);
    3507          279 :           if (gimple_needing_rewrite_undefined (init_stmt))
    3508              :             {
    3509          119 :               gimple_seq seq;
    3510          119 :               seq = rewrite_to_defined_unconditional (init_stmt);
    3511          119 :               gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
    3512              :             }
    3513              :           else
    3514          160 :             gsi_insert_before (&gsi, init_stmt, GSI_SAME_STMT);
    3515              :         }
    3516              :       else
    3517              :         {
    3518           14 :           gimple_stmt_iterator gsi = gsi_last_bb (bb);
    3519           14 :           gimple *basis_stmt = lookup_cand (c->basis)->cand_stmt;
    3520           14 :           location_t loc = gimple_location (basis_stmt);
    3521              : 
    3522           14 :           gimple_set_location (init_stmt, gimple_location (basis_stmt));
    3523           14 :           if (!gsi_end_p (gsi) && stmt_ends_bb_p (gsi_stmt (gsi)))
    3524              :             {
    3525           14 :               if (cast_stmt)
    3526              :                 {
    3527            0 :                   gsi_insert_before (&gsi, cast_stmt, GSI_SAME_STMT);
    3528            0 :                   gimple_set_location (cast_stmt, loc);
    3529              :                 }
    3530           14 :               if (gimple_needing_rewrite_undefined (init_stmt))
    3531              :                 {
    3532            9 :                   gimple_seq seq;
    3533            9 :                   seq = rewrite_to_defined_unconditional (init_stmt);
    3534            9 :                   gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
    3535              :                 }
    3536              :               else
    3537            5 :                 gsi_insert_before (&gsi, init_stmt, GSI_SAME_STMT);
    3538              :             }
    3539              :           else
    3540              :             {
    3541            0 :               if (cast_stmt)
    3542              :                 {
    3543            0 :                   gsi_insert_after (&gsi, cast_stmt, GSI_NEW_STMT);
    3544            0 :                   gimple_set_location (cast_stmt, loc);
    3545              :                 }
    3546            0 :               if (gimple_needing_rewrite_undefined (init_stmt))
    3547              :                 {
    3548            0 :                   gimple_seq seq;
    3549            0 :                   seq = rewrite_to_defined_unconditional (init_stmt);
    3550            0 :                   gsi_insert_seq_after (&gsi, seq, GSI_SAME_STMT);
    3551              :                 }
    3552              :               else
    3553            0 :                 gsi_insert_after (&gsi, init_stmt, GSI_SAME_STMT);
    3554              :             }
    3555              :         }
    3556              : 
    3557          293 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3558              :         {
    3559            0 :           if (cast_stmt)
    3560              :             {
    3561            0 :               fputs ("Inserting stride cast: ", dump_file);
    3562            0 :               print_gimple_stmt (dump_file, cast_stmt, 0);
    3563              :             }
    3564            0 :           fputs ("Inserting initializer: ", dump_file);
    3565            0 :           print_gimple_stmt (dump_file, init_stmt, 0);
    3566              :         }
    3567              :     }
    3568        36348 : }
    3569              : 
    3570              : /* Recursive helper function for all_phi_incrs_profitable.  */
    3571              : 
    3572              : static bool
    3573           12 : all_phi_incrs_profitable_1 (slsr_cand_t c, gphi *phi, int *spread)
    3574              : {
    3575           12 :   unsigned i;
    3576           12 :   slsr_cand_t basis = lookup_cand (c->basis);
    3577           12 :   slsr_cand_t phi_cand = *stmt_cand_map->get (phi);
    3578              : 
    3579           12 :   if (phi_cand->visited)
    3580              :     return true;
    3581              : 
    3582           12 :   phi_cand->visited = 1;
    3583           12 :   (*spread)++;
    3584              : 
    3585              :   /* If the basis doesn't dominate the PHI (including when the PHI is
    3586              :      in the same block as the basis), we won't be able to create a PHI
    3587              :      using the basis here.  */
    3588           12 :   basic_block basis_bb = gimple_bb (basis->cand_stmt);
    3589           12 :   basic_block phi_bb = gimple_bb (phi);
    3590              : 
    3591           12 :   if (phi_bb == basis_bb
    3592           12 :       || !dominated_by_p (CDI_DOMINATORS, phi_bb, basis_bb))
    3593            0 :     return false;
    3594              : 
    3595           29 :   for (i = 0; i < gimple_phi_num_args (phi); i++)
    3596              :     {
    3597              :       /* If the PHI arg resides in a block not dominated by the basis,
    3598              :          we won't be able to create a PHI using the basis here.  */
    3599           21 :       basic_block pred_bb = gimple_phi_arg_edge (phi, i)->src;
    3600              : 
    3601           21 :       if (!dominated_by_p (CDI_DOMINATORS, pred_bb, basis_bb))
    3602              :         return false;
    3603              : 
    3604           21 :       tree arg = gimple_phi_arg_def (phi, i);
    3605           21 :       gimple *arg_def = SSA_NAME_DEF_STMT (arg);
    3606              : 
    3607           21 :       if (gimple_code (arg_def) == GIMPLE_PHI)
    3608              :         {
    3609            0 :           if (!all_phi_incrs_profitable_1 (c, as_a <gphi *> (arg_def), spread)
    3610            0 :               || *spread > MAX_SPREAD)
    3611              :             return false;
    3612              :         }
    3613              :       else
    3614              :         {
    3615           21 :           int j;
    3616           21 :           offset_int increment;
    3617              : 
    3618           21 :           if (operand_equal_p (arg, phi_cand->base_expr, 0))
    3619            7 :             increment = -basis->index;
    3620              :           else
    3621              :             {
    3622           14 :               slsr_cand_t arg_cand = base_cand_from_table (arg);
    3623           14 :               increment = arg_cand->index - basis->index;
    3624              :             }
    3625              : 
    3626           21 :           if (!address_arithmetic_p && wi::neg_p (increment))
    3627            1 :             increment = -increment;
    3628              : 
    3629           21 :           j = incr_vec_index (increment);
    3630              : 
    3631           21 :           if (dump_file && (dump_flags & TDF_DETAILS))
    3632              :             {
    3633            0 :               fprintf (dump_file, "  Conditional candidate %d, phi: ",
    3634              :                        c->cand_num);
    3635            0 :               print_gimple_stmt (dump_file, phi, 0);
    3636            0 :               fputs ("    increment: ", dump_file);
    3637            0 :               print_decs (increment, dump_file);
    3638            0 :               if (j < 0)
    3639            0 :                 fprintf (dump_file,
    3640              :                          "\n  Not replaced; incr_vec overflow.\n");
    3641              :               else {
    3642            0 :                 fprintf (dump_file, "\n    cost: %d\n", incr_vec[j].cost);
    3643            0 :                 if (profitable_increment_p (j))
    3644            0 :                   fputs ("  Replacing...\n", dump_file);
    3645              :                 else
    3646            0 :                   fputs ("  Not replaced.\n", dump_file);
    3647              :               }
    3648              :             }
    3649              : 
    3650           21 :           if (j < 0 || !profitable_increment_p (j))
    3651            4 :             return false;
    3652              :         }
    3653              :     }
    3654              : 
    3655              :   return true;
    3656              : }
    3657              : 
    3658              : /* Return TRUE iff all required increments for candidates feeding PHI
    3659              :    are profitable (and legal!) to replace on behalf of candidate C.  */
    3660              : 
    3661              : static bool
    3662           12 : all_phi_incrs_profitable (slsr_cand_t c, gphi *phi)
    3663              : {
    3664           12 :   int spread = 0;
    3665           12 :   bool retval = all_phi_incrs_profitable_1 (c, phi, &spread);
    3666           12 :   clear_visited (phi);
    3667           12 :   return retval;
    3668              : }
    3669              : 
    3670              : /* Create a NOP_EXPR that copies FROM_EXPR into a new SSA name of
    3671              :    type TO_TYPE, and insert it in front of the statement represented
    3672              :    by candidate C.  Use *NEW_VAR to create the new SSA name.  Return
    3673              :    the new SSA name.  */
    3674              : 
    3675              : static tree
    3676         5845 : introduce_cast_before_cand (slsr_cand_t c, tree to_type, tree from_expr)
    3677              : {
    3678         5845 :   tree cast_lhs;
    3679         5845 :   gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
    3680              : 
    3681        11690 :   cast_lhs = gimple_convert (&gsi, true, GSI_SAME_STMT,
    3682         5845 :                              gimple_location (c->cand_stmt),
    3683              :                              to_type, from_expr);
    3684              : 
    3685         5845 :   if (dump_file && (dump_flags & TDF_DETAILS))
    3686              :     {
    3687            0 :       fputs ("  Inserting(cast): ", dump_file);
    3688            0 :       print_generic_expr (dump_file, cast_lhs);
    3689            0 :       fprintf (dump_file, "\n");
    3690              :     }
    3691              : 
    3692         5845 :   return cast_lhs;
    3693              : }
    3694              : 
    3695              : /* Replace the RHS of the statement represented by candidate C with
    3696              :    NEW_CODE, NEW_RHS1, and NEW_RHS2, provided that to do so doesn't
    3697              :    leave C unchanged or just interchange its operands.  The original
    3698              :    operation and operands are in OLD_CODE, OLD_RHS1, and OLD_RHS2.
    3699              :    If the replacement was made and we are doing a details dump,
    3700              :    return the revised statement, else NULL.  */
    3701              : 
    3702              : static gimple *
    3703         7858 : replace_rhs_if_not_dup (enum tree_code new_code, tree new_rhs1, tree new_rhs2,
    3704              :                         enum tree_code old_code, tree old_rhs1, tree old_rhs2,
    3705              :                         slsr_cand_t c)
    3706              : {
    3707         7858 :   if (new_code != old_code
    3708         7858 :       || ((!operand_equal_p (new_rhs1, old_rhs1, 0)
    3709            0 :            || !operand_equal_p (new_rhs2, old_rhs2, 0))
    3710         3542 :           && (!operand_equal_p (new_rhs1, old_rhs2, 0)
    3711            0 :               || !operand_equal_p (new_rhs2, old_rhs1, 0))))
    3712              :     {
    3713         7858 :       tree lhs = gimple_assign_lhs (c->cand_stmt);
    3714         7858 :       gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
    3715         7858 :       tree rhs2_type = TREE_TYPE (lhs);
    3716         7858 :       if (POINTER_TYPE_P (rhs2_type))
    3717         1217 :         rhs2_type = sizetype;
    3718         7858 :       new_rhs1 = gimple_convert (&gsi, true, GSI_SAME_STMT,
    3719              :                                  UNKNOWN_LOCATION,
    3720         7858 :                                  TREE_TYPE (lhs), new_rhs1);
    3721         7858 :       new_rhs2 = gimple_convert (&gsi, true, GSI_SAME_STMT,
    3722              :                                  UNKNOWN_LOCATION,
    3723              :                                  rhs2_type, new_rhs2);
    3724         7858 :       slsr_cand_t cc = lookup_cand (c->first_interp);
    3725         7858 :       gimple_assign_set_rhs_with_ops (&gsi, new_code, new_rhs1, new_rhs2);
    3726         7858 :       update_stmt (gsi_stmt (gsi));
    3727        30184 :       while (cc)
    3728              :         {
    3729        14468 :           cc->cand_stmt = gsi_stmt (gsi);
    3730        14468 :           cc = lookup_cand (cc->next_interp);
    3731              :         }
    3732              : 
    3733         7858 :       if (gimple_needing_rewrite_undefined (gsi_stmt (gsi)))
    3734         6736 :         rewrite_to_defined_unconditional (&gsi);
    3735         7858 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3736            0 :         return gsi_stmt (gsi);
    3737              :     }
    3738              : 
    3739            0 :   else if (dump_file && (dump_flags & TDF_DETAILS))
    3740            0 :     fputs ("  (duplicate, not actually replacing)\n", dump_file);
    3741              : 
    3742              :   return NULL;
    3743              : }
    3744              : 
    3745              : /* Strength-reduce the statement represented by candidate C by replacing
    3746              :    it with an equivalent addition or subtraction.  I is the index into
    3747              :    the increment vector identifying C's increment.  NEW_VAR is used to
    3748              :    create a new SSA name if a cast needs to be introduced.  BASIS_NAME
    3749              :    is the rhs1 to use in creating the add/subtract.  */
    3750              : 
    3751              : static void
    3752        18878 : replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name,
    3753              :                        auto_bitmap &sdce_worklist)
    3754              : {
    3755        18878 :   gimple *stmt_to_print = NULL;
    3756        18878 :   tree orig_rhs1, orig_rhs2;
    3757        18878 :   tree rhs2;
    3758        18878 :   enum tree_code orig_code, repl_code;
    3759        18878 :   offset_int cand_incr;
    3760              : 
    3761        18878 :   orig_code = gimple_assign_rhs_code (c->cand_stmt);
    3762        18878 :   orig_rhs1 = gimple_assign_rhs1 (c->cand_stmt);
    3763        18878 :   orig_rhs2 = gimple_assign_rhs2 (c->cand_stmt);
    3764        18878 :   cand_incr = cand_increment (c);
    3765              : 
    3766              :   /* If orig_rhs2 is NULL, we have already replaced this in situ with
    3767              :      a copy statement under another interpretation.  */
    3768        18878 :   if (!orig_rhs2)
    3769            0 :     return;
    3770              : 
    3771              :   /* Mark the 2 original rhs for maybe DCEing.  */
    3772        18878 :   if (TREE_CODE (orig_rhs1) == SSA_NAME)
    3773        18878 :     bitmap_set_bit (sdce_worklist, SSA_NAME_VERSION (orig_rhs1));
    3774        18878 :   if (TREE_CODE (orig_rhs2) == SSA_NAME)
    3775        18878 :    bitmap_set_bit (sdce_worklist, SSA_NAME_VERSION (orig_rhs2));
    3776              : 
    3777        18878 :   if (dump_file && (dump_flags & TDF_DETAILS))
    3778              :     {
    3779            0 :       fputs ("Replacing: ", dump_file);
    3780            0 :       print_gimple_stmt (dump_file, c->cand_stmt, 0);
    3781            0 :       stmt_to_print = c->cand_stmt;
    3782              :     }
    3783              : 
    3784        18878 :   if (address_arithmetic_p)
    3785              :     repl_code = POINTER_PLUS_EXPR;
    3786              :   else
    3787        16335 :     repl_code = PLUS_EXPR;
    3788              : 
    3789              :   /* If the increment has an initializer T_0, replace the candidate
    3790              :      statement with an add of the basis name and the initializer.  */
    3791        18878 :   if (incr_vec[i].initializer)
    3792              :     {
    3793         1422 :       tree init_type = TREE_TYPE (incr_vec[i].initializer);
    3794         1422 :       tree orig_type = TREE_TYPE (orig_rhs2);
    3795              : 
    3796         1422 :       if (types_compatible_p (orig_type, init_type))
    3797         1422 :         rhs2 = incr_vec[i].initializer;
    3798              :       else
    3799            0 :         rhs2 = introduce_cast_before_cand (c, orig_type,
    3800            0 :                                            incr_vec[i].initializer);
    3801              : 
    3802         1422 :       if (incr_vec[i].incr != cand_incr)
    3803              :         {
    3804          180 :           gcc_assert (repl_code == PLUS_EXPR);
    3805              :           repl_code = MINUS_EXPR;
    3806              :         }
    3807              : 
    3808         1422 :       stmt_to_print = replace_rhs_if_not_dup (repl_code, basis_name, rhs2,
    3809              :                                               orig_code, orig_rhs1, orig_rhs2,
    3810              :                                               c);
    3811              :     }
    3812              : 
    3813              :   /* Otherwise, the increment is one of -1, 0, and 1.  Replace
    3814              :      with a subtract of the stride from the basis name, a copy
    3815              :      from the basis name, or an add of the stride to the basis
    3816              :      name, respectively.  It may be necessary to introduce a
    3817              :      cast (or reuse an existing cast).  */
    3818        17456 :   else if (cand_incr == 1)
    3819              :     {
    3820         6436 :       tree stride_type = TREE_TYPE (c->stride);
    3821         6436 :       tree orig_type = TREE_TYPE (orig_rhs2);
    3822              : 
    3823         6436 :       if (types_compatible_p (orig_type, stride_type))
    3824         5419 :         rhs2 = c->stride;
    3825              :       else
    3826         1017 :         rhs2 = introduce_cast_before_cand (c, orig_type, c->stride);
    3827              : 
    3828         6436 :       stmt_to_print = replace_rhs_if_not_dup (repl_code, basis_name, rhs2,
    3829              :                                               orig_code, orig_rhs1, orig_rhs2,
    3830              :                                               c);
    3831              :     }
    3832              : 
    3833        11020 :   else if (cand_incr == -1)
    3834              :     {
    3835          393 :       tree stride_type = TREE_TYPE (c->stride);
    3836          393 :       tree orig_type = TREE_TYPE (orig_rhs2);
    3837          393 :       gcc_assert (repl_code != POINTER_PLUS_EXPR);
    3838              : 
    3839          393 :       if (types_compatible_p (orig_type, stride_type))
    3840          316 :         rhs2 = c->stride;
    3841              :       else
    3842           77 :         rhs2 = introduce_cast_before_cand (c, orig_type, c->stride);
    3843              : 
    3844          393 :       if (orig_code != MINUS_EXPR
    3845           42 :           || !operand_equal_p (basis_name, orig_rhs1, 0)
    3846          393 :           || !operand_equal_p (rhs2, orig_rhs2, 0))
    3847              :         {
    3848          393 :           gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
    3849          393 :           tree lhs = gimple_assign_lhs (c->cand_stmt);
    3850          393 :           slsr_cand_t cc = lookup_cand (c->first_interp);
    3851          393 :           basis_name = gimple_convert (&gsi, true, GSI_SAME_STMT,
    3852              :                                        UNKNOWN_LOCATION,
    3853          393 :                                        TREE_TYPE (lhs), basis_name);
    3854          393 :           rhs2 = gimple_convert (&gsi, true, GSI_SAME_STMT,
    3855              :                                  UNKNOWN_LOCATION,
    3856          393 :                                  TREE_TYPE (lhs), rhs2);
    3857          393 :           gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, basis_name, rhs2);
    3858          393 :           update_stmt (gsi_stmt (gsi));
    3859         1530 :           while (cc)
    3860              :             {
    3861          744 :               cc->cand_stmt = gsi_stmt (gsi);
    3862          744 :               cc = lookup_cand (cc->next_interp);
    3863              :             }
    3864              : 
    3865          393 :           if (dump_file && (dump_flags & TDF_DETAILS))
    3866            0 :             stmt_to_print = gsi_stmt (gsi);
    3867              :         }
    3868            0 :       else if (dump_file && (dump_flags & TDF_DETAILS))
    3869            0 :         fputs ("  (duplicate, not actually replacing)\n", dump_file);
    3870              :     }
    3871              : 
    3872        10627 :   else if (cand_incr == 0)
    3873              :     {
    3874        10627 :       tree lhs = gimple_assign_lhs (c->cand_stmt);
    3875        10627 :       tree lhs_type = TREE_TYPE (lhs);
    3876        10627 :       tree basis_type = TREE_TYPE (basis_name);
    3877              : 
    3878        10627 :       if (types_compatible_p (lhs_type, basis_type))
    3879              :         {
    3880        10567 :           gassign *copy_stmt = gimple_build_assign (lhs, basis_name);
    3881        10567 :           gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
    3882        10567 :           slsr_cand_t cc = lookup_cand (c->first_interp);
    3883        10567 :           gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
    3884        10567 :           gsi_replace (&gsi, copy_stmt, false);
    3885        39029 :           while (cc)
    3886              :             {
    3887        17895 :               cc->cand_stmt = copy_stmt;
    3888        17895 :               cc = lookup_cand (cc->next_interp);
    3889              :             }
    3890              : 
    3891        10567 :           if (dump_file && (dump_flags & TDF_DETAILS))
    3892              :             stmt_to_print = copy_stmt;
    3893              :         }
    3894              :       else
    3895              :         {
    3896           60 :           gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
    3897           60 :           gassign *cast_stmt = gimple_build_assign (lhs, NOP_EXPR, basis_name);
    3898           60 :           slsr_cand_t cc = lookup_cand (c->first_interp);
    3899           60 :           gimple_set_location (cast_stmt, gimple_location (c->cand_stmt));
    3900           60 :           gsi_replace (&gsi, cast_stmt, false);
    3901          187 :           while (cc)
    3902              :             {
    3903           67 :               cc->cand_stmt = cast_stmt;
    3904           67 :               cc = lookup_cand (cc->next_interp);
    3905              :             }
    3906              : 
    3907           60 :           if (dump_file && (dump_flags & TDF_DETAILS))
    3908              :             stmt_to_print = cast_stmt;
    3909              :         }
    3910              :     }
    3911              :   else
    3912            0 :     gcc_unreachable ();
    3913              : 
    3914        18878 :   if (dump_file && (dump_flags & TDF_DETAILS) && stmt_to_print)
    3915              :     {
    3916            0 :       fputs ("With: ", dump_file);
    3917            0 :       print_gimple_stmt (dump_file, stmt_to_print, 0);
    3918            0 :       fputs ("\n", dump_file);
    3919              :     }
    3920              : }
    3921              : 
    3922              : /* For each candidate in the tree rooted at C, replace it with
    3923              :    an increment if such has been shown to be profitable.  */
    3924              : 
    3925              : static void
    3926        39581 : replace_profitable_candidates (slsr_cand_t c, auto_bitmap &sdce_worklist)
    3927              : {
    3928        70046 :   if (!cand_already_replaced (c))
    3929              :     {
    3930        70046 :       offset_int increment = cand_abs_increment (c);
    3931        70046 :       enum tree_code orig_code = gimple_assign_rhs_code (c->cand_stmt);
    3932        70046 :       int i;
    3933              : 
    3934        70046 :       i = incr_vec_index (increment);
    3935              : 
    3936              :       /* Only process profitable increments.  Nothing useful can be done
    3937              :          to a cast or copy.  */
    3938        70046 :       if (i >= 0
    3939        70046 :           && profitable_increment_p (i)
    3940        68257 :           && orig_code != SSA_NAME
    3941       122505 :           && !CONVERT_EXPR_CODE_P (orig_code))
    3942              :         {
    3943        18882 :           if (phi_dependent_cand_p (c))
    3944              :             {
    3945           12 :               gphi *phi = as_a <gphi *> (lookup_cand (c->def_phi)->cand_stmt);
    3946              : 
    3947           12 :               if (all_phi_incrs_profitable (c, phi))
    3948              :                 {
    3949              :                   /* Look up the LHS SSA name from C's basis.  This will be
    3950              :                      the RHS1 of the adds we will introduce to create new
    3951              :                      phi arguments.  */
    3952            8 :                   slsr_cand_t basis = lookup_cand (c->basis);
    3953            8 :                   tree basis_name = gimple_assign_lhs (basis->cand_stmt);
    3954              : 
    3955              :                   /* Create a new phi statement that will represent C's true
    3956              :                      basis after the transformation is complete.  */
    3957            8 :                   location_t loc = gimple_location (c->cand_stmt);
    3958            8 :                   tree name = create_phi_basis (c, phi, basis_name,
    3959              :                                                 loc, UNKNOWN_STRIDE);
    3960              : 
    3961              :                   /* Replace C with an add of the new basis phi and the
    3962              :                      increment.  */
    3963            8 :                   replace_one_candidate (c, i, name, sdce_worklist);
    3964              :                 }
    3965              :             }
    3966              :           else
    3967              :             {
    3968        18870 :               slsr_cand_t basis = lookup_cand (c->basis);
    3969        18870 :               tree basis_name = gimple_assign_lhs (basis->cand_stmt);
    3970        18870 :               replace_one_candidate (c, i, basis_name, sdce_worklist);
    3971              :             }
    3972              :         }
    3973              :     }
    3974              : 
    3975        70046 :   if (c->sibling)
    3976         3233 :     replace_profitable_candidates (lookup_cand (c->sibling), sdce_worklist);
    3977              : 
    3978        70046 :   if (c->dependent)
    3979        30465 :     replace_profitable_candidates (lookup_cand (c->dependent), sdce_worklist);
    3980        39581 : }
    3981              : 
    3982              : /* Analyze costs of related candidates in the candidate vector,
    3983              :    and make beneficial replacements.  */
    3984              : 
    3985              : static void
    3986      1041466 : analyze_candidates_and_replace (void)
    3987              : {
    3988      1041466 :   unsigned i;
    3989      1041466 :   slsr_cand_t c;
    3990      1041466 :   auto_bitmap simple_dce_worklist;
    3991              : 
    3992              :   /* Each candidate that has a null basis and a non-null
    3993              :      dependent is the root of a tree of related statements.
    3994              :      Analyze each tree to determine a subset of those
    3995              :      statements that can be replaced with maximum benefit.
    3996              : 
    3997              :      Note the first NULL element is skipped.  */
    3998      9003287 :   FOR_EACH_VEC_ELT_FROM (cand_vec, i, c, 1)
    3999              :     {
    4000      7961821 :       slsr_cand_t first_dep;
    4001              : 
    4002      7961821 :       if (c->basis != 0 || c->dependent == 0)
    4003      7340356 :         continue;
    4004              : 
    4005       621465 :       if (dump_file && (dump_flags & TDF_DETAILS))
    4006            7 :         fprintf (dump_file, "\nProcessing dependency tree rooted at %d.\n",
    4007              :                  c->cand_num);
    4008              : 
    4009       621465 :       first_dep = lookup_cand (c->dependent);
    4010              : 
    4011              :       /* If this is a chain of CAND_REFs, unconditionally replace
    4012              :          each of them with a strength-reduced data reference.  */
    4013       621465 :       if (c->kind == CAND_REF)
    4014         7906 :         replace_refs (c);
    4015              : 
    4016              :       /* If the common stride of all related candidates is a known
    4017              :          constant, each candidate without a phi-dependence can be
    4018              :          profitably replaced.  Each replaces a multiply by a single
    4019              :          add, with the possibility that a feeding add also goes dead.
    4020              :          A candidate with a phi-dependence is replaced only if the
    4021              :          compensation code it requires is offset by the strength
    4022              :          reduction savings.  */
    4023       613559 :       else if (TREE_CODE (c->stride) == INTEGER_CST)
    4024       577211 :         replace_uncond_cands_and_profitable_phis (first_dep,
    4025              :                                                   simple_dce_worklist);
    4026              : 
    4027              :       /* When the stride is an SSA name, it may still be profitable
    4028              :          to replace some or all of the dependent candidates, depending
    4029              :          on whether the introduced increments can be reused, or are
    4030              :          less expensive to calculate than the replaced statements.  */
    4031              :       else
    4032              :         {
    4033        36348 :           machine_mode mode;
    4034        36348 :           bool speed;
    4035              : 
    4036              :           /* Determine whether we'll be generating pointer arithmetic
    4037              :              when replacing candidates.  */
    4038        72696 :           address_arithmetic_p = (c->kind == CAND_ADD
    4039        36348 :                                   && POINTER_TYPE_P (c->cand_type));
    4040              : 
    4041              :           /* If all candidates have already been replaced under other
    4042              :              interpretations, nothing remains to be done.  */
    4043        36348 :           if (!count_candidates (c))
    4044            0 :             continue;
    4045              : 
    4046              :           /* Construct an array of increments for this candidate chain.  */
    4047        36348 :           incr_vec = XNEWVEC (incr_info, MAX_INCR_VEC_LEN);
    4048        36348 :           incr_vec_len = 0;
    4049        36348 :           record_increments (c);
    4050              : 
    4051              :           /* Determine which increments are profitable to replace.  */
    4052        36348 :           mode = TYPE_MODE (TREE_TYPE (gimple_assign_lhs (c->cand_stmt)));
    4053        36348 :           speed = optimize_cands_for_speed_p (c);
    4054        36348 :           analyze_increments (first_dep, mode, speed);
    4055              : 
    4056              :           /* Insert initializers of the form T_0 = stride * increment
    4057              :              for use in profitable replacements.  */
    4058        36348 :           insert_initializers (first_dep);
    4059        36348 :           dump_incr_vec ();
    4060              : 
    4061              :           /* Perform the replacements.  */
    4062        36348 :           replace_profitable_candidates (first_dep, simple_dce_worklist);
    4063        36348 :           free (incr_vec);
    4064              :         }
    4065              :     }
    4066              : 
    4067              :   /* For conditional candidates, we may have uncommitted insertions
    4068              :      on edges to clean up.  */
    4069      1041466 :   gsi_commit_edge_inserts ();
    4070              : 
    4071      1041466 :   simple_dce_from_worklist (simple_dce_worklist);
    4072      1041466 : }
    4073              : 
    4074              : namespace {
    4075              : 
    4076              : const pass_data pass_data_strength_reduction =
    4077              : {
    4078              :   GIMPLE_PASS, /* type */
    4079              :   "slsr", /* name */
    4080              :   OPTGROUP_NONE, /* optinfo_flags */
    4081              :   TV_GIMPLE_SLSR, /* tv_id */
    4082              :   ( PROP_cfg | PROP_ssa ), /* properties_required */
    4083              :   0, /* properties_provided */
    4084              :   0, /* properties_destroyed */
    4085              :   0, /* todo_flags_start */
    4086              :   0, /* todo_flags_finish */
    4087              : };
    4088              : 
    4089              : class pass_strength_reduction : public gimple_opt_pass
    4090              : {
    4091              : public:
    4092       285722 :   pass_strength_reduction (gcc::context *ctxt)
    4093       571444 :     : gimple_opt_pass (pass_data_strength_reduction, ctxt)
    4094              :   {}
    4095              : 
    4096              :   /* opt_pass methods: */
    4097      1041484 :   bool gate (function *) final override { return flag_tree_slsr; }
    4098              :   unsigned int execute (function *) final override;
    4099              : 
    4100              : }; // class pass_strength_reduction
    4101              : 
    4102              : unsigned
    4103      1041466 : pass_strength_reduction::execute (function *fun)
    4104              : {
    4105              :   /* Create the obstack where candidates will reside.  */
    4106      1041466 :   gcc_obstack_init (&cand_obstack);
    4107              : 
    4108              :   /* Allocate the candidate vector and initialize the first NULL element.  */
    4109      1041466 :   cand_vec.create (128);
    4110      1041466 :   cand_vec.safe_push (NULL);
    4111              : 
    4112              :   /* Allocate the mapping from statements to candidate indices.  */
    4113      1041466 :   stmt_cand_map = new hash_map<gimple *, slsr_cand_t>;
    4114              : 
    4115              :   /* Create the obstack where candidate chains will reside.  */
    4116      1041466 :   gcc_obstack_init (&chain_obstack);
    4117              : 
    4118              :   /* Allocate the mapping from base expressions to candidate chains.  */
    4119      1041466 :   base_cand_map = new hash_table<cand_chain_hasher> (500);
    4120              : 
    4121              :   /* Allocate the mapping from bases to alternative bases.  */
    4122      1041466 :   alt_base_map = new hash_map<tree, tree>;
    4123              : 
    4124              :   /* Initialize the loop optimizer.  We need to detect flow across
    4125              :      back edges, and this gives us dominator information as well.  */
    4126      1041466 :   loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
    4127              : 
    4128              :   /* Walk the CFG in predominator order looking for strength reduction
    4129              :      candidates.  */
    4130      1041466 :   find_candidates_dom_walker (CDI_DOMINATORS)
    4131      1041466 :     .walk (fun->cfg->x_entry_block_ptr);
    4132              : 
    4133      1041466 :   if (dump_file && (dump_flags & TDF_DETAILS))
    4134              :     {
    4135            3 :       dump_cand_vec ();
    4136            3 :       dump_cand_chains ();
    4137              :     }
    4138              : 
    4139      2082932 :   delete alt_base_map;
    4140      1041466 :   free_affine_expand_cache (&name_expansions);
    4141              : 
    4142              :   /* Analyze costs and make appropriate replacements.  */
    4143      1041466 :   analyze_candidates_and_replace ();
    4144              : 
    4145      1041466 :   loop_optimizer_finalize ();
    4146      1041466 :   delete base_cand_map;
    4147      1041466 :   base_cand_map = NULL;
    4148      1041466 :   obstack_free (&chain_obstack, NULL);
    4149      2082932 :   delete stmt_cand_map;
    4150      1041466 :   cand_vec.release ();
    4151      1041466 :   obstack_free (&cand_obstack, NULL);
    4152              : 
    4153      1041466 :   return 0;
    4154              : }
    4155              : 
    4156              : } // anon namespace
    4157              : 
    4158              : gimple_opt_pass *
    4159       285722 : make_pass_strength_reduction (gcc::context *ctxt)
    4160              : {
    4161       285722 :   return new pass_strength_reduction (ctxt);
    4162              : }
        

Generated by: LCOV version 2.4-beta

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