LCOV - code coverage report
Current view: top level - gcc - gimple-ssa-strength-reduction.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.7 % 1612 1430
Test Date: 2024-09-07 14:08:43 Functions: 98.7 % 77 76
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

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

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