LCOV - code coverage report
Current view: top level - gcc - tree-ssa-loop-im.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 97.9 % 1678 1642
Test Date: 2026-10-17 16:30:31 Functions: 100.0 % 80 80
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Loop invariant motion.
       2              :    Copyright (C) 2003-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it
       7              : under the terms of the GNU General Public License as published by the
       8              : Free Software Foundation; either version 3, or (at your option) any
       9              : later version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT
      12              : ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #include "config.h"
      21              : #include "system.h"
      22              : #include "coretypes.h"
      23              : #include "backend.h"
      24              : #include "tree.h"
      25              : #include "gimple.h"
      26              : #include "cfghooks.h"
      27              : #include "tree-pass.h"
      28              : #include "ssa.h"
      29              : #include "gimple-pretty-print.h"
      30              : #include "fold-const.h"
      31              : #include "cfganal.h"
      32              : #include "tree-eh.h"
      33              : #include "gimple-iterator.h"
      34              : #include "tree-cfg.h"
      35              : #include "tree-ssa-loop-manip.h"
      36              : #include "tree-ssa-loop.h"
      37              : #include "tree-into-ssa.h"
      38              : #include "cfgloop.h"
      39              : #include "tree-affine.h"
      40              : #include "tree-ssa-propagate.h"
      41              : #include "trans-mem.h"
      42              : #include "gimple-fold.h"
      43              : #include "tree-scalar-evolution.h"
      44              : #include "tree-ssa-loop-niter.h"
      45              : #include "alias.h"
      46              : #include "builtins.h"
      47              : #include "tree-dfa.h"
      48              : #include "tree-ssa.h"
      49              : #include "dbgcnt.h"
      50              : #include "insn-codes.h"
      51              : #include "optabs-tree.h"
      52              : 
      53              : /* TODO:  Support for predicated code motion.  I.e.
      54              : 
      55              :    while (1)
      56              :      {
      57              :        if (cond)
      58              :          {
      59              :            a = inv;
      60              :            something;
      61              :          }
      62              :      }
      63              : 
      64              :    Where COND and INV are invariants, but evaluating INV may trap or be
      65              :    invalid from some other reason if !COND.  This may be transformed to
      66              : 
      67              :    if (cond)
      68              :      a = inv;
      69              :    while (1)
      70              :      {
      71              :        if (cond)
      72              :          something;
      73              :      }  */
      74              : 
      75              : /* The auxiliary data kept for each statement.  */
      76              : 
      77              : struct lim_aux_data
      78              : {
      79              :   class loop *max_loop; /* The outermost loop in that the statement
      80              :                                    is invariant.  */
      81              : 
      82              :   class loop *tgt_loop; /* The loop out of that we want to move the
      83              :                                    invariant.  */
      84              : 
      85              :   class loop *always_executed_in;
      86              :                                 /* The outermost loop for that we are sure
      87              :                                    the statement is executed if the loop
      88              :                                    is entered.  */
      89              : 
      90              :   unsigned cost;                /* Cost of the computation performed by the
      91              :                                    statement.  */
      92              : 
      93              :   unsigned ref;                 /* The simple_mem_ref in this stmt or 0.  */
      94              : 
      95              :   vec<gimple *> depends;  /* Vector of statements that must be also
      96              :                                    hoisted out of the loop when this statement
      97              :                                    is hoisted; i.e. those that define the
      98              :                                    operands of the statement and are inside of
      99              :                                    the MAX_LOOP loop.  */
     100              : };
     101              : 
     102              : /* Maps statements to their lim_aux_data.  */
     103              : 
     104              : static hash_map<gimple *, lim_aux_data *> *lim_aux_data_map;
     105              : 
     106              : /* Description of a memory reference location.  */
     107              : 
     108              : struct mem_ref_loc
     109              : {
     110              :   tree *ref;                    /* The reference itself.  */
     111              :   gimple *stmt;                 /* The statement in that it occurs.  */
     112              : };
     113              : 
     114              : 
     115              : /* Description of a memory reference.  */
     116              : 
     117              : class im_mem_ref
     118              : {
     119              : public:
     120              :   unsigned id : 30;             /* ID assigned to the memory reference
     121              :                                    (its index in memory_accesses.refs_list)  */
     122              :   unsigned ref_canonical : 1;   /* Whether mem.ref was canonicalized.  */
     123              :   unsigned ref_decomposed : 1;  /* Whether the ref was hashed from mem.  */
     124              :   hashval_t hash;               /* Its hash value.  */
     125              : 
     126              :   /* The memory access itself and associated caching of alias-oracle
     127              :      query meta-data.  We are using mem.ref == error_mark_node for the
     128              :      case the reference is represented by its single access stmt
     129              :      in accesses_in_loop[0].  */
     130              :   ao_ref mem;
     131              : 
     132              :   bitmap stored;                /* The set of loops in that this memory location
     133              :                                    is stored to.  */
     134              :   bitmap loaded;                /* The set of loops in that this memory location
     135              :                                    is loaded from.  */
     136              :   vec<mem_ref_loc>                accesses_in_loop;
     137              :                                 /* The locations of the accesses.  */
     138              : 
     139              :   /* The following set is computed on demand.  */
     140              :   bitmap_head dep_loop;         /* The set of loops in that the memory
     141              :                                    reference is {in,}dependent in
     142              :                                    different modes.  */
     143              : };
     144              : 
     145              : static bool in_loop_pipeline;
     146              : 
     147              : /* We use six bits per loop in the ref->dep_loop bitmap to record
     148              :    the dep_kind x dep_state combinations.  */
     149              : 
     150              : enum dep_kind { lim_raw, sm_war, sm_waw };
     151              : enum dep_state { dep_unknown, dep_independent, dep_dependent };
     152              : 
     153              : /* coldest outermost loop for given loop.  */
     154              : vec<class loop *> coldest_outermost_loop;
     155              : /* hotter outer loop nearest to given loop.  */
     156              : vec<class loop *> hotter_than_inner_loop;
     157              : 
     158              : /* Populate the loop dependence cache of REF for LOOP, KIND with STATE.  */
     159              : 
     160              : static void
     161      2101414 : record_loop_dependence (class loop *loop, im_mem_ref *ref,
     162              :                         dep_kind kind, dep_state state)
     163              : {
     164      2101414 :   gcc_assert (state != dep_unknown);
     165      2101414 :   unsigned bit = 6 * loop->num + kind * 2 + state == dep_dependent ? 1 : 0;
     166      2101414 :   bitmap_set_bit (&ref->dep_loop, bit);
     167      2101414 : }
     168              : 
     169              : /* Query the loop dependence cache of REF for LOOP, KIND.  */
     170              : 
     171              : static dep_state
     172       664427 : query_loop_dependence (class loop *loop, im_mem_ref *ref, dep_kind kind)
     173              : {
     174       664427 :   unsigned first_bit = 6 * loop->num + kind * 2;
     175       664427 :   if (bitmap_bit_p (&ref->dep_loop, first_bit))
     176              :     return dep_independent;
     177       664427 :   else if (bitmap_bit_p (&ref->dep_loop, first_bit + 1))
     178            0 :     return dep_dependent;
     179              :   return dep_unknown;
     180              : }
     181              : 
     182              : /* Mem_ref hashtable helpers.  */
     183              : 
     184              : struct mem_ref_hasher : nofree_ptr_hash <im_mem_ref>
     185              : {
     186              :   typedef ao_ref *compare_type;
     187              :   static inline hashval_t hash (const im_mem_ref *);
     188              :   static inline bool equal (const im_mem_ref *, const ao_ref *);
     189              : };
     190              : 
     191              : /* A hash function for class im_mem_ref object OBJ.  */
     192              : 
     193              : inline hashval_t
     194     11527668 : mem_ref_hasher::hash (const im_mem_ref *mem)
     195              : {
     196     11527668 :   return mem->hash;
     197              : }
     198              : 
     199              : /* An equality function for class im_mem_ref object MEM1 with
     200              :    memory reference OBJ2.  */
     201              : 
     202              : inline bool
     203     13377824 : mem_ref_hasher::equal (const im_mem_ref *mem1, const ao_ref *obj2)
     204              : {
     205     13377824 :   if (!obj2->max_size_known_p ())
     206      1465896 :     return operand_equal_p (mem1->mem.ref, obj2->ref, 0);
     207              : 
     208     11911928 :   if (!mem1->ref_decomposed)
     209              :     return false;
     210              : 
     211              :   /* obj2 is now known decomposable and the hash is based on offset,
     212              :      size and base, matching gather_mem_refs_stmt.  */
     213     11378211 :   bool refs_equal
     214     11378211 :     = ((TREE_CODE (mem1->mem.base) == MEM_REF
     215      5044105 :         && TREE_CODE (obj2->base) == MEM_REF
     216      3361961 :         && operand_equal_p (TREE_OPERAND (mem1->mem.base, 0),
     217      3361961 :                             TREE_OPERAND (obj2->base, 0), 0)
     218      2000133 :         && known_eq (mem_ref_offset (mem1->mem.base) * BITS_PER_UNIT
     219              :                      + mem1->mem.offset,
     220              :                      mem_ref_offset (obj2->base) * BITS_PER_UNIT
     221              :                      + obj2->offset))
     222     15962025 :        || (operand_equal_p (mem1->mem.base, obj2->base, 0)
     223       878914 :            && known_eq (mem1->mem.offset, obj2->offset)));
     224              : 
     225     11378211 :   return (refs_equal
     226       959515 :           && known_eq (mem1->mem.size, obj2->size)
     227       957175 :           && known_eq (mem1->mem.max_size, obj2->max_size)
     228       957175 :           && mem1->mem.volatile_p == obj2->volatile_p
     229       957159 :           && (mem1->mem.ref_alias_set == obj2->ref_alias_set
     230              :               /* We are not canonicalizing alias-sets but for the
     231              :                  special-case we didn't canonicalize yet and the
     232              :                  incoming ref is a alias-set zero MEM we pick
     233              :                  the correct one already.  */
     234        15469 :               || (!mem1->ref_canonical
     235        13877 :                   && (TREE_CODE (obj2->ref) == MEM_REF
     236        13877 :                       || TREE_CODE (obj2->ref) == TARGET_MEM_REF)
     237         8769 :                   && obj2->ref_alias_set == 0)
     238              :               /* Likewise if there's a canonical ref with alias-set zero.  */
     239        12392 :               || (mem1->ref_canonical && mem1->mem.ref_alias_set == 0))
     240       945653 :           && types_compatible_p (TREE_TYPE (mem1->mem.ref),
     241       945653 :                                  TREE_TYPE (obj2->ref)));
     242              : }
     243              : 
     244              : 
     245              : /* Description of memory accesses in loops.  */
     246              : 
     247              : static struct
     248              : {
     249              :   /* The hash table of memory references accessed in loops.  */
     250              :   hash_table<mem_ref_hasher> *refs;
     251              : 
     252              :   /* The list of memory references.  */
     253              :   vec<im_mem_ref *> refs_list;
     254              : 
     255              :   /* The set of memory references accessed in each loop.  */
     256              :   vec<bitmap_head> refs_loaded_in_loop;
     257              : 
     258              :   /* The set of memory references stored in each loop.  */
     259              :   vec<bitmap_head> refs_stored_in_loop;
     260              : 
     261              :   /* The set of memory references stored in each loop, including subloops .  */
     262              :   vec<bitmap_head> all_refs_stored_in_loop;
     263              : 
     264              :   /* Cache for expanding memory addresses.  */
     265              :   hash_map<tree, name_expansion *> *ttae_cache;
     266              : } memory_accesses;
     267              : 
     268              : /* Obstack for the bitmaps in the above data structures.  */
     269              : static bitmap_obstack lim_bitmap_obstack;
     270              : static obstack mem_ref_obstack;
     271              : 
     272              : static bool ref_indep_loop_p (class loop *, im_mem_ref *, dep_kind);
     273              : static bool ref_always_stored_p (class loop *, im_mem_ref *);
     274              : static bool refs_independent_p (im_mem_ref *, im_mem_ref *, bool = true);
     275              : 
     276              : /* Minimum cost of an expensive expression.  */
     277              : #define LIM_EXPENSIVE ((unsigned) param_lim_expensive)
     278              : 
     279              : /* The outermost loop for which execution of the header guarantees that the
     280              :    block will be executed.  */
     281              : #define ALWAYS_EXECUTED_IN(BB) ((class loop *) (BB)->aux)
     282              : #define SET_ALWAYS_EXECUTED_IN(BB, VAL) ((BB)->aux = (void *) (VAL))
     283              : 
     284              : /* ID of the shared unanalyzable mem.  */
     285              : #define UNANALYZABLE_MEM_ID 0
     286              : 
     287              : /* Whether the reference was analyzable.  */
     288              : #define MEM_ANALYZABLE(REF) ((REF)->id != UNANALYZABLE_MEM_ID)
     289              : 
     290              : static struct lim_aux_data *
     291     18244502 : init_lim_data (gimple *stmt)
     292              : {
     293     18244502 :   lim_aux_data *p = XCNEW (struct lim_aux_data);
     294     18244502 :   lim_aux_data_map->put (stmt, p);
     295              : 
     296     18244502 :   return p;
     297              : }
     298              : 
     299              : static struct lim_aux_data *
     300    100119548 : get_lim_data (gimple *stmt)
     301              : {
     302    100119548 :   lim_aux_data **p = lim_aux_data_map->get (stmt);
     303    100119548 :   if (!p)
     304              :     return NULL;
     305              : 
     306     49717300 :   return *p;
     307              : }
     308              : 
     309              : /* Releases the memory occupied by DATA.  */
     310              : 
     311              : static void
     312     18244319 : free_lim_aux_data (struct lim_aux_data *data)
     313              : {
     314            0 :   data->depends.release ();
     315     18244319 :   free (data);
     316            0 : }
     317              : 
     318              : static void
     319     18244319 : clear_lim_data (gimple *stmt)
     320              : {
     321     18244319 :   lim_aux_data **p = lim_aux_data_map->get (stmt);
     322     18244319 :   if (!p)
     323              :     return;
     324              : 
     325     18244319 :   free_lim_aux_data (*p);
     326     18244319 :   *p = NULL;
     327              : }
     328              : 
     329              : 
     330              : /* The possibilities of statement movement.  */
     331              : enum move_pos
     332              :   {
     333              :     MOVE_IMPOSSIBLE,            /* No movement -- side effect expression.  */
     334              :     MOVE_PRESERVE_EXECUTION,    /* Must not cause the non-executed statement
     335              :                                    become executed -- memory accesses, ... */
     336              :     MOVE_POSSIBLE               /* Unlimited movement.  */
     337              :   };
     338              : 
     339              : 
     340              : /* If it is possible to hoist the statement STMT unconditionally,
     341              :    returns MOVE_POSSIBLE.
     342              :    If it is possible to hoist the statement STMT, but we must avoid making
     343              :    it executed if it would not be executed in the original program (e.g.
     344              :    because it may trap), return MOVE_PRESERVE_EXECUTION.
     345              :    Otherwise return MOVE_IMPOSSIBLE.  */
     346              : 
     347              : static enum move_pos
     348     50883709 : movement_possibility_1 (gimple *stmt)
     349              : {
     350     50883709 :   tree lhs;
     351     50883709 :   enum move_pos ret = MOVE_POSSIBLE;
     352              : 
     353     50883709 :   if (flag_unswitch_loops
     354     50883709 :       && gimple_code (stmt) == GIMPLE_COND)
     355              :     {
     356              :       /* If we perform unswitching, force the operands of the invariant
     357              :          condition to be moved out of the loop.  */
     358              :       return MOVE_POSSIBLE;
     359              :     }
     360              : 
     361     50510320 :   if (gimple_code (stmt) == GIMPLE_PHI
     362      2678121 :       && gimple_phi_num_args (stmt) <= 2
     363      4991510 :       && !virtual_operand_p (gimple_phi_result (stmt))
     364     51994429 :       && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (stmt)))
     365              :     return MOVE_POSSIBLE;
     366              : 
     367     49026473 :   if (gimple_get_lhs (stmt) == NULL_TREE)
     368              :     return MOVE_IMPOSSIBLE;
     369              : 
     370     32465706 :   if (gimple_vdef (stmt))
     371              :     return MOVE_IMPOSSIBLE;
     372              : 
     373     13707073 :   if (stmt_ends_bb_p (stmt)
     374     12485060 :       || gimple_has_volatile_ops (stmt)
     375     13651604 :       || gimple_has_side_effects (stmt)
     376     27352775 :       || stmt_could_throw_p (cfun, stmt))
     377              :     return MOVE_IMPOSSIBLE;
     378              : 
     379     13248553 :   if (is_gimple_call (stmt))
     380              :     {
     381              :       /* While pure or const call is guaranteed to have no side effects, we
     382              :          cannot move it arbitrarily.  Consider code like
     383              : 
     384              :          char *s = something ();
     385              : 
     386              :          while (1)
     387              :            {
     388              :              if (s)
     389              :                t = strlen (s);
     390              :              else
     391              :                t = 0;
     392              :            }
     393              : 
     394              :          Here the strlen call cannot be moved out of the loop, even though
     395              :          s is invariant.  In addition to possibly creating a call with
     396              :          invalid arguments, moving out a function call that is not executed
     397              :          may cause performance regressions in case the call is costly and
     398              :          not executed at all.  */
     399       130137 :       ret = MOVE_PRESERVE_EXECUTION;
     400       130137 :       lhs = gimple_call_lhs (stmt);
     401              :     }
     402     13118416 :   else if (is_gimple_assign (stmt))
     403     11924142 :     lhs = gimple_assign_lhs (stmt);
     404              :   else
     405              :     return MOVE_IMPOSSIBLE;
     406              : 
     407     12054279 :   if (TREE_CODE (lhs) == SSA_NAME
     408     12054279 :       && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
     409              :     return MOVE_IMPOSSIBLE;
     410              : 
     411     12054064 :   if (TREE_CODE (lhs) != SSA_NAME
     412     12054064 :       || gimple_could_trap_p (stmt))
     413              :     return MOVE_PRESERVE_EXECUTION;
     414              : 
     415      9584351 :   if (is_gimple_assign (stmt))
     416              :     {
     417      9462400 :       auto code = gimple_assign_rhs_code (stmt);
     418      9462400 :       tree type = TREE_TYPE (gimple_assign_rhs1 (stmt));
     419              :       /* A shift or rotate by a possibly out-of-bound count moves only where
     420              :          rewrite_to_defined_unconditional can reduce the count, and not at
     421              :          all when optimizing for size.  */
     422      9462400 :       if ((code == LSHIFT_EXPR
     423              :            || code == RSHIFT_EXPR
     424              :            || code == LROTATE_EXPR
     425      9462400 :            || code == RROTATE_EXPR)
     426       169135 :           && (TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST
     427              :               /* We cannot use ranges at 'stmt' here.  */
     428       126335 :               || wi::geu_p (wi::to_wide (gimple_assign_rhs2 (stmt)),
     429      9588735 :                             element_precision (type)))
     430      9505201 :           && (!gimple_needing_rewrite_undefined (stmt, true)
     431        41784 :               || optimize_loop_for_size_p (loop_containing_stmt (stmt))))
     432              :         ret = MOVE_PRESERVE_EXECUTION;
     433              :     }
     434              : 
     435              :   /* Non local loads in a transaction cannot be hoisted out.  Well,
     436              :      unless the load happens on every path out of the loop, but we
     437              :      don't take this into account yet.  */
     438      9584351 :   if (flag_tm
     439          434 :       && gimple_in_transaction (stmt)
     440      9584454 :       && gimple_assign_single_p (stmt))
     441              :     {
     442           21 :       tree rhs = gimple_assign_rhs1 (stmt);
     443           21 :       if (DECL_P (rhs) && is_global_var (rhs))
     444              :         {
     445           18 :           if (dump_file)
     446              :             {
     447            2 :               fprintf (dump_file, "Cannot hoist conditional load of ");
     448            2 :               print_generic_expr (dump_file, rhs, TDF_SLIM);
     449            2 :               fprintf (dump_file, " because it is in a transaction.\n");
     450              :             }
     451              :           return MOVE_IMPOSSIBLE;
     452              :         }
     453              :     }
     454              : 
     455              :   return ret;
     456              : }
     457              : 
     458              : static enum move_pos
     459     50883709 : movement_possibility (gimple *stmt)
     460              : {
     461     50883709 :   enum move_pos pos = movement_possibility_1 (stmt);
     462     50883709 :   if (pos == MOVE_POSSIBLE)
     463              :     {
     464     11317722 :       use_operand_p use_p;
     465     11317722 :       ssa_op_iter ssa_iter;
     466     36675894 :       FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, ssa_iter, SSA_OP_USE)
     467     14060467 :         if (TREE_CODE (USE_FROM_PTR (use_p)) == SSA_NAME
     468     14060467 :             && ssa_name_maybe_undef_p (USE_FROM_PTR (use_p)))
     469        20017 :           return MOVE_PRESERVE_EXECUTION;
     470              :     }
     471              :   return pos;
     472              : }
     473              : 
     474              : 
     475              : /* Compare the profile count inequality of bb and loop's preheader, it is
     476              :    three-state as stated in profile-count.h, FALSE is returned if inequality
     477              :    cannot be decided.  */
     478              : bool
     479     14468416 : bb_colder_than_loop_preheader (basic_block bb, class loop *loop)
     480              : {
     481     14468416 :   gcc_assert (bb && loop);
     482     14468416 :   return bb->count < loop_preheader_edge (loop)->src->count;
     483              : }
     484              : 
     485              : /* Check coldest loop between OUTERMOST_LOOP and LOOP by comparing profile
     486              :    count.
     487              :   It does three steps check:
     488              :   1) Check whether CURR_BB is cold in it's own loop_father, if it is cold, just
     489              :   return NULL which means it should not be moved out at all;
     490              :   2) CURR_BB is NOT cold, check if pre-computed COLDEST_LOOP is outside of
     491              :   OUTERMOST_LOOP, if it is inside of OUTERMOST_LOOP, return the COLDEST_LOOP;
     492              :   3) If COLDEST_LOOP is outside of OUTERMOST_LOOP, check whether there is a
     493              :   hotter loop between OUTERMOST_LOOP and loop in pre-computed
     494              :   HOTTER_THAN_INNER_LOOP, return it's nested inner loop, otherwise return
     495              :   OUTERMOST_LOOP.
     496              :   At last, the coldest_loop is inside of OUTERMOST_LOOP, just return it as
     497              :   the hoist target.  */
     498              : 
     499              : static class loop *
     500     12804667 : get_coldest_out_loop (class loop *outermost_loop, class loop *loop,
     501              :                       basic_block curr_bb)
     502              : {
     503     12804667 :   gcc_assert (outermost_loop == loop
     504              :               || flow_loop_nested_p (outermost_loop, loop));
     505              : 
     506              :   /* If bb_colder_than_loop_preheader returns false due to three-state
     507              :     comparison, OUTERMOST_LOOP is returned finally to preserve the behavior.
     508              :     Otherwise, return the coldest loop between OUTERMOST_LOOP and LOOP.  */
     509     12804667 :   if (curr_bb && bb_colder_than_loop_preheader (curr_bb, loop))
     510              :     return NULL;
     511              : 
     512     11726598 :   class loop *coldest_loop = coldest_outermost_loop[loop->num];
     513     23453196 :   if (loop_depth (coldest_loop) < loop_depth (outermost_loop))
     514              :     {
     515       229128 :       class loop *hotter_loop = hotter_than_inner_loop[loop->num];
     516       229128 :       if (!hotter_loop
     517       231217 :           || loop_depth (hotter_loop) < loop_depth (outermost_loop))
     518              :         return outermost_loop;
     519              : 
     520              :       /*  hotter_loop is between OUTERMOST_LOOP and LOOP like:
     521              :         [loop tree root, ..., coldest_loop, ..., outermost_loop, ...,
     522              :         hotter_loop, second_coldest_loop, ..., loop]
     523              :         return second_coldest_loop to be the hoist target.  */
     524           38 :       class loop *aloop;
     525           38 :       for (aloop = hotter_loop->inner; aloop; aloop = aloop->next)
     526           38 :         if (aloop == loop || flow_loop_nested_p (aloop, loop))
     527              :           return aloop;
     528              :     }
     529              :   return coldest_loop;
     530              : }
     531              : 
     532              : /* Suppose that operand DEF is used inside the LOOP.  Returns the outermost
     533              :    loop to that we could move the expression using DEF if it did not have
     534              :    other operands, i.e. the outermost loop enclosing LOOP in that the value
     535              :    of DEF is invariant.  */
     536              : 
     537              : static class loop *
     538     20242948 : outermost_invariant_loop (tree def, class loop *loop)
     539              : {
     540     20242948 :   gimple *def_stmt;
     541     20242948 :   basic_block def_bb;
     542     20242948 :   class loop *max_loop;
     543     20242948 :   struct lim_aux_data *lim_data;
     544              : 
     545     20242948 :   if (!def)
     546       937693 :     return superloop_at_depth (loop, 1);
     547              : 
     548     19305255 :   if (TREE_CODE (def) != SSA_NAME)
     549              :     {
     550      4032203 :       gcc_assert (is_gimple_min_invariant (def));
     551      4032203 :       return superloop_at_depth (loop, 1);
     552              :     }
     553              : 
     554     15273052 :   def_stmt = SSA_NAME_DEF_STMT (def);
     555     15273052 :   def_bb = gimple_bb (def_stmt);
     556     15273052 :   if (!def_bb)
     557        76371 :     return superloop_at_depth (loop, 1);
     558              : 
     559     15196681 :   max_loop = find_common_loop (loop, def_bb->loop_father);
     560              : 
     561     15196681 :   lim_data = get_lim_data (def_stmt);
     562     15196681 :   if (lim_data != NULL && lim_data->max_loop != NULL)
     563       729870 :     max_loop = find_common_loop (max_loop,
     564              :                                  loop_outer (lim_data->max_loop));
     565     15196681 :   if (max_loop == loop)
     566              :     return NULL;
     567      1915313 :   max_loop = superloop_at_depth (loop, loop_depth (max_loop) + 1);
     568              : 
     569      1915313 :   return max_loop;
     570              : }
     571              : 
     572              : /* DATA is a structure containing information associated with a statement
     573              :    inside LOOP.  DEF is one of the operands of this statement.
     574              : 
     575              :    Find the outermost loop enclosing LOOP in that value of DEF is invariant
     576              :    and record this in DATA->max_loop field.  If DEF itself is defined inside
     577              :    this loop as well (i.e. we need to hoist it out of the loop if we want
     578              :    to hoist the statement represented by DATA), record the statement in that
     579              :    DEF is defined to the DATA->depends list.  Additionally if ADD_COST is true,
     580              :    add the cost of the computation of DEF to the DATA->cost.
     581              : 
     582              :    If DEF is not invariant in LOOP, return false.  Otherwise return TRUE.  */
     583              : 
     584              : static bool
     585     11920245 : add_dependency (tree def, struct lim_aux_data *data, class loop *loop,
     586              :                 bool add_cost)
     587              : {
     588     11920245 :   gimple *def_stmt = SSA_NAME_DEF_STMT (def);
     589     11920245 :   basic_block def_bb = gimple_bb (def_stmt);
     590     11920245 :   class loop *max_loop;
     591     11920245 :   struct lim_aux_data *def_data;
     592              : 
     593     11920245 :   if (!def_bb)
     594              :     return true;
     595              : 
     596     11550738 :   max_loop = outermost_invariant_loop (def, loop);
     597     11550738 :   if (!max_loop)
     598              :     return false;
     599              : 
     600      1442678 :   if (flow_loop_nested_p (data->max_loop, max_loop))
     601       432353 :     data->max_loop = max_loop;
     602              : 
     603      1442678 :   def_data = get_lim_data (def_stmt);
     604      1442678 :   if (!def_data)
     605              :     return true;
     606              : 
     607       718968 :   if (add_cost
     608              :       /* Only add the cost if the statement defining DEF is inside LOOP,
     609              :          i.e. if it is likely that by moving the invariants dependent
     610              :          on it, we will be able to avoid creating a new register for
     611              :          it (since it will be only used in these dependent invariants).  */
     612       693897 :       && def_bb->loop_father == loop)
     613       491257 :     data->cost += def_data->cost;
     614              : 
     615       718968 :   data->depends.safe_push (def_stmt);
     616              : 
     617       718968 :   return true;
     618              : }
     619              : 
     620              : /* Returns an estimate for a cost of statement STMT.  The values here
     621              :    are just ad-hoc constants, similar to costs for inlining.  */
     622              : 
     623              : static unsigned
     624       822969 : stmt_cost (gimple *stmt)
     625              : {
     626              :   /* Always try to create possibilities for unswitching.  */
     627       822969 :   if (gimple_code (stmt) == GIMPLE_COND
     628       822969 :       || gimple_code (stmt) == GIMPLE_PHI)
     629        17128 :     return LIM_EXPENSIVE;
     630              : 
     631              :   /* We should be hoisting calls if possible.  */
     632       805841 :   if (is_gimple_call (stmt))
     633              :     {
     634          886 :       tree fndecl;
     635              : 
     636              :       /* Unless the call is a builtin_constant_p; this always folds to a
     637              :          constant, so moving it is useless.  */
     638          886 :       fndecl = gimple_call_fndecl (stmt);
     639          886 :       if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_CONSTANT_P))
     640              :         return 0;
     641              : 
     642          886 :       return LIM_EXPENSIVE;
     643              :     }
     644              : 
     645              :   /* Hoisting memory references out should almost surely be a win.  */
     646       804955 :   if (gimple_references_memory_p (stmt))
     647        70696 :     return LIM_EXPENSIVE;
     648              : 
     649       734259 :   if (gimple_code (stmt) != GIMPLE_ASSIGN)
     650              :     return 1;
     651              : 
     652       734259 :   enum tree_code code = gimple_assign_rhs_code (stmt);
     653       734259 :   switch (code)
     654              :     {
     655       121632 :     case MULT_EXPR:
     656       121632 :     case WIDEN_MULT_EXPR:
     657       121632 :     case WIDEN_MULT_PLUS_EXPR:
     658       121632 :     case WIDEN_MULT_MINUS_EXPR:
     659       121632 :     case DOT_PROD_EXPR:
     660       121632 :     case TRUNC_DIV_EXPR:
     661       121632 :     case CEIL_DIV_EXPR:
     662       121632 :     case FLOOR_DIV_EXPR:
     663       121632 :     case ROUND_DIV_EXPR:
     664       121632 :     case EXACT_DIV_EXPR:
     665       121632 :     case CEIL_MOD_EXPR:
     666       121632 :     case FLOOR_MOD_EXPR:
     667       121632 :     case ROUND_MOD_EXPR:
     668       121632 :     case TRUNC_MOD_EXPR:
     669       121632 :     case RDIV_EXPR:
     670              :       /* Division and multiplication are usually expensive.  */
     671       121632 :       return LIM_EXPENSIVE;
     672              : 
     673         9021 :     case LSHIFT_EXPR:
     674         9021 :     case RSHIFT_EXPR:
     675         9021 :     case WIDEN_LSHIFT_EXPR:
     676         9021 :     case LROTATE_EXPR:
     677         9021 :     case RROTATE_EXPR:
     678              :       /* Shifts and rotates are usually expensive.  */
     679         9021 :       return LIM_EXPENSIVE;
     680              : 
     681          483 :     case COND_EXPR:
     682          483 :     case VEC_COND_EXPR:
     683              :       /* Conditionals are expensive.  */
     684          483 :       return LIM_EXPENSIVE;
     685              : 
     686         1477 :     case CONSTRUCTOR:
     687              :       /* Make vector construction cost proportional to the number
     688              :          of elements.  */
     689         1477 :       return CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));
     690              : 
     691              :     case SSA_NAME:
     692              :     case PAREN_EXPR:
     693              :       /* Whether or not something is wrapped inside a PAREN_EXPR
     694              :          should not change move cost.  Nor should an intermediate
     695              :          unpropagated SSA name copy.  */
     696              :       return 0;
     697              : 
     698       565366 :     default:
     699              :       /* Comparisons are usually expensive.  */
     700       565366 :       if (TREE_CODE_CLASS (code) == tcc_comparison)
     701         8521 :         return LIM_EXPENSIVE;
     702              :       return 1;
     703              :     }
     704              : }
     705              : 
     706              : /* Finds the outermost loop between OUTER and LOOP in that the memory reference
     707              :    REF is independent.  If REF is not independent in LOOP, NULL is returned
     708              :    instead.  */
     709              : 
     710              : static class loop *
     711       810005 : outermost_indep_loop (class loop *outer, class loop *loop, im_mem_ref *ref)
     712              : {
     713       810005 :   class loop *aloop;
     714              : 
     715       810005 :   if (ref->stored && bitmap_bit_p (ref->stored, loop->num))
     716              :     return NULL;
     717              : 
     718        85746 :   for (aloop = outer;
     719       726554 :        aloop != loop;
     720        85746 :        aloop = superloop_at_depth (loop, loop_depth (aloop) + 1))
     721        10403 :     if ((!ref->stored || !bitmap_bit_p (ref->stored, aloop->num))
     722        96010 :         && ref_indep_loop_p (aloop, ref, lim_raw))
     723              :       return aloop;
     724              : 
     725       632380 :   if (ref_indep_loop_p (loop, ref, lim_raw))
     726              :     return loop;
     727              :   else
     728       570112 :     return NULL;
     729              : }
     730              : 
     731              : /* If there is a simple load or store to a memory reference in STMT, returns
     732              :    the location of the memory reference, and sets IS_STORE according to whether
     733              :    it is a store or load.  Otherwise, returns NULL.  */
     734              : 
     735              : static tree *
     736      7271046 : simple_mem_ref_in_stmt (gimple *stmt, bool *is_store)
     737              : {
     738      7271046 :   tree *lhs, *rhs;
     739              : 
     740              :   /* Recognize SSA_NAME = MEM and MEM = (SSA_NAME | invariant) patterns.  */
     741      7271046 :   if (!gimple_assign_single_p (stmt))
     742              :     return NULL;
     743              : 
     744      5956541 :   lhs = gimple_assign_lhs_ptr (stmt);
     745      5956541 :   rhs = gimple_assign_rhs1_ptr (stmt);
     746              : 
     747      9298107 :   if (TREE_CODE (*lhs) == SSA_NAME && gimple_vuse (stmt))
     748              :     {
     749      3341566 :       *is_store = false;
     750      3341566 :       return rhs;
     751              :     }
     752      2614975 :   else if (gimple_vdef (stmt)
     753      2614975 :            && (TREE_CODE (*rhs) == SSA_NAME || is_gimple_min_invariant (*rhs)))
     754              :     {
     755      2140650 :       *is_store = true;
     756      2140650 :       return lhs;
     757              :     }
     758              :   else
     759              :     return NULL;
     760              : }
     761              : 
     762              : /* From a controlling predicate in DOM determine the arguments from
     763              :    the PHI node PHI that are chosen if the predicate evaluates to
     764              :    true and false and store them to *TRUE_ARG_P and *FALSE_ARG_P if
     765              :    they are non-NULL.  Returns true if the arguments can be determined,
     766              :    else return false.  */
     767              : 
     768              : static bool
     769        13801 : extract_true_false_args_from_phi (basic_block dom, gphi *phi,
     770              :                                   tree *true_arg_p, tree *false_arg_p)
     771              : {
     772        13801 :   edge te, fe;
     773        13801 :   if (! extract_true_false_controlled_edges (dom, gimple_bb (phi),
     774              :                                              &te, &fe))
     775              :     return false;
     776              : 
     777        12904 :   if (true_arg_p)
     778         1417 :     *true_arg_p = PHI_ARG_DEF (phi, te->dest_idx);
     779        12904 :   if (false_arg_p)
     780         1417 :     *false_arg_p = PHI_ARG_DEF (phi, fe->dest_idx);
     781              : 
     782              :   return true;
     783              : }
     784              : 
     785              : /* Return true if STMT is a shift or rotate whose count would have to be
     786              :    masked when moved out of LOOP, because STMT is not always executed
     787              :    when LOOP is entered.  An out-of-range constant count folds instead.  */
     788              : 
     789              : static bool
     790       226970 : shift_needs_mask_p (gimple *stmt, class loop *loop)
     791              : {
     792       226970 :   if (!gimple_needing_rewrite_undefined (stmt, true))
     793              :     return false;
     794        25457 :   enum tree_code code = gimple_assign_rhs_code (stmt);
     795        25457 :   if ((code != LSHIFT_EXPR
     796              :        && code != RSHIFT_EXPR
     797              :        && code != LROTATE_EXPR
     798        25457 :        && code != RROTATE_EXPR)
     799        25457 :       || TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST)
     800              :     return false;
     801          765 :   class loop *always = get_lim_data (stmt)->always_executed_in;
     802          765 :   return !always || !(always == loop || flow_loop_nested_p (always, loop));
     803              : }
     804              : 
     805              : /* Determine the outermost loop to that it is possible to hoist a statement
     806              :    STMT and store it to LIM_DATA (STMT)->max_loop.  To do this we determine
     807              :    the outermost loop in that the value computed by STMT is invariant.
     808              :    If MUST_PRESERVE_EXEC is true, additionally choose such a loop that
     809              :    we preserve the fact whether STMT is executed.  It also fills other related
     810              :    information to LIM_DATA (STMT).
     811              : 
     812              :    The function returns false if STMT cannot be hoisted outside of the loop it
     813              :    is defined in, and true otherwise.  */
     814              : 
     815              : static bool
     816     12762142 : determine_max_movement (gimple *stmt, bool must_preserve_exec)
     817              : {
     818     12762142 :   basic_block bb = gimple_bb (stmt);
     819     12762142 :   class loop *loop = bb->loop_father;
     820     12762142 :   class loop *level;
     821     12762142 :   struct lim_aux_data *lim_data = get_lim_data (stmt);
     822     12762142 :   tree val;
     823     12762142 :   ssa_op_iter iter;
     824              : 
     825     12762142 :   if (must_preserve_exec)
     826      1458407 :     level = ALWAYS_EXECUTED_IN (bb);
     827              :   else
     828     11303735 :     level = superloop_at_depth (loop, 1);
     829     12762142 :   lim_data->max_loop = get_coldest_out_loop (level, loop, bb);
     830     12762142 :   if (!lim_data->max_loop)
     831              :     return false;
     832              : 
     833     11685752 :   if (gphi *phi = dyn_cast <gphi *> (stmt))
     834              :     {
     835      1426704 :       use_operand_p use_p;
     836      1426704 :       unsigned min_cost = UINT_MAX;
     837      1426704 :       unsigned total_cost = 0;
     838      1426704 :       struct lim_aux_data *def_data;
     839              : 
     840              :       /* We will end up promoting dependencies to be unconditionally
     841              :          evaluated.  For this reason the PHI cost (and thus the
     842              :          cost we remove from the loop by doing the invariant motion)
     843              :          is that of the cheapest PHI argument dependency chain.  */
     844      1641617 :       FOR_EACH_PHI_ARG (use_p, phi, iter, SSA_OP_USE)
     845              :         {
     846      1615765 :           val = USE_FROM_PTR (use_p);
     847              : 
     848      1615765 :           if (TREE_CODE (val) != SSA_NAME)
     849              :             {
     850              :               /* Assign const 1 to constants.  */
     851       132117 :               min_cost = MIN (min_cost, 1);
     852       132117 :               total_cost += 1;
     853       132117 :               continue;
     854              :             }
     855      1483648 :           if (!add_dependency (val, lim_data, loop, false))
     856              :             return false;
     857              : 
     858        82796 :           gimple *def_stmt = SSA_NAME_DEF_STMT (val);
     859        82796 :           if (gimple_bb (def_stmt)
     860        82796 :               && gimple_bb (def_stmt)->loop_father == loop)
     861              :             {
     862         2996 :               def_data = get_lim_data (def_stmt);
     863         2996 :               if (def_data)
     864              :                 {
     865         2996 :                   min_cost = MIN (min_cost, def_data->cost);
     866         2996 :                   total_cost += def_data->cost;
     867              :                 }
     868              :             }
     869              :         }
     870              : 
     871        25852 :       min_cost = MIN (min_cost, total_cost);
     872        25852 :       lim_data->cost += min_cost;
     873              : 
     874        25852 :       if (gimple_phi_num_args (phi) > 1)
     875              :         {
     876        25599 :           basic_block dom = get_immediate_dominator (CDI_DOMINATORS, bb);
     877        25599 :           gimple *cond;
     878        51198 :           if (gsi_end_p (gsi_last_bb (dom)))
     879              :             return false;
     880        17483 :           cond = gsi_stmt (gsi_last_bb (dom));
     881        17483 :           if (gimple_code (cond) != GIMPLE_COND)
     882              :             return false;
     883              :           /* Verify that this is an extended form of a diamond and
     884              :              the PHI arguments are completely controlled by the
     885              :              predicate in DOM.  */
     886        12384 :           if (!extract_true_false_args_from_phi (dom, phi, NULL, NULL))
     887              :             return false;
     888              : 
     889              :         /* Check if one of the dependent statement is a vector compare whether
     890              :            the target supports it,  otherwise it's invalid to hoist it out of
     891              :            the gcond it belonged to.  */
     892        11487 :         if (VECTOR_TYPE_P (TREE_TYPE (gimple_cond_lhs (cond))))
     893              :           {
     894            5 :             tree type = TREE_TYPE (gimple_cond_lhs (cond));
     895            5 :             auto code = gimple_cond_code (cond);
     896            5 :             if (!target_supports_op_p (type, code, optab_vector))
     897              :               return false;
     898              :           }
     899              : 
     900              :           /* Fold in dependencies and cost of the condition.  */
     901        14709 :           FOR_EACH_SSA_TREE_OPERAND (val, cond, iter, SSA_OP_USE)
     902              :             {
     903        12250 :               if (!add_dependency (val, lim_data, loop, false))
     904              :                 return false;
     905         3227 :               def_data = get_lim_data (SSA_NAME_DEF_STMT (val));
     906         3227 :               if (def_data)
     907         1917 :                 lim_data->cost += def_data->cost;
     908              :             }
     909              : 
     910              :           /* We want to avoid unconditionally executing very expensive
     911              :              operations.  As costs for our dependencies cannot be
     912              :              negative just claim we are not invariand for this case.
     913              :              We also are not sure whether the control-flow inside the
     914              :              loop will vanish.  */
     915         2459 :           if (total_cost - min_cost >= 2 * LIM_EXPENSIVE
     916         1088 :               && !(min_cost != 0
     917         1088 :                    && total_cost / min_cost <= 2))
     918              :             return false;
     919              : 
     920              :           /* Assume that the control-flow in the loop will vanish.
     921              :              ???  We should verify this and not artificially increase
     922              :              the cost if that is not the case.  */
     923         1417 :           lim_data->cost += stmt_cost (stmt);
     924              :         }
     925              : 
     926              :       return true;
     927              :     }
     928              : 
     929              :   /* A stmt that receives abnormal edges cannot be hoisted.  */
     930     10259048 :   if (is_a <gcall *> (stmt)
     931     10259048 :       && (gimple_call_flags (stmt) & ECF_RETURNS_TWICE))
     932              :     return false;
     933              : 
     934     11985183 :   FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_USE)
     935     10423242 :     if (!add_dependency (val, lim_data, loop, true))
     936              :       return false;
     937              : 
     938      3108171 :   if (gimple_vuse (stmt))
     939              :     {
     940       811110 :       im_mem_ref *ref
     941       811110 :         = lim_data ? memory_accesses.refs_list[lim_data->ref] : NULL;
     942       811110 :       if (ref
     943       811110 :           && MEM_ANALYZABLE (ref))
     944              :         {
     945       810005 :           lim_data->max_loop = outermost_indep_loop (lim_data->max_loop,
     946              :                                                      loop, ref);
     947       810005 :           if (!lim_data->max_loop)
     948              :             return false;
     949              :         }
     950         1105 :       else if (! add_dependency (gimple_vuse (stmt), lim_data, loop, false))
     951              :         return false;
     952              :     }
     953              : 
     954              :   /* A shift that needs its count masked is not worth moving on its own.  */
     955       821552 :   unsigned cost = stmt_cost (stmt);
     956       821552 :   if (cost >= LIM_EXPENSIVE && shift_needs_mask_p (stmt, lim_data->max_loop))
     957              :     cost = 1;
     958       821552 :   lim_data->cost += cost;
     959              : 
     960       821552 :   return true;
     961              : }
     962              : 
     963              : /* Suppose that some statement in ORIG_LOOP is hoisted to the loop LEVEL,
     964              :    and that one of the operands of this statement is computed by STMT.
     965              :    Ensure that STMT (together with all the statements that define its
     966              :    operands) is hoisted at least out of the loop LEVEL.  */
     967              : 
     968              : static void
     969       760057 : set_level (gimple *stmt, class loop *orig_loop, class loop *level)
     970              : {
     971       760057 :   class loop *stmt_loop = gimple_bb (stmt)->loop_father;
     972       760057 :   struct lim_aux_data *lim_data;
     973       760057 :   gimple *dep_stmt;
     974       760057 :   unsigned i;
     975              : 
     976       760057 :   stmt_loop = find_common_loop (orig_loop, stmt_loop);
     977       760057 :   lim_data = get_lim_data (stmt);
     978       760057 :   if (lim_data != NULL && lim_data->tgt_loop != NULL)
     979       197071 :     stmt_loop = find_common_loop (stmt_loop,
     980              :                                   loop_outer (lim_data->tgt_loop));
     981       760057 :   if (flow_loop_nested_p (stmt_loop, level))
     982       760057 :     return;
     983              : 
     984       498899 :   gcc_assert (level == lim_data->max_loop
     985              :               || flow_loop_nested_p (lim_data->max_loop, level));
     986              : 
     987       498899 :   lim_data->tgt_loop = level;
     988       867745 :   FOR_EACH_VEC_ELT (lim_data->depends, i, dep_stmt)
     989       368846 :     set_level (dep_stmt, orig_loop, level);
     990              : }
     991              : 
     992              : /* Determines an outermost loop from that we want to hoist the statement STMT.
     993              :    For now we chose the outermost possible loop.  TODO -- use profiling
     994              :    information to set it more sanely.  */
     995              : 
     996              : static void
     997       327771 : set_profitable_level (gimple *stmt)
     998              : {
     999       327771 :   set_level (stmt, gimple_bb (stmt)->loop_father, get_lim_data (stmt)->max_loop);
    1000       327771 : }
    1001              : 
    1002              : /* Returns true if STMT is a call that has side effects.  */
    1003              : 
    1004              : static bool
    1005     78875322 : nonpure_call_p (gimple *stmt)
    1006              : {
    1007            0 :   if (gimple_code (stmt) != GIMPLE_CALL)
    1008              :     return false;
    1009              : 
    1010      2371116 :   return gimple_has_side_effects (stmt);
    1011              : }
    1012              : 
    1013              : /* Rewrite a/b to a*(1/b).  Return the invariant stmt to process.  */
    1014              : 
    1015              : static gimple *
    1016           35 : rewrite_reciprocal (gimple_stmt_iterator *bsi)
    1017              : {
    1018           35 :   gassign *stmt, *stmt1, *stmt2;
    1019           35 :   tree name, lhs, type;
    1020           35 :   tree real_one;
    1021           35 :   gimple_stmt_iterator gsi;
    1022              : 
    1023           35 :   stmt = as_a <gassign *> (gsi_stmt (*bsi));
    1024           35 :   lhs = gimple_assign_lhs (stmt);
    1025           35 :   type = TREE_TYPE (lhs);
    1026              : 
    1027           35 :   real_one = build_one_cst (type);
    1028              : 
    1029           35 :   name = make_temp_ssa_name (type, NULL, "reciptmp");
    1030           70 :   stmt1 = gimple_build_assign (name, RDIV_EXPR, real_one,
    1031              :                                gimple_assign_rhs2 (stmt));
    1032           35 :   stmt2 = gimple_build_assign (lhs, MULT_EXPR, name,
    1033              :                                gimple_assign_rhs1 (stmt));
    1034              : 
    1035              :   /* Replace division stmt with reciprocal and multiply stmts.
    1036              :      The multiply stmt is not invariant, so update iterator
    1037              :      and avoid rescanning.  */
    1038           35 :   gsi = *bsi;
    1039           35 :   gsi_insert_before (bsi, stmt1, GSI_NEW_STMT);
    1040           35 :   gsi_replace (&gsi, stmt2, true);
    1041              : 
    1042              :   /* Continue processing with invariant reciprocal statement.  */
    1043           35 :   return stmt1;
    1044              : }
    1045              : 
    1046              : /* Check if the pattern at *BSI is a bittest of the form
    1047              :    (A >> B) & 1 != 0 and in this case rewrite it to A & (1 << B) != 0.  */
    1048              : 
    1049              : static gimple *
    1050         9625 : rewrite_bittest (gimple_stmt_iterator *bsi)
    1051              : {
    1052         9625 :   gassign *stmt;
    1053         9625 :   gimple *stmt1;
    1054         9625 :   gassign *stmt2;
    1055         9625 :   gimple *use_stmt;
    1056         9625 :   gcond *cond_stmt;
    1057         9625 :   tree lhs, name, t, a, b;
    1058         9625 :   use_operand_p use;
    1059              : 
    1060         9625 :   stmt = as_a <gassign *> (gsi_stmt (*bsi));
    1061         9625 :   lhs = gimple_assign_lhs (stmt);
    1062              : 
    1063              :   /* Verify that the single use of lhs is a comparison against zero.  */
    1064         9625 :   if (TREE_CODE (lhs) != SSA_NAME
    1065         9625 :       || !single_imm_use (lhs, &use, &use_stmt))
    1066              :     return stmt;
    1067         9173 :   cond_stmt = dyn_cast <gcond *> (use_stmt);
    1068         5319 :   if (!cond_stmt)
    1069              :     return stmt;
    1070         5319 :   if (gimple_cond_lhs (cond_stmt) != lhs
    1071         5141 :       || (gimple_cond_code (cond_stmt) != NE_EXPR
    1072         2227 :           && gimple_cond_code (cond_stmt) != EQ_EXPR)
    1073        10460 :       || !integer_zerop (gimple_cond_rhs (cond_stmt)))
    1074              :     return stmt;
    1075              : 
    1076              :   /* Get at the operands of the shift.  The rhs is TMP1 & 1.  */
    1077         5109 :   stmt1 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
    1078         5109 :   if (gimple_code (stmt1) != GIMPLE_ASSIGN)
    1079              :     return stmt;
    1080              : 
    1081              :   /* There is a conversion in between possibly inserted by fold.  */
    1082         5029 :   if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt1)))
    1083              :     {
    1084          221 :       t = gimple_assign_rhs1 (stmt1);
    1085          221 :       if (TREE_CODE (t) != SSA_NAME
    1086          221 :           || !has_single_use (t))
    1087              :         return stmt;
    1088          151 :       stmt1 = SSA_NAME_DEF_STMT (t);
    1089          151 :       if (gimple_code (stmt1) != GIMPLE_ASSIGN)
    1090              :         return stmt;
    1091              :     }
    1092              : 
    1093              :   /* Verify that B is loop invariant but A is not.  Verify that with
    1094              :      all the stmt walking we are still in the same loop.  */
    1095         4917 :   if (gimple_assign_rhs_code (stmt1) != RSHIFT_EXPR
    1096        11357 :       || loop_containing_stmt (stmt1) != loop_containing_stmt (stmt))
    1097              :     return stmt;
    1098              : 
    1099         3220 :   a = gimple_assign_rhs1 (stmt1);
    1100         3220 :   b = gimple_assign_rhs2 (stmt1);
    1101              : 
    1102         3220 :   if (outermost_invariant_loop (b, loop_containing_stmt (stmt1)) != NULL
    1103         3249 :       && outermost_invariant_loop (a, loop_containing_stmt (stmt1)) == NULL)
    1104              :     {
    1105           29 :       gimple_stmt_iterator rsi;
    1106              : 
    1107              :       /* 1 << B */
    1108           29 :       t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (a),
    1109              :                        build_int_cst (TREE_TYPE (a), 1), b);
    1110           29 :       name = make_temp_ssa_name (TREE_TYPE (a), NULL, "shifttmp");
    1111           29 :       stmt1 = gimple_build_assign (name, t);
    1112              : 
    1113              :       /* A & (1 << B) */
    1114           29 :       t = fold_build2 (BIT_AND_EXPR, TREE_TYPE (a), a, name);
    1115           29 :       name = make_temp_ssa_name (TREE_TYPE (a), NULL, "shifttmp");
    1116           29 :       stmt2 = gimple_build_assign (name, t);
    1117              : 
    1118              :       /* Replace the SSA_NAME we compare against zero.  Adjust
    1119              :          the type of zero accordingly.  */
    1120           29 :       SET_USE (use, name);
    1121           29 :       gimple_cond_set_rhs (cond_stmt,
    1122           29 :                            build_int_cst_type (TREE_TYPE (name),
    1123              :                                                0));
    1124              : 
    1125              :       /* Don't use gsi_replace here, none of the new assignments sets
    1126              :          the variable originally set in stmt.  Move bsi to stmt1, and
    1127              :          then remove the original stmt, so that we get a chance to
    1128              :          retain debug info for it.  */
    1129           29 :       rsi = *bsi;
    1130           29 :       gsi_insert_before (bsi, stmt1, GSI_NEW_STMT);
    1131           29 :       gsi_insert_before (&rsi, stmt2, GSI_SAME_STMT);
    1132           29 :       gimple *to_release = gsi_stmt (rsi);
    1133           29 :       gsi_remove (&rsi, true);
    1134           29 :       release_defs (to_release);
    1135              : 
    1136           29 :       return stmt1;
    1137              :     }
    1138              : 
    1139              :   return stmt;
    1140              : }
    1141              : 
    1142              : /* Determine the outermost loops in that statements in basic block BB are
    1143              :    invariant, and record them to the LIM_DATA associated with the
    1144              :    statements.  */
    1145              : 
    1146              : static void
    1147     14975448 : compute_invariantness (basic_block bb)
    1148              : {
    1149     14975448 :   enum move_pos pos;
    1150     14975448 :   gimple_stmt_iterator bsi;
    1151     14975448 :   gimple *stmt;
    1152     14975448 :   bool maybe_never = ALWAYS_EXECUTED_IN (bb) == NULL;
    1153     14975448 :   class loop *outermost = ALWAYS_EXECUTED_IN (bb);
    1154     14975448 :   struct lim_aux_data *lim_data;
    1155              : 
    1156     14975448 :   if (!loop_outer (bb->loop_father))
    1157      8687793 :     return;
    1158              : 
    1159      6287655 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1160          585 :     fprintf (dump_file, "Basic block %d (loop %d -- depth %d):\n\n",
    1161          585 :              bb->index, bb->loop_father->num, loop_depth (bb->loop_father));
    1162              : 
    1163              :   /* Look at PHI nodes, but only if there is at most two.
    1164              :      ???  We could relax this further by post-processing the inserted
    1165              :      code and transforming adjacent cond-exprs with the same predicate
    1166              :      to control flow again.  */
    1167      6287655 :   bsi = gsi_start_phis (bb);
    1168      6287655 :   if (!gsi_end_p (bsi)
    1169      6287655 :       && ((gsi_next (&bsi), gsi_end_p (bsi))
    1170      1411184 :           || (gsi_next (&bsi), gsi_end_p (bsi))))
    1171      4446780 :     for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
    1172              :       {
    1173      2678121 :         stmt = gsi_stmt (bsi);
    1174              : 
    1175      2678121 :         pos = movement_possibility (stmt);
    1176      2678121 :         if (pos == MOVE_IMPOSSIBLE)
    1177      1194274 :           continue;
    1178              : 
    1179      1483847 :         lim_data = get_lim_data (stmt);
    1180      1483847 :         if (! lim_data)
    1181      1483847 :           lim_data = init_lim_data (stmt);
    1182      1483847 :         lim_data->always_executed_in = outermost;
    1183              : 
    1184      1483847 :         if (!determine_max_movement (stmt, false))
    1185              :           {
    1186      1482177 :             lim_data->max_loop = NULL;
    1187      1482177 :             continue;
    1188              :           }
    1189              : 
    1190         1670 :         if (dump_file && (dump_flags & TDF_DETAILS))
    1191              :           {
    1192            2 :             print_gimple_stmt (dump_file, stmt, 2);
    1193            2 :             fprintf (dump_file, "  invariant up to level %d, cost %d.\n\n",
    1194            2 :                      loop_depth (lim_data->max_loop),
    1195              :                      lim_data->cost);
    1196              :           }
    1197              : 
    1198         1670 :         if (lim_data->cost >= LIM_EXPENSIVE)
    1199         1445 :           set_profitable_level (stmt);
    1200              :       }
    1201              : 
    1202     60780898 :   for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
    1203              :     {
    1204     48205588 :       stmt = gsi_stmt (bsi);
    1205              : 
    1206     48205588 :       pos = movement_possibility (stmt);
    1207     48205588 :       if (pos == MOVE_IMPOSSIBLE)
    1208              :         {
    1209     37018111 :           if (nonpure_call_p (stmt))
    1210              :             {
    1211              :               maybe_never = true;
    1212              :               outermost = NULL;
    1213              :             }
    1214              :           /* Make sure to note always_executed_in for stores to make
    1215              :              store-motion work.  */
    1216     34543601 :           else if (stmt_makes_single_store (stmt))
    1217              :             {
    1218      2603848 :               struct lim_aux_data *lim_data = get_lim_data (stmt);
    1219      2603848 :               if (! lim_data)
    1220            0 :                 lim_data = init_lim_data (stmt);
    1221      2603848 :               lim_data->always_executed_in = outermost;
    1222              :             }
    1223     35778153 :           continue;
    1224     35778153 :         }
    1225              : 
    1226     12427435 :       if (is_gimple_assign (stmt)
    1227     12427435 :           && (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
    1228              :               == GIMPLE_BINARY_RHS))
    1229              :         {
    1230      5959416 :           tree op0 = gimple_assign_rhs1 (stmt);
    1231      5959416 :           tree op1 = gimple_assign_rhs2 (stmt);
    1232     11918832 :           class loop *ol1 = outermost_invariant_loop (op1,
    1233              :                                         loop_containing_stmt (stmt));
    1234              : 
    1235              :           /* If divisor is invariant, convert a/b to a*(1/b), allowing reciprocal
    1236              :              to be hoisted out of loop, saving expensive divide.  */
    1237      5959416 :           if (pos == MOVE_POSSIBLE
    1238      5524470 :               && gimple_assign_rhs_code (stmt) == RDIV_EXPR
    1239          983 :               && flag_unsafe_math_optimizations
    1240          423 :               && !flag_trapping_math
    1241          423 :               && ol1 != NULL
    1242      5959454 :               && outermost_invariant_loop (op0, ol1) == NULL)
    1243           35 :             stmt = rewrite_reciprocal (&bsi);
    1244              : 
    1245              :           /* If the shift count is invariant, convert (A >> B) & 1 to
    1246              :              A & (1 << B) allowing the bit mask to be hoisted out of the loop
    1247              :              saving an expensive shift.  */
    1248      5959416 :           if (pos == MOVE_POSSIBLE
    1249      5524470 :               && gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
    1250       196171 :               && integer_onep (op1)
    1251        19709 :               && TREE_CODE (op0) == SSA_NAME
    1252      5979125 :               && has_single_use (op0))
    1253         9625 :             stmt = rewrite_bittest (&bsi);
    1254              :         }
    1255              : 
    1256     12427435 :       lim_data = get_lim_data (stmt);
    1257     12427435 :       if (! lim_data)
    1258      9448575 :         lim_data = init_lim_data (stmt);
    1259     12427435 :       lim_data->always_executed_in = outermost;
    1260              : 
    1261     12427435 :       if (maybe_never && pos == MOVE_PRESERVE_EXECUTION)
    1262      1149140 :         continue;
    1263              : 
    1264     11278295 :       if (!determine_max_movement (stmt, pos == MOVE_PRESERVE_EXECUTION))
    1265              :         {
    1266     10456743 :           lim_data->max_loop = NULL;
    1267     10456743 :           continue;
    1268              :         }
    1269              : 
    1270       821552 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1271              :         {
    1272          318 :           print_gimple_stmt (dump_file, stmt, 2);
    1273          318 :           fprintf (dump_file, "  invariant up to level %d, cost %d.\n\n",
    1274          318 :                    loop_depth (lim_data->max_loop),
    1275              :                    lim_data->cost);
    1276              :         }
    1277              : 
    1278       821552 :       if (lim_data->cost >= LIM_EXPENSIVE)
    1279       326326 :         set_profitable_level (stmt);
    1280              :       /* When we run before PRE and PRE is active hoist all expressions
    1281              :          to the always executed loop since PRE would do so anyway
    1282              :          and we can preserve range info while PRE cannot.  */
    1283       495226 :       else if (flag_tree_pre && !in_loop_pipeline
    1284       105065 :                && outermost)
    1285              :         {
    1286        60494 :           class loop *mloop = lim_data->max_loop;
    1287       181482 :           if (loop_depth (outermost) > loop_depth (mloop))
    1288              :             {
    1289         6502 :               mloop = outermost;
    1290         6502 :               if (dump_file && (dump_flags & TDF_DETAILS))
    1291            1 :                 fprintf (dump_file, "  constraining to loop depth %d\n\n\n",
    1292              :                          loop_depth (mloop));
    1293              :             }
    1294        60494 :           set_level (stmt, bb->loop_father, mloop);
    1295              :         }
    1296              :     }
    1297              : }
    1298              : 
    1299              : /* Hoist the statements in basic block BB out of the loops prescribed by
    1300              :    data stored in LIM_DATA structures associated with each statement.  Callback
    1301              :    for walk_dominator_tree.  */
    1302              : 
    1303              : unsigned int
    1304     15014523 : move_computations_worker (basic_block bb)
    1305              : {
    1306     15014523 :   class loop *level;
    1307     15014523 :   unsigned cost = 0;
    1308     15014523 :   struct lim_aux_data *lim_data;
    1309     15014523 :   unsigned int todo = 0;
    1310              : 
    1311     15014523 :   if (!loop_outer (bb->loop_father))
    1312              :     return todo;
    1313              : 
    1314     10974552 :   for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi); )
    1315              :     {
    1316      4680689 :       gassign *new_stmt;
    1317      4680689 :       gphi *stmt = bsi.phi ();
    1318              : 
    1319      4680689 :       lim_data = get_lim_data (stmt);
    1320      4680689 :       if (lim_data == NULL)
    1321              :         {
    1322      3196842 :           gsi_next (&bsi);
    1323      3196842 :           continue;
    1324              :         }
    1325              : 
    1326      1483847 :       cost = lim_data->cost;
    1327      1483847 :       level = lim_data->tgt_loop;
    1328      1483847 :       clear_lim_data (stmt);
    1329              : 
    1330      1483847 :       if (!level)
    1331              :         {
    1332      1482392 :           gsi_next (&bsi);
    1333      1482392 :           continue;
    1334              :         }
    1335              : 
    1336         1455 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1337              :         {
    1338            2 :           fprintf (dump_file, "Moving PHI node\n");
    1339            2 :           print_gimple_stmt (dump_file, stmt, 0);
    1340            2 :           fprintf (dump_file, "(cost %u) out of loop %d.\n\n",
    1341              :                    cost, level->num);
    1342              :         }
    1343              : 
    1344         1455 :       if (gimple_phi_num_args (stmt) == 1)
    1345              :         {
    1346           38 :           tree arg = PHI_ARG_DEF (stmt, 0);
    1347           38 :           new_stmt = gimple_build_assign (gimple_phi_result (stmt),
    1348           38 :                                           TREE_CODE (arg), arg);
    1349              :         }
    1350              :       else
    1351              :         {
    1352         1417 :           basic_block dom = get_immediate_dominator (CDI_DOMINATORS, bb);
    1353         1417 :           gimple *cond = gsi_stmt (gsi_last_bb (dom));
    1354         1417 :           tree arg0 = NULL_TREE, arg1 = NULL_TREE, t;
    1355              :           /* Get the PHI arguments corresponding to the true and false
    1356              :              edges of COND.  */
    1357         1417 :           extract_true_false_args_from_phi (dom, stmt, &arg0, &arg1);
    1358         1417 :           gcc_assert (arg0 && arg1);
    1359              :           /* For `bool_val != 0`, reuse bool_val. */
    1360         1417 :           if (gimple_cond_code (cond) == NE_EXPR
    1361          631 :               && integer_zerop (gimple_cond_rhs (cond))
    1362         1973 :               && types_compatible_p (TREE_TYPE (gimple_cond_lhs (cond)),
    1363              :                                      boolean_type_node))
    1364              :             {
    1365           54 :               t = gimple_cond_lhs (cond);
    1366              :             }
    1367              :           else
    1368              :             {
    1369         1363 :               t = make_ssa_name (boolean_type_node);
    1370         1363 :               new_stmt = gimple_build_assign (t, gimple_cond_code (cond),
    1371              :                                               gimple_cond_lhs (cond),
    1372              :                                               gimple_cond_rhs (cond));
    1373         1363 :               gsi_insert_on_edge (loop_preheader_edge (level), new_stmt);
    1374              :             }
    1375         1417 :           new_stmt = gimple_build_assign (gimple_phi_result (stmt),
    1376              :                                           COND_EXPR, t, arg0, arg1);
    1377         1417 :           todo |= TODO_cleanup_cfg;
    1378              :         }
    1379         1455 :       if (!ALWAYS_EXECUTED_IN (bb)
    1380         1455 :           || (ALWAYS_EXECUTED_IN (bb) != level
    1381          100 :               && !flow_loop_nested_p (ALWAYS_EXECUTED_IN (bb), level)))
    1382          889 :         reset_flow_sensitive_info (gimple_assign_lhs (new_stmt));
    1383         1455 :       gsi_insert_on_edge (loop_preheader_edge (level), new_stmt);
    1384         1455 :       remove_phi_node (&bsi, false);
    1385              :     }
    1386              : 
    1387     60855970 :   for (gimple_stmt_iterator bsi = gsi_start_bb (bb); !gsi_end_p (bsi); )
    1388              :     {
    1389     48268244 :       edge e;
    1390              : 
    1391     48268244 :       gimple *stmt = gsi_stmt (bsi);
    1392              : 
    1393     48268244 :       lim_data = get_lim_data (stmt);
    1394     48268244 :       if (lim_data == NULL)
    1395              :         {
    1396     31507772 :           gsi_next (&bsi);
    1397     31507772 :           continue;
    1398              :         }
    1399              : 
    1400     16760472 :       cost = lim_data->cost;
    1401     16760472 :       level = lim_data->tgt_loop;
    1402     16760472 :       clear_lim_data (stmt);
    1403              : 
    1404     16760472 :       if (!level)
    1405              :         {
    1406     16223341 :           gsi_next (&bsi);
    1407     16223341 :           continue;
    1408              :         }
    1409              : 
    1410              :       /* We do not really want to move conditionals out of the loop; we just
    1411              :          placed it here to force its operands to be moved if necessary.  */
    1412       537131 :       if (gimple_code (stmt) == GIMPLE_COND)
    1413              :         {
    1414        15711 :           gsi_next (&bsi);
    1415        15711 :           continue;
    1416              :         }
    1417              : 
    1418       521420 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1419              :         {
    1420          387 :           fprintf (dump_file, "Moving statement ");
    1421          387 :           print_gimple_stmt (dump_file, stmt, 0);
    1422          387 :           fprintf (dump_file, "(cost %u) out of loop %d.\n\n",
    1423              :                    cost, level->num);
    1424              :         }
    1425              : 
    1426       521420 :       e = loop_preheader_edge (level);
    1427      1042840 :       gcc_assert (!gimple_vdef (stmt));
    1428      1042840 :       if (gimple_vuse (stmt))
    1429              :         {
    1430              :           /* The new VUSE is the one from the virtual PHI in the loop
    1431              :              header or the one already present.  */
    1432        88044 :           gphi_iterator gsi2;
    1433        88044 :           for (gsi2 = gsi_start_phis (e->dest);
    1434       205491 :                !gsi_end_p (gsi2); gsi_next (&gsi2))
    1435              :             {
    1436       186039 :               gphi *phi = gsi2.phi ();
    1437       372078 :               if (virtual_operand_p (gimple_phi_result (phi)))
    1438              :                 {
    1439        68592 :                   SET_USE (gimple_vuse_op (stmt),
    1440              :                            PHI_ARG_DEF_FROM_EDGE (phi, e));
    1441        68592 :                   break;
    1442              :                 }
    1443              :             }
    1444              :         }
    1445       521420 :       gsi_remove (&bsi, false);
    1446       521420 :       if (gimple_has_lhs (stmt)
    1447       521420 :           && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME
    1448       481272 :           && (!ALWAYS_EXECUTED_IN (bb)
    1449       370183 :               || !(ALWAYS_EXECUTED_IN (bb) == level
    1450        77856 :                    || flow_loop_nested_p (ALWAYS_EXECUTED_IN (bb), level))))
    1451       210985 :         reset_flow_sensitive_info (gimple_get_lhs (stmt));
    1452              :       /* In case this is a stmt that is not unconditionally executed
    1453              :          when the target loop header is executed and the stmt may
    1454              :          invoke undefined integer or pointer overflow rewrite it to
    1455              :          unsigned arithmetic.  */
    1456       521420 :       if (gimple_needing_rewrite_undefined (stmt, true)
    1457       521420 :           && (!ALWAYS_EXECUTED_IN (bb)
    1458        73662 :               || !(ALWAYS_EXECUTED_IN (bb) == level
    1459        19070 :                    || flow_loop_nested_p (ALWAYS_EXECUTED_IN (bb), level))))
    1460        20283 :         gsi_insert_seq_on_edge (e, rewrite_to_defined_unconditional (stmt));
    1461              :       else
    1462       501137 :         gsi_insert_on_edge (e, stmt);
    1463              :     }
    1464              : 
    1465      6293863 :   return todo;
    1466              : }
    1467              : 
    1468              : /* Checks whether the statement defining variable *INDEX can be hoisted
    1469              :    out of the loop passed in DATA.  Callback for for_each_index.  */
    1470              : 
    1471              : static bool
    1472      1788963 : may_move_till (tree ref, tree *index, void *data)
    1473              : {
    1474      1788963 :   class loop *loop = (class loop *) data, *max_loop;
    1475              : 
    1476              :   /* If REF is an array reference, check also that the step and the lower
    1477              :      bound is invariant in LOOP.  */
    1478      1788963 :   if (TREE_CODE (ref) == ARRAY_REF)
    1479              :     {
    1480       470272 :       tree step = TREE_OPERAND (ref, 3);
    1481       470272 :       tree lbound = TREE_OPERAND (ref, 2);
    1482              : 
    1483       470272 :       max_loop = outermost_invariant_loop (step, loop);
    1484       470272 :       if (!max_loop)
    1485              :         return false;
    1486              : 
    1487       470272 :       max_loop = outermost_invariant_loop (lbound, loop);
    1488       470272 :       if (!max_loop)
    1489              :         return false;
    1490              :     }
    1491              : 
    1492      1788963 :   max_loop = outermost_invariant_loop (*index, loop);
    1493      1788963 :   if (!max_loop)
    1494      1148063 :     return false;
    1495              : 
    1496              :   return true;
    1497              : }
    1498              : 
    1499              : /* If OP is SSA NAME, force the statement that defines it to be
    1500              :    moved out of the LOOP.  ORIG_LOOP is the loop in that EXPR is used.  */
    1501              : 
    1502              : static void
    1503        36985 : force_move_till_op (tree op, class loop *orig_loop, class loop *loop)
    1504              : {
    1505        36985 :   gimple *stmt;
    1506              : 
    1507        36985 :   if (!op
    1508        36985 :       || is_gimple_min_invariant (op))
    1509              :     return;
    1510              : 
    1511         4546 :   gcc_assert (TREE_CODE (op) == SSA_NAME);
    1512              : 
    1513         4546 :   stmt = SSA_NAME_DEF_STMT (op);
    1514         4546 :   if (gimple_nop_p (stmt))
    1515              :     return;
    1516              : 
    1517         2946 :   set_level (stmt, orig_loop, loop);
    1518              : }
    1519              : 
    1520              : /* Forces statement defining invariants in REF (and *INDEX) to be moved out of
    1521              :    the LOOP.  The reference REF is used in the loop ORIG_LOOP.  Callback for
    1522              :    for_each_index.  */
    1523              : 
    1524              : struct fmt_data
    1525              : {
    1526              :   class loop *loop;
    1527              :   class loop *orig_loop;
    1528              : };
    1529              : 
    1530              : static bool
    1531        19157 : force_move_till (tree ref, tree *index, void *data)
    1532              : {
    1533        19157 :   struct fmt_data *fmt_data = (struct fmt_data *) data;
    1534              : 
    1535        19157 :   if (TREE_CODE (ref) == ARRAY_REF)
    1536              :     {
    1537         8914 :       tree step = TREE_OPERAND (ref, 3);
    1538         8914 :       tree lbound = TREE_OPERAND (ref, 2);
    1539              : 
    1540         8914 :       force_move_till_op (step, fmt_data->orig_loop, fmt_data->loop);
    1541         8914 :       force_move_till_op (lbound, fmt_data->orig_loop, fmt_data->loop);
    1542              :     }
    1543              : 
    1544        19157 :   force_move_till_op (*index, fmt_data->orig_loop, fmt_data->loop);
    1545              : 
    1546        19157 :   return true;
    1547              : }
    1548              : 
    1549              : /* A function to free the mem_ref object OBJ.  */
    1550              : 
    1551              : static void
    1552      5444730 : memref_free (class im_mem_ref *mem)
    1553              : {
    1554            0 :   mem->accesses_in_loop.release ();
    1555            0 : }
    1556              : 
    1557              : /* Allocates and returns a memory reference description for MEM whose hash
    1558              :    value is HASH and id is ID.  */
    1559              : 
    1560              : static im_mem_ref *
    1561      5444730 : mem_ref_alloc (ao_ref *mem, unsigned hash, unsigned id)
    1562              : {
    1563      5444730 :   im_mem_ref *ref = XOBNEW (&mem_ref_obstack, class im_mem_ref);
    1564      5444730 :   if (mem)
    1565      4472163 :     ref->mem = *mem;
    1566              :   else
    1567       972567 :     ao_ref_init (&ref->mem, error_mark_node);
    1568      5444730 :   ref->id = id;
    1569      5444730 :   ref->ref_canonical = false;
    1570      5444730 :   ref->ref_decomposed = false;
    1571      5444730 :   ref->hash = hash;
    1572      5444730 :   ref->stored = NULL;
    1573      5444730 :   ref->loaded = NULL;
    1574      5444730 :   bitmap_initialize (&ref->dep_loop, &lim_bitmap_obstack);
    1575      5444730 :   ref->accesses_in_loop.create (1);
    1576              : 
    1577      5444730 :   return ref;
    1578              : }
    1579              : 
    1580              : /* Records memory reference location *LOC in LOOP to the memory reference
    1581              :    description REF.  The reference occurs in statement STMT.  */
    1582              : 
    1583              : static void
    1584      5956541 : record_mem_ref_loc (im_mem_ref *ref, gimple *stmt, tree *loc)
    1585              : {
    1586      5956541 :   mem_ref_loc aref;
    1587      5956541 :   aref.stmt = stmt;
    1588      5956541 :   aref.ref = loc;
    1589            0 :   ref->accesses_in_loop.safe_push (aref);
    1590            0 : }
    1591              : 
    1592              : /* Set the LOOP bit in REF stored bitmap and allocate that if
    1593              :    necessary.  Return whether a bit was changed.  */
    1594              : 
    1595              : static bool
    1596      4594052 : set_ref_stored_in_loop (im_mem_ref *ref, class loop *loop)
    1597              : {
    1598      4594052 :   if (!ref->stored)
    1599      2600865 :     ref->stored = BITMAP_ALLOC (&lim_bitmap_obstack);
    1600      4594052 :   return bitmap_set_bit (ref->stored, loop->num);
    1601              : }
    1602              : 
    1603              : /* Marks reference REF as stored in LOOP.  */
    1604              : 
    1605              : static void
    1606      3844829 : mark_ref_stored (im_mem_ref *ref, class loop *loop)
    1607              : {
    1608      3844829 :   while (loop != current_loops->tree_root
    1609      7368319 :          && set_ref_stored_in_loop (ref, loop))
    1610      3523490 :     loop = loop_outer (loop);
    1611      3844829 : }
    1612              : 
    1613              : /* Set the LOOP bit in REF loaded bitmap and allocate that if
    1614              :    necessary.  Return whether a bit was changed.  */
    1615              : 
    1616              : static bool
    1617      6400771 : set_ref_loaded_in_loop (im_mem_ref *ref, class loop *loop)
    1618              : {
    1619      6400771 :   if (!ref->loaded)
    1620      3514190 :     ref->loaded = BITMAP_ALLOC (&lim_bitmap_obstack);
    1621      6400771 :   return bitmap_set_bit (ref->loaded, loop->num);
    1622              : }
    1623              : 
    1624              : /* Marks reference REF as loaded in LOOP.  */
    1625              : 
    1626              : static void
    1627      5130396 : mark_ref_loaded (im_mem_ref *ref, class loop *loop)
    1628              : {
    1629      5130396 :   while (loop != current_loops->tree_root
    1630     10144241 :          && set_ref_loaded_in_loop (ref, loop))
    1631      5013845 :     loop = loop_outer (loop);
    1632      5130396 : }
    1633              : 
    1634              : /* Gathers memory references in statement STMT in LOOP, storing the
    1635              :    information about them in the memory_accesses structure.  Marks
    1636              :    the vops accessed through unrecognized statements there as
    1637              :    well.  */
    1638              : 
    1639              : static void
    1640     48205524 : gather_mem_refs_stmt (class loop *loop, gimple *stmt)
    1641              : {
    1642     48205524 :   tree *mem = NULL;
    1643     48205524 :   hashval_t hash;
    1644     48205524 :   im_mem_ref **slot;
    1645     48205524 :   im_mem_ref *ref;
    1646     48205524 :   bool is_stored;
    1647     48205524 :   unsigned id;
    1648              : 
    1649     64575278 :   if (!gimple_vuse (stmt))
    1650              :     return;
    1651              : 
    1652      7271046 :   mem = simple_mem_ref_in_stmt (stmt, &is_stored);
    1653      7271046 :   if (!mem && is_gimple_assign (stmt))
    1654              :     {
    1655              :       /* For aggregate copies record distinct references but use them
    1656              :          only for disambiguation purposes.  */
    1657       474325 :       id = memory_accesses.refs_list.length ();
    1658       474325 :       ref = mem_ref_alloc (NULL, 0, id);
    1659       474325 :       memory_accesses.refs_list.safe_push (ref);
    1660       474325 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1661              :         {
    1662           30 :           fprintf (dump_file, "Unhandled memory reference %u: ", id);
    1663           30 :           print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    1664              :         }
    1665       474325 :       record_mem_ref_loc (ref, stmt, mem);
    1666       948650 :       is_stored = gimple_vdef (stmt);
    1667              :     }
    1668      6796721 :   else if (!mem)
    1669              :     {
    1670              :       /* We use the shared mem_ref for all unanalyzable refs.  */
    1671      1314505 :       id = UNANALYZABLE_MEM_ID;
    1672      1314505 :       ref = memory_accesses.refs_list[id];
    1673      1314505 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1674              :         {
    1675           21 :           fprintf (dump_file, "Unanalyzed memory reference %u: ", id);
    1676           21 :           print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    1677              :         }
    1678      2629010 :       is_stored = gimple_vdef (stmt);
    1679              :     }
    1680              :   else
    1681              :     {
    1682              :       /* We are looking for equal refs that might differ in structure
    1683              :          such as a.b vs. MEM[&a + 4].  So we key off the ao_ref but
    1684              :          make sure we can canonicalize the ref in the hashtable if
    1685              :          non-operand_equal_p refs are found.  For the lookup we mark
    1686              :          the case we want strict equality with aor.max_size == -1.  */
    1687      5482216 :       ao_ref aor;
    1688      5482216 :       ao_ref_init (&aor, *mem);
    1689      5482216 :       ao_ref_base (&aor);
    1690      5482216 :       ao_ref_alias_set (&aor);
    1691      5482216 :       HOST_WIDE_INT offset, size, max_size;
    1692      5482216 :       poly_int64 saved_maxsize = aor.max_size, mem_off;
    1693      5482216 :       tree mem_base;
    1694      5482216 :       bool ref_decomposed;
    1695      5482216 :       if (aor.max_size_known_p ()
    1696      5298528 :           && aor.offset.is_constant (&offset)
    1697      5298528 :           && aor.size.is_constant (&size)
    1698      5298528 :           && aor.max_size.is_constant (&max_size)
    1699      5298528 :           && size == max_size
    1700      4703034 :           && (size % BITS_PER_UNIT) == 0
    1701              :           /* We're canonicalizing to a MEM where TYPE_SIZE specifies the
    1702              :              size.  Make sure this is consistent with the extraction.  */
    1703      4691389 :           && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (*mem)))
    1704      4691389 :           && known_eq (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (*mem))),
    1705              :                        aor.size)
    1706     10173513 :           && (mem_base = get_addr_base_and_unit_offset (aor.ref, &mem_off)))
    1707              :         {
    1708      4690163 :           ref_decomposed = true;
    1709      4690163 :           tree base = ao_ref_base (&aor);
    1710      4690163 :           poly_int64 moffset;
    1711      4690163 :           HOST_WIDE_INT mcoffset;
    1712      4690163 :           if (TREE_CODE (base) == MEM_REF
    1713      4690163 :               && (mem_ref_offset (base) * BITS_PER_UNIT + offset).to_shwi (&moffset)
    1714      4690163 :               && moffset.is_constant (&mcoffset))
    1715              :             {
    1716      2148177 :               hash = iterative_hash_expr (TREE_OPERAND (base, 0), 0);
    1717      2148177 :               hash = iterative_hash_host_wide_int (mcoffset, hash);
    1718              :             }
    1719              :           else
    1720              :             {
    1721      2541986 :               hash = iterative_hash_expr (base, 0);
    1722      2541986 :               hash = iterative_hash_host_wide_int (offset, hash);
    1723              :             }
    1724      4690163 :           hash = iterative_hash_host_wide_int (size, hash);
    1725              :         }
    1726              :       else
    1727              :         {
    1728       792053 :           ref_decomposed = false;
    1729       792053 :           hash = iterative_hash_expr (aor.ref, 0);
    1730       792053 :           aor.max_size = -1;
    1731              :         }
    1732      5482216 :       slot = memory_accesses.refs->find_slot_with_hash (&aor, hash, INSERT);
    1733      5482216 :       aor.max_size = saved_maxsize;
    1734      5482216 :       if (*slot)
    1735              :         {
    1736      1010053 :           if (!(*slot)->ref_canonical
    1737      1010053 :               && !operand_equal_p (*mem, (*slot)->mem.ref, 0))
    1738              :             {
    1739              :               /* If we didn't yet canonicalize the hashtable ref (which
    1740              :                  we'll end up using for code insertion) and hit a second
    1741              :                  equal ref that is not structurally equivalent create
    1742              :                  a canonical ref which is a bare MEM_REF.  */
    1743        60258 :               if (TREE_CODE (*mem) == MEM_REF
    1744        60258 :                   || TREE_CODE (*mem) == TARGET_MEM_REF)
    1745        17860 :                 (*slot)->mem = aor;
    1746              :               else
    1747              :                 {
    1748        42398 :                   tree ref_alias_type = reference_alias_ptr_type (*mem);
    1749        42398 :                   unsigned int ref_align = get_object_alignment (*mem);
    1750        42398 :                   tree ref_type = TREE_TYPE (*mem);
    1751        42398 :                   tree tmp = build1 (ADDR_EXPR, ptr_type_node,
    1752              :                                      unshare_expr (mem_base));
    1753        42398 :                   if (TYPE_ALIGN (ref_type) != ref_align)
    1754        12343 :                     ref_type = build_aligned_type (ref_type, ref_align);
    1755        42398 :                   tree new_ref
    1756        42398 :                     = fold_build2 (MEM_REF, ref_type, tmp,
    1757              :                                    build_int_cst (ref_alias_type, mem_off));
    1758        42398 :                   if ((*slot)->mem.volatile_p)
    1759           14 :                     TREE_THIS_VOLATILE (new_ref) = 1;
    1760        42398 :                   (*slot)->mem.ref = new_ref;
    1761              :                   /* Make sure the recorded base and offset are consistent
    1762              :                      with the newly built ref.  */
    1763        42398 :                   if (TREE_CODE (TREE_OPERAND (new_ref, 0)) == ADDR_EXPR)
    1764              :                     ;
    1765              :                   else
    1766              :                     {
    1767        22495 :                       (*slot)->mem.base = new_ref;
    1768        22495 :                       (*slot)->mem.offset = 0;
    1769              :                     }
    1770        42398 :                   gcc_checking_assert (TREE_CODE ((*slot)->mem.ref) == MEM_REF
    1771              :                                        && is_gimple_mem_ref_addr
    1772              :                                             (TREE_OPERAND ((*slot)->mem.ref,
    1773              :                                                            0)));
    1774        42398 :                   (*slot)->mem.base_alias_set = (*slot)->mem.ref_alias_set;
    1775              :                 }
    1776        60258 :               (*slot)->ref_canonical = true;
    1777              :             }
    1778      1010053 :           ref = *slot;
    1779      1010053 :           id = ref->id;
    1780              :         }
    1781              :       else
    1782              :         {
    1783      4472163 :           id = memory_accesses.refs_list.length ();
    1784      4472163 :           ref = mem_ref_alloc (&aor, hash, id);
    1785      4472163 :           ref->ref_decomposed = ref_decomposed;
    1786      4472163 :           memory_accesses.refs_list.safe_push (ref);
    1787      4472163 :           *slot = ref;
    1788              : 
    1789      4472163 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1790              :             {
    1791          550 :               fprintf (dump_file, "Memory reference %u: ", id);
    1792          550 :               print_generic_expr (dump_file, ref->mem.ref, TDF_SLIM);
    1793          550 :               fprintf (dump_file, "\n");
    1794              :             }
    1795              :         }
    1796              : 
    1797      5482216 :       record_mem_ref_loc (ref, stmt, mem);
    1798              :     }
    1799      7271046 :   if (is_stored)
    1800              :     {
    1801      3844829 :       bitmap_set_bit (&memory_accesses.refs_stored_in_loop[loop->num], ref->id);
    1802      3844829 :       mark_ref_stored (ref, loop);
    1803              :     }
    1804              :   /* A not simple memory op is also a read when it is a write.  */
    1805      7271046 :   if (!is_stored || id == UNANALYZABLE_MEM_ID
    1806      2614975 :       || ref->mem.ref == error_mark_node)
    1807              :     {
    1808      5130396 :       bitmap_set_bit (&memory_accesses.refs_loaded_in_loop[loop->num], ref->id);
    1809      5130396 :       mark_ref_loaded (ref, loop);
    1810              :     }
    1811      7271046 :   init_lim_data (stmt)->ref = ref->id;
    1812      7271046 :   return;
    1813              : }
    1814              : 
    1815              : static unsigned *bb_loop_postorder;
    1816              : 
    1817              : /* qsort sort function to sort blocks after their loop fathers postorder.  */
    1818              : 
    1819              : static int
    1820    164998334 : sort_bbs_in_loop_postorder_cmp (const void *bb1_, const void *bb2_,
    1821              :                                 void *bb_loop_postorder_)
    1822              : {
    1823    164998334 :   unsigned *bb_loop_postorder = (unsigned *)bb_loop_postorder_;
    1824    164998334 :   basic_block bb1 = *(const basic_block *)bb1_;
    1825    164998334 :   basic_block bb2 = *(const basic_block *)bb2_;
    1826    164998334 :   class loop *loop1 = bb1->loop_father;
    1827    164998334 :   class loop *loop2 = bb2->loop_father;
    1828    164998334 :   if (loop1->num == loop2->num)
    1829     78722346 :     return bb1->index - bb2->index;
    1830     86275988 :   return bb_loop_postorder[loop1->num] < bb_loop_postorder[loop2->num] ? -1 : 1;
    1831              : }
    1832              : 
    1833              : /* qsort sort function to sort ref locs after their loop fathers postorder.  */
    1834              : 
    1835              : static int
    1836      1010038 : sort_locs_in_loop_postorder_cmp (const void *loc1_, const void *loc2_,
    1837              :                                  void *bb_loop_postorder_)
    1838              : {
    1839      1010038 :   unsigned *bb_loop_postorder = (unsigned *)bb_loop_postorder_;
    1840      1010038 :   const mem_ref_loc *loc1 = (const mem_ref_loc *)loc1_;
    1841      1010038 :   const mem_ref_loc *loc2 = (const mem_ref_loc *)loc2_;
    1842      1010038 :   class loop *loop1 = gimple_bb (loc1->stmt)->loop_father;
    1843      1010038 :   class loop *loop2 = gimple_bb (loc2->stmt)->loop_father;
    1844      1010038 :   if (loop1->num == loop2->num)
    1845              :     return 0;
    1846       149238 :   return bb_loop_postorder[loop1->num] < bb_loop_postorder[loop2->num] ? -1 : 1;
    1847              : }
    1848              : 
    1849              : /* Gathers memory references in loops.  */
    1850              : 
    1851              : static void
    1852       498242 : analyze_memory_references (bool store_motion)
    1853              : {
    1854       498242 :   gimple_stmt_iterator bsi;
    1855       498242 :   basic_block bb, *bbs;
    1856       498242 :   class loop *outer;
    1857       498242 :   unsigned i, n;
    1858              : 
    1859              :   /* Collect all basic-blocks in loops and sort them after their
    1860              :      loops postorder.  */
    1861       498242 :   i = 0;
    1862       498242 :   bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS);
    1863     15473690 :   FOR_EACH_BB_FN (bb, cfun)
    1864     14975448 :     if (bb->loop_father != current_loops->tree_root)
    1865      6287655 :       bbs[i++] = bb;
    1866       498242 :   n = i;
    1867       498242 :   gcc_sort_r (bbs, n, sizeof (basic_block), sort_bbs_in_loop_postorder_cmp,
    1868              :               bb_loop_postorder);
    1869              : 
    1870              :   /* Visit blocks in loop postorder and assign mem-ref IDs in that order.
    1871              :      That results in better locality for all the bitmaps.  It also
    1872              :      automatically sorts the location list of gathered memory references
    1873              :      after their loop postorder number allowing to binary-search it.  */
    1874      7284139 :   for (i = 0; i < n; ++i)
    1875              :     {
    1876      6287655 :       basic_block bb = bbs[i];
    1877     60780834 :       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
    1878     48205524 :         gather_mem_refs_stmt (bb->loop_father, gsi_stmt (bsi));
    1879              :     }
    1880              : 
    1881              :   /* Verify the list of gathered memory references is sorted after their
    1882              :      loop postorder number.  */
    1883       498242 :   if (flag_checking)
    1884              :     {
    1885              :       im_mem_ref *ref;
    1886     11387624 :       FOR_EACH_VEC_ELT (memory_accesses.refs_list, i, ref)
    1887      6454736 :         for (unsigned j = 1; j < ref->accesses_in_loop.length (); ++j)
    1888      1010038 :           gcc_assert (sort_locs_in_loop_postorder_cmp
    1889              :                         (&ref->accesses_in_loop[j-1], &ref->accesses_in_loop[j],
    1890              :                          bb_loop_postorder) <= 0);
    1891              :     }
    1892              : 
    1893       498242 :   free (bbs);
    1894              : 
    1895       498242 :   if (!store_motion)
    1896       498242 :     return;
    1897              : 
    1898              :   /* Propagate the information about accessed memory references up
    1899              :      the loop hierarchy.  */
    1900      2833522 :   for (auto loop : loops_list (cfun, LI_FROM_INNERMOST))
    1901              :     {
    1902              :       /* Finalize the overall touched references (including subloops).  */
    1903      1343287 :       bitmap_ior_into (&memory_accesses.all_refs_stored_in_loop[loop->num],
    1904      1343287 :                        &memory_accesses.refs_stored_in_loop[loop->num]);
    1905              : 
    1906              :       /* Propagate the information about accessed memory references up
    1907              :          the loop hierarchy.  */
    1908      1343287 :       outer = loop_outer (loop);
    1909      1343287 :       if (outer == current_loops->tree_root)
    1910      1039648 :         continue;
    1911              : 
    1912       303639 :       bitmap_ior_into (&memory_accesses.all_refs_stored_in_loop[outer->num],
    1913       303639 :                        &memory_accesses.all_refs_stored_in_loop[loop->num]);
    1914       496745 :     }
    1915              : }
    1916              : 
    1917              : /* Returns true if MEM1 and MEM2 may alias.  TTAE_CACHE is used as a cache in
    1918              :    tree_to_aff_combination_expand.  */
    1919              : 
    1920              : static bool
    1921       547389 : mem_refs_may_alias_p (im_mem_ref *mem1, im_mem_ref *mem2,
    1922              :                       hash_map<tree, name_expansion *> **ttae_cache,
    1923              :                       bool tbaa_p)
    1924              : {
    1925       547389 :   gcc_checking_assert (mem1->mem.ref != error_mark_node
    1926              :                        && mem2->mem.ref != error_mark_node);
    1927              : 
    1928              :   /* Perform BASE + OFFSET analysis -- if MEM1 and MEM2 are based on the same
    1929              :      object and their offset differ in such a way that the locations cannot
    1930              :      overlap, then they cannot alias.  */
    1931       547389 :   poly_widest_int size1, size2;
    1932      1094778 :   aff_tree off1, off2;
    1933              : 
    1934              :   /* Perform basic offset and type-based disambiguation.  */
    1935       547389 :   if (!refs_may_alias_p_1 (&mem1->mem, &mem2->mem, tbaa_p))
    1936              :     return false;
    1937              : 
    1938              :   /* The expansion of addresses may be a bit expensive, thus we only do
    1939              :      the check at -O2 and higher optimization levels.  */
    1940        65993 :   if (optimize < 2)
    1941              :     return true;
    1942              : 
    1943        55867 :   get_inner_reference_aff (mem1->mem.ref, &off1, &size1);
    1944        55867 :   get_inner_reference_aff (mem2->mem.ref, &off2, &size2);
    1945        55867 :   aff_combination_expand (&off1, ttae_cache);
    1946        55867 :   aff_combination_expand (&off2, ttae_cache);
    1947        55867 :   aff_combination_scale (&off1, -1);
    1948        55867 :   aff_combination_add (&off2, &off1);
    1949              : 
    1950        55867 :   if (aff_comb_cannot_overlap_p (&off2, size1, size2))
    1951         2407 :     return false;
    1952              : 
    1953              :   return true;
    1954       547389 : }
    1955              : 
    1956              : /* Compare function for bsearch searching for reference locations
    1957              :    in a loop.  */
    1958              : 
    1959              : static int
    1960       270563 : find_ref_loc_in_loop_cmp (const void *loop_, const void *loc_,
    1961              :                           void *bb_loop_postorder_)
    1962              : {
    1963       270563 :   unsigned *bb_loop_postorder = (unsigned *)bb_loop_postorder_;
    1964       270563 :   class loop *loop = (class loop *)const_cast<void *>(loop_);
    1965       270563 :   mem_ref_loc *loc = (mem_ref_loc *)const_cast<void *>(loc_);
    1966       270563 :   class loop *loc_loop = gimple_bb (loc->stmt)->loop_father;
    1967       270563 :   if (loop->num  == loc_loop->num
    1968       270563 :       || flow_loop_nested_p (loop, loc_loop))
    1969              :     return 0;
    1970        61487 :   return (bb_loop_postorder[loop->num] < bb_loop_postorder[loc_loop->num]
    1971        61487 :           ? -1 : 1);
    1972              : }
    1973              : 
    1974              : /* Iterates over all locations of REF in LOOP and its subloops calling
    1975              :    fn.operator() with the location as argument.  When that operator
    1976              :    returns true the iteration is stopped and true is returned.
    1977              :    Otherwise false is returned.  */
    1978              : 
    1979              : template <typename FN>
    1980              : static bool
    1981       209076 : for_all_locs_in_loop (class loop *loop, im_mem_ref *ref, FN fn)
    1982              : {
    1983              :   unsigned i;
    1984              :   mem_ref_loc *loc;
    1985              : 
    1986              :   /* Search for the cluster of locs in the accesses_in_loop vector
    1987              :      which is sorted after postorder index of the loop father.  */
    1988       209076 :   loc = ref->accesses_in_loop.bsearch (loop, find_ref_loc_in_loop_cmp,
    1989              :                                        bb_loop_postorder);
    1990       209076 :   if (!loc)
    1991              :     return false;
    1992              : 
    1993              :   /* We have found one location inside loop or its sub-loops.  Iterate
    1994              :      both forward and backward to cover the whole cluster.  */
    1995       209076 :   i = loc - ref->accesses_in_loop.address ();
    1996       299926 :   while (i > 0)
    1997              :     {
    1998       148874 :       --i;
    1999       148874 :       mem_ref_loc *l = &ref->accesses_in_loop[i];
    2000       148874 :       if (!flow_bb_inside_loop_p (loop, gimple_bb (l->stmt)))
    2001              :         break;
    2002       124536 :       if (fn (l))
    2003              :         return true;
    2004              :     }
    2005       487208 :   for (i = loc - ref->accesses_in_loop.address ();
    2006       311818 :        i < ref->accesses_in_loop.length (); ++i)
    2007              :     {
    2008       231823 :       mem_ref_loc *l = &ref->accesses_in_loop[i];
    2009       231823 :       if (!flow_bb_inside_loop_p (loop, gimple_bb (l->stmt)))
    2010              :         break;
    2011       212191 :       if (fn (l))
    2012              :         return true;
    2013              :     }
    2014              : 
    2015              :   return false;
    2016              : }
    2017              : 
    2018              : /* Rewrites location LOC by TMP_VAR.  */
    2019              : 
    2020              : class rewrite_mem_ref_loc
    2021              : {
    2022              : public:
    2023        34299 :   rewrite_mem_ref_loc (tree tmp_var_) : tmp_var (tmp_var_) {}
    2024              :   bool operator () (mem_ref_loc *loc);
    2025              :   tree tmp_var;
    2026              : };
    2027              : 
    2028              : bool
    2029        54196 : rewrite_mem_ref_loc::operator () (mem_ref_loc *loc)
    2030              : {
    2031        54196 :   *loc->ref = tmp_var;
    2032        54196 :   update_stmt (loc->stmt);
    2033        54196 :   return false;
    2034              : }
    2035              : 
    2036              : /* Rewrites all references to REF in LOOP by variable TMP_VAR.  */
    2037              : 
    2038              : static void
    2039        34299 : rewrite_mem_refs (class loop *loop, im_mem_ref *ref, tree tmp_var)
    2040              : {
    2041            0 :   for_all_locs_in_loop (loop, ref, rewrite_mem_ref_loc (tmp_var));
    2042            0 : }
    2043              : 
    2044              : /* Stores the first reference location in LOCP.  */
    2045              : 
    2046              : class first_mem_ref_loc_1
    2047              : {
    2048              : public:
    2049        34299 :   first_mem_ref_loc_1 (mem_ref_loc **locp_) : locp (locp_) {}
    2050              :   bool operator () (mem_ref_loc *loc);
    2051              :   mem_ref_loc **locp;
    2052              : };
    2053              : 
    2054              : bool
    2055        34299 : first_mem_ref_loc_1::operator () (mem_ref_loc *loc)
    2056              : {
    2057        34299 :   *locp = loc;
    2058        34299 :   return true;
    2059              : }
    2060              : 
    2061              : /* Returns the first reference location to REF in LOOP.  */
    2062              : 
    2063              : static mem_ref_loc *
    2064        34299 : first_mem_ref_loc (class loop *loop, im_mem_ref *ref)
    2065              : {
    2066        34299 :   mem_ref_loc *locp = NULL;
    2067            0 :   for_all_locs_in_loop (loop, ref, first_mem_ref_loc_1 (&locp));
    2068        34299 :   return locp;
    2069              : }
    2070              : 
    2071              : /* Helper function for execute_sm.  Emit code to store TMP_VAR into
    2072              :    MEM along edge EX.
    2073              : 
    2074              :    The store is only done if MEM has changed.  We do this so no
    2075              :    changes to MEM occur on code paths that did not originally store
    2076              :    into it.
    2077              : 
    2078              :    The common case for execute_sm will transform:
    2079              : 
    2080              :      for (...) {
    2081              :        if (foo)
    2082              :          stuff;
    2083              :        else
    2084              :          MEM = TMP_VAR;
    2085              :      }
    2086              : 
    2087              :    into:
    2088              : 
    2089              :      lsm = MEM;
    2090              :      for (...) {
    2091              :        if (foo)
    2092              :          stuff;
    2093              :        else
    2094              :          lsm = TMP_VAR;
    2095              :      }
    2096              :      MEM = lsm;
    2097              : 
    2098              :   This function will generate:
    2099              : 
    2100              :      lsm = MEM;
    2101              : 
    2102              :      lsm_flag = false;
    2103              :      ...
    2104              :      for (...) {
    2105              :        if (foo)
    2106              :          stuff;
    2107              :        else {
    2108              :          lsm = TMP_VAR;
    2109              :          lsm_flag = true;
    2110              :        }
    2111              :      }
    2112              :      if (lsm_flag)      <--
    2113              :        MEM = lsm;       <-- (X)
    2114              : 
    2115              :   In case MEM and TMP_VAR are NULL the function will return the then
    2116              :   block so the caller can insert (X) and other related stmts.
    2117              : */
    2118              : 
    2119              : static basic_block
    2120        11850 : execute_sm_if_changed (edge ex, tree mem, tree tmp_var, tree flag,
    2121              :                        edge preheader, hash_set <basic_block> *flag_bbs,
    2122              :                        edge &append_cond_position, edge &last_cond_fallthru)
    2123              : {
    2124        11850 :   basic_block new_bb, then_bb, old_dest;
    2125        11850 :   bool loop_has_only_one_exit;
    2126        11850 :   edge then_old_edge;
    2127        11850 :   gimple_stmt_iterator gsi;
    2128        11850 :   gimple *stmt;
    2129        11850 :   bool irr = ex->flags & EDGE_IRREDUCIBLE_LOOP;
    2130              : 
    2131        11850 :   profile_count count_sum = profile_count::zero ();
    2132        11850 :   int nbbs = 0, ncount = 0;
    2133        11850 :   profile_probability flag_probability = profile_probability::uninitialized ();
    2134              : 
    2135              :   /* Flag is set in FLAG_BBS. Determine probability that flag will be true
    2136              :      at loop exit.
    2137              : 
    2138              :      This code may look fancy, but it cannot update profile very realistically
    2139              :      because we do not know the probability that flag will be true at given
    2140              :      loop exit.
    2141              : 
    2142              :      We look for two interesting extremes
    2143              :        - when exit is dominated by block setting the flag, we know it will
    2144              :          always be true.  This is a common case.
    2145              :        - when all blocks setting the flag have very low frequency we know
    2146              :          it will likely be false.
    2147              :      In all other cases we default to 2/3 for flag being true.  */
    2148              : 
    2149        11850 :   for (hash_set<basic_block>::iterator it = flag_bbs->begin ();
    2150        26723 :        it != flag_bbs->end (); ++it)
    2151              :     {
    2152        14873 :        if ((*it)->count.initialized_p ())
    2153        14860 :          count_sum += (*it)->count, ncount ++;
    2154        14873 :        if (dominated_by_p (CDI_DOMINATORS, ex->src, *it))
    2155         2437 :          flag_probability = profile_probability::always ();
    2156        14873 :        nbbs++;
    2157              :     }
    2158              : 
    2159        11850 :   profile_probability cap
    2160        11850 :           = profile_probability::guessed_always ().apply_scale (2, 3);
    2161              : 
    2162        11850 :   if (flag_probability.initialized_p ())
    2163              :     ;
    2164         9520 :   else if (ncount == nbbs
    2165        19231 :            && preheader->count () >= count_sum && preheader->count ().nonzero_p ())
    2166              :     {
    2167          172 :       flag_probability = count_sum.probability_in (preheader->count ());
    2168          172 :       if (flag_probability > cap)
    2169           77 :         flag_probability = cap;
    2170              :     }
    2171              : 
    2172        11850 :   if (!flag_probability.initialized_p ())
    2173         9348 :     flag_probability = cap;
    2174              : 
    2175              :   /* ?? Insert store after previous store if applicable.  See note
    2176              :      below.  */
    2177        11850 :   if (append_cond_position)
    2178         4131 :     ex = append_cond_position;
    2179              : 
    2180        11850 :   loop_has_only_one_exit = single_pred_p (ex->dest);
    2181              : 
    2182        11850 :   if (loop_has_only_one_exit)
    2183         5012 :     ex = split_block_after_labels (ex->dest);
    2184              :   else
    2185              :     {
    2186         6838 :       for (gphi_iterator gpi = gsi_start_phis (ex->dest);
    2187        10540 :            !gsi_end_p (gpi); gsi_next (&gpi))
    2188              :         {
    2189         4476 :           gphi *phi = gpi.phi ();
    2190         8952 :           if (virtual_operand_p (gimple_phi_result (phi)))
    2191         3702 :             continue;
    2192              : 
    2193              :           /* When the destination has a non-virtual PHI node with multiple
    2194              :              predecessors make sure we preserve the PHI structure by
    2195              :              forcing a forwarder block so that hoisting of that PHI will
    2196              :              still work.  */
    2197          774 :           split_edge (ex);
    2198          774 :           break;
    2199              :         }
    2200              :     }
    2201              : 
    2202        11850 :   old_dest = ex->dest;
    2203        11850 :   new_bb = split_edge (ex);
    2204        11850 :   if (append_cond_position)
    2205         4131 :     new_bb->count += last_cond_fallthru->count ();
    2206        11850 :   then_bb = create_empty_bb (new_bb);
    2207        11850 :   then_bb->count = new_bb->count.apply_probability (flag_probability);
    2208        11850 :   if (irr)
    2209           49 :     then_bb->flags = BB_IRREDUCIBLE_LOOP;
    2210        11850 :   add_bb_to_loop (then_bb, new_bb->loop_father);
    2211              : 
    2212        11850 :   gsi = gsi_start_bb (new_bb);
    2213        11850 :   stmt = gimple_build_cond (NE_EXPR, flag, boolean_false_node,
    2214              :                             NULL_TREE, NULL_TREE);
    2215        11850 :   gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
    2216              : 
    2217              :   /* Insert actual store.  */
    2218        11850 :   if (mem)
    2219              :     {
    2220         9602 :       gsi = gsi_start_bb (then_bb);
    2221         9602 :       stmt = gimple_build_assign (unshare_expr (mem), tmp_var);
    2222         9602 :       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
    2223              :     }
    2224              : 
    2225        11850 :   edge e1 = single_succ_edge (new_bb);
    2226        23651 :   edge e2 = make_edge (new_bb, then_bb,
    2227              :                        EDGE_TRUE_VALUE | (irr ? EDGE_IRREDUCIBLE_LOOP : 0));
    2228        11850 :   e2->probability = flag_probability;
    2229              : 
    2230        11850 :   e1->flags |= EDGE_FALSE_VALUE | (irr ? EDGE_IRREDUCIBLE_LOOP : 0);
    2231        11850 :   e1->flags &= ~EDGE_FALLTHRU;
    2232              : 
    2233        11850 :   e1->probability = flag_probability.invert ();
    2234              : 
    2235        23651 :   then_old_edge = make_single_succ_edge (then_bb, old_dest,
    2236              :                              EDGE_FALLTHRU | (irr ? EDGE_IRREDUCIBLE_LOOP : 0));
    2237              : 
    2238        11850 :   set_immediate_dominator (CDI_DOMINATORS, then_bb, new_bb);
    2239              : 
    2240        11850 :   if (append_cond_position)
    2241              :     {
    2242         4131 :       basic_block prevbb = last_cond_fallthru->src;
    2243         4131 :       redirect_edge_succ (last_cond_fallthru, new_bb);
    2244         4131 :       set_immediate_dominator (CDI_DOMINATORS, new_bb, prevbb);
    2245         4131 :       set_immediate_dominator (CDI_DOMINATORS, old_dest,
    2246              :                                recompute_dominator (CDI_DOMINATORS, old_dest));
    2247              :     }
    2248              : 
    2249              :   /* ?? Because stores may alias, they must happen in the exact
    2250              :      sequence they originally happened.  Save the position right after
    2251              :      the (_lsm) store we just created so we can continue appending after
    2252              :      it and maintain the original order.  */
    2253        11850 :   append_cond_position = then_old_edge;
    2254        11850 :   last_cond_fallthru = find_edge (new_bb, old_dest);
    2255              : 
    2256        11850 :   if (!loop_has_only_one_exit)
    2257         6838 :     for (gphi_iterator gpi = gsi_start_phis (old_dest);
    2258        10386 :          !gsi_end_p (gpi); gsi_next (&gpi))
    2259              :       {
    2260         3548 :         gphi *phi = gpi.phi ();
    2261         3548 :         unsigned i;
    2262              : 
    2263        23492 :         for (i = 0; i < gimple_phi_num_args (phi); i++)
    2264        16396 :           if (gimple_phi_arg_edge (phi, i)->src == new_bb)
    2265              :             {
    2266         3548 :               tree arg = gimple_phi_arg_def (phi, i);
    2267         3548 :               add_phi_arg (phi, arg, then_old_edge, UNKNOWN_LOCATION);
    2268         3548 :               update_stmt (phi);
    2269              :             }
    2270              :       }
    2271              : 
    2272        11850 :   return then_bb;
    2273              : }
    2274              : 
    2275              : /* When REF is set on the location, set flag indicating the store.  */
    2276              : 
    2277              : class sm_set_flag_if_changed
    2278              : {
    2279              : public:
    2280         6735 :   sm_set_flag_if_changed (tree flag_, hash_set <basic_block> *bbs_)
    2281         6735 :          : flag (flag_), bbs (bbs_) {}
    2282              :   bool operator () (mem_ref_loc *loc);
    2283              :   tree flag;
    2284              :   hash_set <basic_block> *bbs;
    2285              : };
    2286              : 
    2287              : bool
    2288        12493 : sm_set_flag_if_changed::operator () (mem_ref_loc *loc)
    2289              : {
    2290              :   /* Only set the flag for writes.  */
    2291        12493 :   if (is_gimple_assign (loc->stmt)
    2292        12493 :       && gimple_assign_lhs_ptr (loc->stmt) == loc->ref)
    2293              :     {
    2294         7755 :       gimple_stmt_iterator gsi = gsi_for_stmt (loc->stmt);
    2295         7755 :       gimple *stmt = gimple_build_assign (flag, boolean_true_node);
    2296         7755 :       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
    2297         7755 :       bbs->add (gimple_bb (stmt));
    2298              :     }
    2299        12493 :   return false;
    2300              : }
    2301              : 
    2302              : /* Helper function for execute_sm.  On every location where REF is
    2303              :    set, set an appropriate flag indicating the store.  */
    2304              : 
    2305              : static tree
    2306         6735 : execute_sm_if_changed_flag_set (class loop *loop, im_mem_ref *ref,
    2307              :                                 hash_set <basic_block> *bbs)
    2308              : {
    2309         6735 :   tree flag;
    2310         6735 :   char *str = get_lsm_tmp_name (ref->mem.ref, ~0, "_flag");
    2311         6735 :   flag = create_tmp_reg (boolean_type_node, str);
    2312         6735 :   for_all_locs_in_loop (loop, ref, sm_set_flag_if_changed (flag, bbs));
    2313         6735 :   return flag;
    2314              : }
    2315              : 
    2316        34299 : struct sm_aux
    2317              : {
    2318              :   tree tmp_var;
    2319              :   tree store_flag;
    2320              :   hash_set <basic_block> flag_bbs;
    2321              : };
    2322              : 
    2323              : /* Executes store motion of memory reference REF from LOOP.
    2324              :    Exits from the LOOP are stored in EXITS.  The initialization of the
    2325              :    temporary variable is put to the preheader of the loop, and assignments
    2326              :    to the reference from the temporary variable are emitted to exits.  */
    2327              : 
    2328              : static sm_aux *
    2329        34299 : execute_sm (class loop *loop, im_mem_ref *ref,
    2330              :             hash_map<im_mem_ref *, sm_aux *> &aux_map, bool maybe_mt,
    2331              :             bool use_other_flag_var)
    2332              : {
    2333        34299 :   gassign *load;
    2334        34299 :   struct fmt_data fmt_data;
    2335        34299 :   struct lim_aux_data *lim_data;
    2336        34299 :   bool multi_threaded_model_p = false;
    2337        34299 :   gimple_stmt_iterator gsi;
    2338        34299 :   sm_aux *aux = new sm_aux;
    2339              : 
    2340        34299 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2341              :     {
    2342           82 :       fprintf (dump_file, "Executing store motion of ");
    2343           82 :       print_generic_expr (dump_file, ref->mem.ref);
    2344           82 :       fprintf (dump_file, " from loop %d\n", loop->num);
    2345              :     }
    2346              : 
    2347        34299 :   aux->tmp_var = create_tmp_reg (TREE_TYPE (ref->mem.ref),
    2348        34299 :                                  get_lsm_tmp_name (ref->mem.ref, ~0));
    2349              : 
    2350        34299 :   fmt_data.loop = loop;
    2351        34299 :   fmt_data.orig_loop = loop;
    2352        34299 :   for_each_index (&ref->mem.ref, force_move_till, &fmt_data);
    2353              : 
    2354        68598 :   bool always_stored = ref_always_stored_p (loop, ref);
    2355        34299 :   if (maybe_mt
    2356        10792 :       && (bb_in_transaction (loop_preheader_edge (loop)->src)
    2357        10791 :           || (ref_can_have_store_data_races (ref->mem.ref) && ! always_stored)
    2358              :           /* Do not speculate a load/store when that's not a noop, either
    2359              :              because the mode cannot be transferred or because there's
    2360              :              UB involved for out-of-bound values.  */
    2361         3794 :           || !mode_can_transfer_bits (TYPE_MODE (TREE_TYPE (ref->mem.ref)))
    2362         3794 :           || TREE_CODE (TREE_TYPE (ref->mem.ref)) == BOOLEAN_TYPE
    2363         3783 :           || (TREE_CODE (ref->mem.ref) == COMPONENT_REF
    2364          882 :               && DECL_BIT_FIELD (TREE_OPERAND (ref->mem.ref, 1)))))
    2365              :     multi_threaded_model_p = true;
    2366              : 
    2367        34299 :   if (multi_threaded_model_p && !use_other_flag_var)
    2368         6735 :     aux->store_flag
    2369         6735 :       = execute_sm_if_changed_flag_set (loop, ref, &aux->flag_bbs);
    2370              :   else
    2371              :     aux->store_flag = NULL_TREE;
    2372              : 
    2373              :   /* Remember variable setup.  */
    2374        34299 :   aux_map.put (ref, aux);
    2375              : 
    2376        34299 :   rewrite_mem_refs (loop, ref, aux->tmp_var);
    2377              : 
    2378              :   /* Emit the load code on a random exit edge or into the latch if
    2379              :      the loop does not exit, so that we are sure it will be processed
    2380              :      by move_computations after all dependencies.  */
    2381        34299 :   gsi = gsi_for_stmt (first_mem_ref_loc (loop, ref)->stmt);
    2382              : 
    2383              :   /* Avoid doing a load if there was no load of the ref in the loop.
    2384              :      Esp. when the ref is not always stored we cannot optimize it
    2385              :      away later.  But when it is not always stored we must use a conditional
    2386              :      store then.  */
    2387        34299 :   if ((!always_stored && !multi_threaded_model_p)
    2388        34299 :       || (ref->loaded && bitmap_bit_p (ref->loaded, loop->num)))
    2389        17542 :     load = gimple_build_assign (aux->tmp_var, unshare_expr (ref->mem.ref));
    2390              :   else
    2391              :     {
    2392              :       /* If not emitting a load mark the uninitialized state on the
    2393              :          loop entry as not to be warned for.  */
    2394        16757 :       tree uninit = create_tmp_reg (TREE_TYPE (aux->tmp_var));
    2395        16757 :       suppress_warning (uninit, OPT_Wuninitialized);
    2396        16757 :       uninit = get_or_create_ssa_default_def (cfun, uninit);
    2397        16757 :       load = gimple_build_assign (aux->tmp_var, uninit);
    2398              :     }
    2399        34299 :   lim_data = init_lim_data (load);
    2400        34299 :   lim_data->max_loop = loop;
    2401        34299 :   lim_data->tgt_loop = loop;
    2402        34299 :   gsi_insert_before (&gsi, load, GSI_SAME_STMT);
    2403              : 
    2404        34299 :   if (aux->store_flag)
    2405              :     {
    2406         6735 :       load = gimple_build_assign (aux->store_flag, boolean_false_node);
    2407         6735 :       lim_data = init_lim_data (load);
    2408         6735 :       lim_data->max_loop = loop;
    2409         6735 :       lim_data->tgt_loop = loop;
    2410         6735 :       gsi_insert_before (&gsi, load, GSI_SAME_STMT);
    2411              :     }
    2412              : 
    2413        34299 :   return aux;
    2414              : }
    2415              : 
    2416              : /* sm_ord is used for ordinary stores we can retain order with respect
    2417              :        to other stores
    2418              :    sm_unord is used for conditional executed stores which need to be
    2419              :        able to execute in arbitrary order with respect to other stores
    2420              :    sm_other is used for stores we do not try to apply store motion to.  */
    2421              : enum sm_kind { sm_ord, sm_unord, sm_other };
    2422              : struct seq_entry
    2423              : {
    2424              :   seq_entry () = default;
    2425        50761 :   seq_entry (unsigned f, sm_kind k, tree fr = NULL)
    2426        50761 :     : first (f), second (k), from (fr) {}
    2427              :   unsigned first;
    2428              :   sm_kind second;
    2429              :   tree from;
    2430              : };
    2431              : 
    2432              : static void
    2433        31707 : execute_sm_exit (class loop *loop, edge ex, vec<seq_entry> &seq,
    2434              :                  hash_map<im_mem_ref *, sm_aux *> &aux_map, sm_kind kind,
    2435              :                  edge &append_cond_position, edge &last_cond_fallthru,
    2436              :                  bitmap clobbers_to_prune)
    2437              : {
    2438              :   /* Sink the stores to exit from the loop.  */
    2439       111148 :   for (unsigned i = seq.length (); i > 0; --i)
    2440              :     {
    2441        47734 :       im_mem_ref *ref = memory_accesses.refs_list[seq[i-1].first];
    2442        47734 :       if (seq[i-1].second == sm_other)
    2443              :         {
    2444         4845 :           gcc_assert (kind == sm_ord && seq[i-1].from != NULL_TREE);
    2445         4845 :           gassign *store;
    2446         4845 :           if (ref->mem.ref == error_mark_node)
    2447              :             {
    2448          183 :               tree lhs = gimple_assign_lhs (ref->accesses_in_loop[0].stmt);
    2449          183 :               if (dump_file && (dump_flags & TDF_DETAILS))
    2450              :                 {
    2451            3 :                   fprintf (dump_file, "Re-issuing dependent ");
    2452            3 :                   print_generic_expr (dump_file, unshare_expr (seq[i-1].from));
    2453            3 :                   fprintf (dump_file, " of ");
    2454            3 :                   print_generic_expr (dump_file, lhs);
    2455            3 :                   fprintf (dump_file, " from loop %d on exit %d -> %d\n",
    2456            3 :                            loop->num, ex->src->index, ex->dest->index);
    2457              :                 }
    2458          183 :               store = gimple_build_assign (unshare_expr (lhs),
    2459          183 :                                            unshare_expr (seq[i-1].from));
    2460          183 :               bitmap_set_bit (clobbers_to_prune, seq[i-1].first);
    2461              :             }
    2462              :           else
    2463              :             {
    2464         4662 :               if (dump_file && (dump_flags & TDF_DETAILS))
    2465              :                 {
    2466            0 :                   fprintf (dump_file, "Re-issuing dependent store of ");
    2467            0 :                   print_generic_expr (dump_file, ref->mem.ref);
    2468            0 :                   fprintf (dump_file, " from loop %d on exit %d -> %d\n",
    2469            0 :                            loop->num, ex->src->index, ex->dest->index);
    2470              :                 }
    2471         4662 :               store = gimple_build_assign (unshare_expr (ref->mem.ref),
    2472         4662 :                                            seq[i-1].from);
    2473              :             }
    2474         4845 :           gsi_insert_on_edge (ex, store);
    2475              :         }
    2476              :       else
    2477              :         {
    2478        42889 :           sm_aux *aux = *aux_map.get (ref);
    2479        42889 :           if (!aux->store_flag || kind == sm_ord)
    2480              :             {
    2481        33287 :               gassign *store;
    2482        33287 :               store = gimple_build_assign (unshare_expr (ref->mem.ref),
    2483              :                                            aux->tmp_var);
    2484        33287 :               gsi_insert_on_edge (ex, store);
    2485        33287 :             }
    2486              :           else
    2487         9602 :             execute_sm_if_changed (ex, ref->mem.ref, aux->tmp_var,
    2488              :                                    aux->store_flag,
    2489              :                                    loop_preheader_edge (loop), &aux->flag_bbs,
    2490              :                                    append_cond_position, last_cond_fallthru);
    2491              :         }
    2492              :     }
    2493        31707 : }
    2494              : 
    2495              : /* Push the SM candidate at index PTR in the sequence SEQ down until
    2496              :    we hit the next SM candidate.  Return true if that went OK and
    2497              :    false if we could not disambiguate against another unrelated ref.
    2498              :    Update *AT to the index where the candidate now resides.  */
    2499              : 
    2500              : static bool
    2501        37440 : sm_seq_push_down (vec<seq_entry> &seq, unsigned ptr, unsigned *at)
    2502              : {
    2503        37440 :   *at = ptr;
    2504        38181 :   for (; ptr > 0; --ptr)
    2505              :     {
    2506        17612 :       seq_entry &new_cand = seq[ptr];
    2507        17612 :       seq_entry &against = seq[ptr-1];
    2508        17612 :       if (against.second == sm_ord
    2509         5722 :           || (against.second == sm_other && against.from != NULL_TREE))
    2510              :         /* Found the tail of the sequence.  */
    2511              :         break;
    2512              :       /* We may not ignore self-dependences here.  */
    2513         1048 :       if (new_cand.first == against.first
    2514              :           /* ???  We could actually handle clobbers here, but not easily
    2515              :              with LIMs dependence analysis.  */
    2516          826 :           || (memory_accesses.refs_list[new_cand.first]->mem.ref
    2517          826 :               == error_mark_node)
    2518          821 :           || (memory_accesses.refs_list[against.first]->mem.ref
    2519              :               == error_mark_node)
    2520         1845 :           || !refs_independent_p (memory_accesses.refs_list[new_cand.first],
    2521          797 :                                   memory_accesses.refs_list[against.first],
    2522              :                                   false))
    2523              :         /* ???  Prune new_cand from the list of refs to apply SM to.  */
    2524              :         return false;
    2525          741 :       std::swap (new_cand, against);
    2526          741 :       *at = ptr - 1;
    2527              :     }
    2528              :   return true;
    2529              : }
    2530              : 
    2531              : /* Computes the sequence of stores from candidates in REFS_NOT_IN_SEQ to SEQ
    2532              :    walking backwards from VDEF (or the end of BB if VDEF is NULL).  */
    2533              : 
    2534              : static int
    2535        29707 : sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
    2536              :                  vec<seq_entry> &seq, bitmap refs_not_in_seq,
    2537              :                  bitmap refs_not_supported, bool forked,
    2538              :                  bitmap fully_visited)
    2539              : {
    2540        34525 :   if (!vdef)
    2541       139118 :     for (gimple_stmt_iterator gsi = gsi_last_bb (bb); !gsi_end_p (gsi);
    2542        87244 :          gsi_prev (&gsi))
    2543              :       {
    2544       138800 :         vdef = gimple_vdef (gsi_stmt (gsi));
    2545        51556 :         if (vdef)
    2546              :           break;
    2547              :       }
    2548        25937 :   if (!vdef)
    2549              :     {
    2550         8019 :       gphi *vphi = get_virtual_phi (bb);
    2551         8019 :       if (vphi)
    2552         3952 :         vdef = gimple_phi_result (vphi);
    2553              :     }
    2554        34525 :   if (!vdef)
    2555              :     {
    2556         4067 :       if (single_pred_p (bb))
    2557              :         /* This handles the perfect nest case.  */
    2558         3289 :         return sm_seq_valid_bb (loop, single_pred (bb), vdef,
    2559              :                                 seq, refs_not_in_seq, refs_not_supported,
    2560         3289 :                                 forked, fully_visited);
    2561              :       return 0;
    2562              :     }
    2563        77404 :   do
    2564              :     {
    2565        53931 :       gimple *def = SSA_NAME_DEF_STMT (vdef);
    2566        53931 :       if (gimple_bb (def) != bb)
    2567              :         {
    2568              :           /* If we forked by processing a PHI do not allow our walk to
    2569              :              merge again until we handle that robustly.  */
    2570         2968 :           if (forked)
    2571              :             {
    2572              :               /* Mark refs_not_in_seq as unsupported.  */
    2573         1261 :               bitmap_ior_into (refs_not_supported, refs_not_in_seq);
    2574         1261 :               return 1;
    2575              :             }
    2576              :           /* Otherwise it doesn't really matter if we end up in different
    2577              :              BBs.  */
    2578              :           bb = gimple_bb (def);
    2579              :         }
    2580        52670 :       if (gphi *phi = dyn_cast <gphi *> (def))
    2581              :         {
    2582              :           /* Handle CFG merges.  Until we handle forks (gimple_bb (def) != bb)
    2583              :              this is still linear.
    2584              :              Eventually we want to cache intermediate results per BB
    2585              :              (but we can't easily cache for different exits?).  */
    2586              :           /* Stop at PHIs with possible backedges.  */
    2587        10080 :           if (bb == bb->loop_father->header
    2588         5099 :               || bb->flags & BB_IRREDUCIBLE_LOOP)
    2589              :             {
    2590              :               /* Mark refs_not_in_seq as unsupported.  */
    2591         4986 :               bitmap_ior_into (refs_not_supported, refs_not_in_seq);
    2592         4986 :               return 1;
    2593              :             }
    2594         5094 :           if (gimple_phi_num_args (phi) == 1)
    2595         1529 :             return sm_seq_valid_bb (loop, gimple_phi_arg_edge (phi, 0)->src,
    2596              :                                     gimple_phi_arg_def (phi, 0), seq,
    2597              :                                     refs_not_in_seq, refs_not_supported,
    2598         1529 :                                     false, fully_visited);
    2599         7130 :           if (bitmap_bit_p (fully_visited,
    2600         3565 :                             SSA_NAME_VERSION (gimple_phi_result (phi))))
    2601              :             return 1;
    2602         3461 :           auto_vec<seq_entry> first_edge_seq;
    2603         3461 :           auto_bitmap tem_refs_not_in_seq (&lim_bitmap_obstack);
    2604         3461 :           int eret;
    2605         3461 :           bitmap_copy (tem_refs_not_in_seq, refs_not_in_seq);
    2606         3461 :           eret = sm_seq_valid_bb (loop, gimple_phi_arg_edge (phi, 0)->src,
    2607              :                                   gimple_phi_arg_def (phi, 0),
    2608              :                                   first_edge_seq,
    2609              :                                   tem_refs_not_in_seq, refs_not_supported,
    2610              :                                   true, fully_visited);
    2611         3461 :           if (eret != 1)
    2612              :             return -1;
    2613              :           /* Simplify our lives by pruning the sequence of !sm_ord.  */
    2614         3279 :           while (!first_edge_seq.is_empty ()
    2615         7922 :                  && first_edge_seq.last ().second != sm_ord)
    2616         1182 :             first_edge_seq.pop ();
    2617         7059 :           for (unsigned int i = 1; i < gimple_phi_num_args (phi); ++i)
    2618              :             {
    2619         5513 :               tree vuse = gimple_phi_arg_def (phi, i);
    2620         5513 :               edge e = gimple_phi_arg_edge (phi, i);
    2621         5513 :               auto_vec<seq_entry> edge_seq;
    2622         5513 :               bitmap_and_compl (tem_refs_not_in_seq,
    2623              :                                 refs_not_in_seq, refs_not_supported);
    2624              :               /* If we've marked all refs we search for as unsupported
    2625              :                  we can stop processing and use the sequence as before
    2626              :                  the PHI.  */
    2627         5513 :               if (bitmap_empty_p (tem_refs_not_in_seq))
    2628              :                 return 1;
    2629         3598 :               eret = sm_seq_valid_bb (loop, e->src, vuse, edge_seq,
    2630              :                                       tem_refs_not_in_seq, refs_not_supported,
    2631              :                                       true, fully_visited);
    2632         3598 :               if (eret != 1)
    2633              :                 return -1;
    2634              :               /* Simplify our lives by pruning the sequence of !sm_ord.  */
    2635         3162 :               while (!edge_seq.is_empty ()
    2636         7810 :                      && edge_seq.last ().second != sm_ord)
    2637         1050 :                 edge_seq.pop ();
    2638         7196 :               unsigned min_len = MIN(first_edge_seq.length (),
    2639              :                                      edge_seq.length ());
    2640              :               /* Incrementally merge seqs into first_edge_seq.  */
    2641         3598 :               int first_uneq = -1;
    2642         3598 :               auto_vec<seq_entry, 2> extra_refs;
    2643         5758 :               for (unsigned int i = 0; i < min_len; ++i)
    2644              :                 {
    2645              :                   /* ???  We can more intelligently merge when we face different
    2646              :                      order by additional sinking operations in one sequence.
    2647              :                      For now we simply mark them as to be processed by the
    2648              :                      not order-preserving SM code.  */
    2649         2160 :                   if (first_edge_seq[i].first != edge_seq[i].first)
    2650              :                     {
    2651           34 :                       if (first_edge_seq[i].second == sm_ord)
    2652           21 :                         bitmap_set_bit (refs_not_supported,
    2653           21 :                                         first_edge_seq[i].first);
    2654           34 :                       if (edge_seq[i].second == sm_ord)
    2655           26 :                         bitmap_set_bit (refs_not_supported, edge_seq[i].first);
    2656           34 :                       first_edge_seq[i].second = sm_other;
    2657           34 :                       first_edge_seq[i].from = NULL_TREE;
    2658              :                       /* Record the dropped refs for later processing.  */
    2659           34 :                       if (first_uneq == -1)
    2660           32 :                         first_uneq = i;
    2661           68 :                       extra_refs.safe_push (seq_entry (edge_seq[i].first,
    2662           34 :                                                        sm_other, NULL_TREE));
    2663              :                     }
    2664              :                   /* sm_other prevails.  */
    2665         2126 :                   else if (first_edge_seq[i].second != edge_seq[i].second)
    2666              :                     {
    2667              :                       /* Make sure the ref is marked as not supported.  */
    2668            0 :                       bitmap_set_bit (refs_not_supported,
    2669            0 :                                       first_edge_seq[i].first);
    2670            0 :                       first_edge_seq[i].second = sm_other;
    2671            0 :                       first_edge_seq[i].from = NULL_TREE;
    2672              :                     }
    2673         2126 :                   else if (first_edge_seq[i].second == sm_other
    2674            4 :                            && first_edge_seq[i].from != NULL_TREE
    2675         2130 :                            && (edge_seq[i].from == NULL_TREE
    2676            4 :                                || !operand_equal_p (first_edge_seq[i].from,
    2677            4 :                                                     edge_seq[i].from, 0)))
    2678            4 :                     first_edge_seq[i].from = NULL_TREE;
    2679              :                 }
    2680              :               /* Any excess elements become sm_other since they are now
    2681              :                  coonditionally executed.  */
    2682         9890 :               if (first_edge_seq.length () > edge_seq.length ())
    2683              :                 {
    2684         6464 :                   for (unsigned i = edge_seq.length ();
    2685         8269 :                        i < first_edge_seq.length (); ++i)
    2686              :                     {
    2687         6464 :                       if (first_edge_seq[i].second == sm_ord)
    2688         3342 :                         bitmap_set_bit (refs_not_supported,
    2689         3342 :                                         first_edge_seq[i].first);
    2690         6464 :                       first_edge_seq[i].second = sm_other;
    2691              :                     }
    2692              :                 }
    2693         1793 :               else if (edge_seq.length () > first_edge_seq.length ())
    2694              :                 {
    2695            5 :                   if (first_uneq == -1)
    2696            0 :                     first_uneq = first_edge_seq.length ();
    2697            5 :                   for (unsigned i = first_edge_seq.length ();
    2698           20 :                        i < edge_seq.length (); ++i)
    2699              :                     {
    2700           15 :                       if (edge_seq[i].second == sm_ord)
    2701            5 :                         bitmap_set_bit (refs_not_supported, edge_seq[i].first);
    2702           30 :                       extra_refs.safe_push (seq_entry (edge_seq[i].first,
    2703           15 :                                                        sm_other, NULL_TREE));
    2704              :                     }
    2705              :                 }
    2706              :               /* Put unmerged refs at first_uneq to force dependence checking
    2707              :                  on them.  */
    2708         3598 :               if (first_uneq != -1)
    2709              :                 {
    2710              :                   /* Missing ordered_splice_at.  */
    2711           64 :                   if ((unsigned)first_uneq == first_edge_seq.length ())
    2712            0 :                     first_edge_seq.safe_splice (extra_refs);
    2713              :                   else
    2714              :                     {
    2715           32 :                       unsigned fes_length = first_edge_seq.length ();
    2716           32 :                       first_edge_seq.safe_grow (fes_length
    2717           32 :                                                 + extra_refs.length ());
    2718           32 :                       memmove (&first_edge_seq[first_uneq + extra_refs.length ()],
    2719           32 :                                &first_edge_seq[first_uneq],
    2720           32 :                                (fes_length - first_uneq) * sizeof (seq_entry));
    2721           64 :                       memcpy (&first_edge_seq[first_uneq],
    2722           32 :                               extra_refs.address (),
    2723           32 :                               extra_refs.length () * sizeof (seq_entry));
    2724              :                     }
    2725              :                 }
    2726         5513 :             }
    2727              :           /* Use the sequence from the first edge and push SMs down.  */
    2728         4345 :           for (unsigned i = 0; i < first_edge_seq.length (); ++i)
    2729              :             {
    2730         2799 :               unsigned id = first_edge_seq[i].first;
    2731         2799 :               seq.safe_push (first_edge_seq[i]);
    2732         2799 :               unsigned new_idx;
    2733         2799 :               if ((first_edge_seq[i].second == sm_ord
    2734         2178 :                    || (first_edge_seq[i].second == sm_other
    2735         2178 :                        && first_edge_seq[i].from != NULL_TREE))
    2736         3770 :                   && !sm_seq_push_down (seq, seq.length () - 1, &new_idx))
    2737              :                 {
    2738          125 :                   if (first_edge_seq[i].second == sm_ord)
    2739            0 :                     bitmap_set_bit (refs_not_supported, id);
    2740              :                   /* Mark it sm_other.  */
    2741          125 :                   seq[new_idx].second = sm_other;
    2742          125 :                   seq[new_idx].from = NULL_TREE;
    2743              :                 }
    2744              :             }
    2745         1546 :           bitmap_set_bit (fully_visited,
    2746         1546 :                           SSA_NAME_VERSION (gimple_phi_result (phi)));
    2747         1546 :           return 1;
    2748         3461 :         }
    2749        42590 :       lim_aux_data *data = get_lim_data (def);
    2750        42590 :       im_mem_ref *ref = memory_accesses.refs_list[data->ref];
    2751        42590 :       if (data->ref == UNANALYZABLE_MEM_ID)
    2752              :         return -1;
    2753              :       /* Stop at memory references which we can't move.  */
    2754        42590 :       else if ((ref->mem.ref == error_mark_node
    2755              :                 /* We can move end-of-storage/object down.  */
    2756          379 :                 && !gimple_clobber_p (ref->accesses_in_loop[0].stmt,
    2757              :                                       CLOBBER_STORAGE_END)
    2758          244 :                 && !gimple_clobber_p (ref->accesses_in_loop[0].stmt,
    2759              :                                       CLOBBER_OBJECT_END))
    2760        42881 :                || TREE_THIS_VOLATILE (ref->mem.ref))
    2761              :         {
    2762              :           /* Mark refs_not_in_seq as unsupported.  */
    2763          120 :           bitmap_ior_into (refs_not_supported, refs_not_in_seq);
    2764          120 :           return 1;
    2765              :         }
    2766              :       /* One of the stores we want to apply SM to and we've not yet seen.  */
    2767        42470 :       else if (bitmap_clear_bit (refs_not_in_seq, data->ref))
    2768              :         {
    2769        33512 :           seq.safe_push (seq_entry (data->ref, sm_ord));
    2770              : 
    2771              :           /* 1) push it down the queue until a SMed
    2772              :              and not ignored ref is reached, skipping all not SMed refs
    2773              :              and ignored refs via non-TBAA disambiguation.  */
    2774        33512 :           unsigned new_idx;
    2775        67024 :           if (!sm_seq_push_down (seq, seq.length () - 1, &new_idx)
    2776              :               /* If that fails but we did not fork yet continue, we'll see
    2777              :                  to re-materialize all of the stores in the sequence then.
    2778              :                  Further stores will only be pushed up to this one.  */
    2779        33512 :               && forked)
    2780              :             {
    2781            0 :               bitmap_set_bit (refs_not_supported, data->ref);
    2782              :               /* Mark it sm_other.  */
    2783            0 :               seq[new_idx].second = sm_other;
    2784              :             }
    2785              : 
    2786              :           /* 2) check whether we've seen all refs we want to SM and if so
    2787              :              declare success for the active exit  */
    2788        33512 :           if (bitmap_empty_p (refs_not_in_seq))
    2789        18997 :             return 1;
    2790              :         }
    2791              :       else
    2792              :         /* Another store not part of the final sequence.  Simply push it.  */
    2793         8958 :         seq.safe_push (seq_entry (data->ref, sm_other,
    2794         8958 :                                   gimple_assign_rhs1 (def)));
    2795              : 
    2796        23473 :       vdef = gimple_vuse (def);
    2797        23473 :     }
    2798              :   while (1);
    2799              : }
    2800              : 
    2801              : /* Hoists memory references MEM_REFS out of LOOP.  EXITS is the list of exit
    2802              :    edges of the LOOP.  */
    2803              : 
    2804              : static void
    2805        21148 : hoist_memory_references (class loop *loop, bitmap mem_refs,
    2806              :                          const vec<edge> &exits)
    2807              : {
    2808        21148 :   im_mem_ref *ref;
    2809        21148 :   unsigned  i;
    2810        21148 :   bitmap_iterator bi;
    2811              : 
    2812              :   /* There's a special case we can use ordered re-materialization for
    2813              :      conditionally executed stores which is when all stores in the loop
    2814              :      happen in the same basic-block.  In that case we know we'll reach
    2815              :      all stores and thus can simply process that BB and emit a single
    2816              :      conditional block of ordered materializations.  See PR102436.  */
    2817        21148 :   basic_block single_store_bb = NULL;
    2818        30509 :   EXECUTE_IF_SET_IN_BITMAP (&memory_accesses.all_refs_stored_in_loop[loop->num],
    2819              :                             0, i, bi)
    2820              :     {
    2821        28369 :       bool fail = false;
    2822        28369 :       ref = memory_accesses.refs_list[i];
    2823       130143 :       for (auto loc : ref->accesses_in_loop)
    2824       140363 :         if (!gimple_vdef (loc.stmt))
    2825              :           ;
    2826        31283 :         else if (!single_store_bb)
    2827              :           {
    2828        21148 :             single_store_bb = gimple_bb (loc.stmt);
    2829        21148 :             bool conditional = false;
    2830        76244 :             for (edge e : exits)
    2831        22685 :               if (!dominated_by_p (CDI_DOMINATORS, e->src, single_store_bb))
    2832              :                 {
    2833              :                   /* Conditional as seen from e.  */
    2834              :                   conditional = true;
    2835              :                   break;
    2836              :                 }
    2837        21148 :             if (!conditional)
    2838              :               {
    2839              :                 fail = true;
    2840              :                 break;
    2841              :               }
    2842              :           }
    2843        10135 :         else if (single_store_bb != gimple_bb (loc.stmt))
    2844              :           {
    2845              :             fail = true;
    2846              :             break;
    2847              :           }
    2848        28369 :       if (fail)
    2849              :         {
    2850              :           single_store_bb = NULL;
    2851              :           break;
    2852              :         }
    2853              :     }
    2854        21148 :   if (single_store_bb)
    2855              :     {
    2856              :       /* Analyze the single block with stores.  */
    2857         2140 :       auto_bitmap fully_visited;
    2858         2140 :       auto_bitmap refs_not_supported;
    2859         2140 :       auto_bitmap refs_not_in_seq;
    2860         2140 :       auto_vec<seq_entry> seq;
    2861         2140 :       bitmap_copy (refs_not_in_seq, mem_refs);
    2862         2140 :       int res = sm_seq_valid_bb (loop, single_store_bb, NULL_TREE,
    2863              :                                  seq, refs_not_in_seq, refs_not_supported,
    2864              :                                  false, fully_visited);
    2865         2140 :       if (res != 1)
    2866              :         {
    2867              :           /* Unhandled refs can still fail this.  */
    2868            0 :           bitmap_clear (mem_refs);
    2869            0 :           return;
    2870              :         }
    2871              : 
    2872              :       /* We cannot handle sm_other since we neither remember the
    2873              :          stored location nor the value at the point we execute them.  */
    2874         5173 :       for (unsigned i = 0; i < seq.length (); ++i)
    2875              :         {
    2876         3033 :           unsigned new_i;
    2877         3033 :           if (seq[i].second == sm_other
    2878         3033 :               && seq[i].from != NULL_TREE)
    2879          414 :             seq[i].from = NULL_TREE;
    2880         2619 :           else if ((seq[i].second == sm_ord
    2881            0 :                     || (seq[i].second == sm_other
    2882            0 :                         && seq[i].from != NULL_TREE))
    2883         2619 :                    && !sm_seq_push_down (seq, i, &new_i))
    2884              :             {
    2885           69 :               bitmap_set_bit (refs_not_supported, seq[new_i].first);
    2886           69 :               seq[new_i].second = sm_other;
    2887           69 :               seq[new_i].from = NULL_TREE;
    2888              :             }
    2889              :         }
    2890         2140 :       bitmap_and_compl_into (mem_refs, refs_not_supported);
    2891         2140 :       if (bitmap_empty_p (mem_refs))
    2892              :         return;
    2893              : 
    2894              :       /* Prune seq.  */
    2895         2460 :       while (seq.last ().second == sm_other
    2896         2460 :              && seq.last ().from == NULL_TREE)
    2897          372 :         seq.pop ();
    2898              : 
    2899         2088 :       hash_map<im_mem_ref *, sm_aux *> aux_map;
    2900              : 
    2901              :       /* Execute SM but delay the store materialization for ordered
    2902              :          sequences on exit.  Remember a created flag var and make
    2903              :          sure to re-use it.  */
    2904         2088 :       sm_aux *flag_var_aux = nullptr;
    2905         4638 :       EXECUTE_IF_SET_IN_BITMAP (mem_refs, 0, i, bi)
    2906              :         {
    2907         2550 :           ref = memory_accesses.refs_list[i];
    2908         2550 :           sm_aux *aux = execute_sm (loop, ref, aux_map, true,
    2909              :                                     flag_var_aux != nullptr);
    2910         2550 :           if (aux->store_flag)
    2911         1453 :             flag_var_aux = aux;
    2912              :         }
    2913              : 
    2914              :       /* Materialize ordered store sequences on exits.  */
    2915         2088 :       edge e;
    2916         2088 :       auto_bitmap clobbers_to_prune;
    2917         5655 :       FOR_EACH_VEC_ELT (exits, i, e)
    2918              :         {
    2919         3567 :           edge append_cond_position = NULL;
    2920         3567 :           edge last_cond_fallthru = NULL;
    2921         3567 :           edge insert_e = e;
    2922              :           /* Construct the single flag variable control flow and insert
    2923              :              the ordered seq of stores in the then block.  With
    2924              :              -fstore-data-races we can do the stores unconditionally.  */
    2925         3567 :           if (flag_var_aux)
    2926         2248 :             insert_e
    2927              :               = single_pred_edge
    2928         2248 :                   (execute_sm_if_changed (e, NULL_TREE, NULL_TREE,
    2929              :                                           flag_var_aux->store_flag,
    2930              :                                           loop_preheader_edge (loop),
    2931              :                                           &flag_var_aux->flag_bbs,
    2932              :                                           append_cond_position,
    2933              :                                           last_cond_fallthru));
    2934         3567 :           execute_sm_exit (loop, insert_e, seq, aux_map, sm_ord,
    2935              :                            append_cond_position, last_cond_fallthru,
    2936              :                            clobbers_to_prune);
    2937         3567 :           gsi_commit_one_edge_insert (insert_e, NULL);
    2938              :         }
    2939              : 
    2940              :       /* Remove clobbers inside the loop we re-materialized on exits.  */
    2941         2088 :       EXECUTE_IF_SET_IN_BITMAP (clobbers_to_prune, 0, i, bi)
    2942              :         {
    2943            0 :           gimple *stmt = memory_accesses.refs_list[i]->accesses_in_loop[0].stmt;
    2944            0 :           gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
    2945            0 :           unlink_stmt_vdef (stmt);
    2946            0 :           release_defs (stmt);
    2947            0 :           gimple_set_vdef (stmt, NULL_TREE);
    2948            0 :           gsi_remove (&gsi, true);
    2949              :         }
    2950              : 
    2951         4638 :       for (hash_map<im_mem_ref *, sm_aux *>::iterator iter = aux_map.begin ();
    2952         4638 :            iter != aux_map.end (); ++iter)
    2953         5100 :         delete (*iter).second;
    2954              : 
    2955         2088 :       return;
    2956         4228 :     }
    2957              : 
    2958              :   /* To address PR57359 before actually applying store-motion check
    2959              :      the candidates found for validity with regards to reordering
    2960              :      relative to other stores which we until here disambiguated using
    2961              :      TBAA which isn't valid.
    2962              :      What matters is the order of the last stores to the mem_refs
    2963              :      with respect to the other stores of the loop at the point of the
    2964              :      loop exits.  */
    2965              : 
    2966              :   /* For each exit compute the store order, pruning from mem_refs
    2967              :      on the fly.  */
    2968              :   /* The complexity of this is at least
    2969              :      O(number of exits * number of SM refs) but more approaching
    2970              :      O(number of exits * number of SM refs * number of stores).  */
    2971              :   /* ???  Somehow do this in a single sweep over the loop body.  */
    2972        19008 :   auto_vec<std::pair<edge, vec<seq_entry> > > sms;
    2973        19008 :   auto_bitmap refs_not_supported (&lim_bitmap_obstack);
    2974        19008 :   edge e;
    2975        38738 :   FOR_EACH_VEC_ELT (exits, i, e)
    2976              :     {
    2977        21628 :       vec<seq_entry> seq;
    2978        21628 :       seq.create (4);
    2979        21628 :       auto_bitmap refs_not_in_seq (&lim_bitmap_obstack);
    2980        21628 :       bitmap_and_compl (refs_not_in_seq, mem_refs, refs_not_supported);
    2981        21628 :       if (bitmap_empty_p (refs_not_in_seq))
    2982              :         {
    2983         1120 :           seq.release ();
    2984         1120 :           break;
    2985              :         }
    2986        20508 :       auto_bitmap fully_visited;
    2987        20508 :       int res = sm_seq_valid_bb (loop, e->src, NULL_TREE,
    2988              :                                  seq, refs_not_in_seq,
    2989              :                                  refs_not_supported, false,
    2990              :                                  fully_visited);
    2991        20508 :       if (res != 1)
    2992              :         {
    2993          778 :           bitmap_copy (refs_not_supported, mem_refs);
    2994          778 :           seq.release ();
    2995          778 :           break;
    2996              :         }
    2997        19730 :       sms.safe_push (std::make_pair (e, seq));
    2998        22406 :     }
    2999              : 
    3000              :   /* Prune pruned mem_refs from earlier processed exits.  */
    3001        19008 :   bool changed = !bitmap_empty_p (refs_not_supported);
    3002        19008 :   while (changed)
    3003              :     {
    3004         5670 :       changed = false;
    3005         5670 :       std::pair<edge, vec<seq_entry> > *seq;
    3006        38672 :       FOR_EACH_VEC_ELT (sms, i, seq)
    3007              :         {
    3008              :           bool need_to_push = false;
    3009        13035 :           for (unsigned i = 0; i < seq->second.length (); ++i)
    3010              :             {
    3011         6038 :               sm_kind kind = seq->second[i].second;
    3012         6038 :               if (kind == sm_other && seq->second[i].from == NULL_TREE)
    3013              :                 break;
    3014         5125 :               unsigned id = seq->second[i].first;
    3015         5125 :               unsigned new_idx;
    3016         5125 :               if (kind == sm_ord
    3017         5125 :                   && bitmap_bit_p (refs_not_supported, id))
    3018              :                 {
    3019         2546 :                   seq->second[i].second = sm_other;
    3020         2546 :                   gcc_assert (seq->second[i].from == NULL_TREE);
    3021              :                   need_to_push = true;
    3022              :                 }
    3023         2579 :               else if (need_to_push
    3024         2579 :                        && !sm_seq_push_down (seq->second, i, &new_idx))
    3025              :                 {
    3026              :                   /* We need to push down both sm_ord and sm_other
    3027              :                      but for the latter we need to disqualify all
    3028              :                      following refs.  */
    3029          113 :                   if (kind == sm_ord)
    3030              :                     {
    3031            7 :                       if (bitmap_set_bit (refs_not_supported, id))
    3032            7 :                         changed = true;
    3033            7 :                       seq->second[new_idx].second = sm_other;
    3034              :                     }
    3035              :                   else
    3036              :                     {
    3037          411 :                       for (unsigned j = seq->second.length () - 1;
    3038          305 :                            j > new_idx; --j)
    3039          199 :                         if (seq->second[j].second == sm_ord
    3040          321 :                             && bitmap_set_bit (refs_not_supported,
    3041          122 :                                                seq->second[j].first))
    3042              :                           changed = true;
    3043          106 :                       seq->second.truncate (new_idx);
    3044          106 :                       break;
    3045              :                     }
    3046              :                 }
    3047              :             }
    3048              :         }
    3049              :     }
    3050        19008 :   std::pair<edge, vec<seq_entry> > *seq;
    3051        58468 :   FOR_EACH_VEC_ELT (sms, i, seq)
    3052              :     {
    3053              :       /* Prune sm_other from the end.  */
    3054        63018 :       while (!seq->second.is_empty ()
    3055        43288 :              && seq->second.last ().second == sm_other)
    3056         4907 :         seq->second.pop ();
    3057              :       /* Prune duplicates from the start.  */
    3058        19730 :       auto_bitmap seen (&lim_bitmap_obstack);
    3059        19730 :       unsigned j, k;
    3060        47386 :       for (j = k = 0; j < seq->second.length (); ++j)
    3061        27656 :         if (bitmap_set_bit (seen, seq->second[j].first))
    3062              :           {
    3063        27547 :             if (k != j)
    3064           77 :               seq->second[k] = seq->second[j];
    3065        27547 :             ++k;
    3066              :           }
    3067        19730 :       seq->second.truncate (k);
    3068              :       /* And verify.  */
    3069        19730 :       seq_entry *e;
    3070        86737 :       FOR_EACH_VEC_ELT (seq->second, j, e)
    3071        27547 :         gcc_assert (e->second == sm_ord
    3072              :                     || (e->second == sm_other && e->from != NULL_TREE));
    3073        19730 :     }
    3074              : 
    3075              :   /* Verify dependence for refs we cannot handle with the order preserving
    3076              :      code (refs_not_supported) or prune them from mem_refs.  */
    3077        19008 :   auto_vec<seq_entry> unord_refs;
    3078        33726 :   EXECUTE_IF_SET_IN_BITMAP (refs_not_supported, 0, i, bi)
    3079              :     {
    3080        14718 :       ref = memory_accesses.refs_list[i];
    3081        14718 :       if (!ref_indep_loop_p (loop, ref, sm_waw))
    3082         6476 :         bitmap_clear_bit (mem_refs, i);
    3083              :       /* We've now verified store order for ref with respect to all other
    3084              :          stores in the loop does not matter.  */
    3085              :       else
    3086         8242 :         unord_refs.safe_push (seq_entry (i, sm_unord));
    3087              :     }
    3088              : 
    3089        19008 :   hash_map<im_mem_ref *, sm_aux *> aux_map;
    3090              : 
    3091              :   /* Execute SM but delay the store materialization for ordered
    3092              :      sequences on exit.  */
    3093        50757 :   EXECUTE_IF_SET_IN_BITMAP (mem_refs, 0, i, bi)
    3094              :     {
    3095        31749 :       ref = memory_accesses.refs_list[i];
    3096        31749 :       execute_sm (loop, ref, aux_map, bitmap_bit_p (refs_not_supported, i),
    3097              :                   false);
    3098              :     }
    3099              : 
    3100              :   /* Materialize ordered store sequences on exits.  */
    3101        19008 :   auto_bitmap clobbers_to_prune;
    3102        41810 :   FOR_EACH_VEC_ELT (exits, i, e)
    3103              :     {
    3104        22802 :       edge append_cond_position = NULL;
    3105        22802 :       edge last_cond_fallthru = NULL;
    3106        22802 :       if (i < sms.length ())
    3107              :         {
    3108        19730 :           gcc_assert (sms[i].first == e);
    3109        19730 :           execute_sm_exit (loop, e, sms[i].second, aux_map, sm_ord,
    3110              :                            append_cond_position, last_cond_fallthru,
    3111              :                            clobbers_to_prune);
    3112        19730 :           sms[i].second.release ();
    3113              :         }
    3114        22802 :       if (!unord_refs.is_empty ())
    3115         8410 :         execute_sm_exit (loop, e, unord_refs, aux_map, sm_unord,
    3116              :                          append_cond_position, last_cond_fallthru,
    3117              :                          clobbers_to_prune);
    3118              :       /* Commit edge inserts here to preserve the order of stores
    3119              :          when an exit exits multiple loops.  */
    3120        22802 :       gsi_commit_one_edge_insert (e, NULL);
    3121              :     }
    3122              : 
    3123              :   /* Remove clobbers inside the loop we re-materialized on exits.  */
    3124        19191 :   EXECUTE_IF_SET_IN_BITMAP (clobbers_to_prune, 0, i, bi)
    3125              :     {
    3126          183 :       gimple *stmt = memory_accesses.refs_list[i]->accesses_in_loop[0].stmt;
    3127          183 :       gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
    3128          183 :       unlink_stmt_vdef (stmt);
    3129          183 :       release_defs (stmt);
    3130          183 :       gimple_set_vdef (stmt, NULL_TREE);
    3131          183 :       gsi_remove (&gsi, true);
    3132              :     }
    3133              : 
    3134        50757 :   for (hash_map<im_mem_ref *, sm_aux *>::iterator iter = aux_map.begin ();
    3135        69765 :        iter != aux_map.end (); ++iter)
    3136        63498 :     delete (*iter).second;
    3137        19008 : }
    3138              : 
    3139              : class ref_always_stored
    3140              : {
    3141              : public:
    3142        91911 :   ref_always_stored (class loop *loop_)
    3143        91911 :       : loop (loop_) {}
    3144              :   bool operator () (mem_ref_loc *loc);
    3145              :   class loop *loop;
    3146              : };
    3147              : 
    3148              : bool
    3149       193214 : ref_always_stored::operator () (mem_ref_loc *loc)
    3150              : {
    3151              :   /* Make sure the statement is a store.  */
    3152       193214 :   tree lhs = gimple_get_lhs (loc->stmt);
    3153       193214 :   if (!lhs
    3154       193214 :       || !(DECL_P (lhs) || REFERENCE_CLASS_P (lhs)))
    3155              :     return false;
    3156              : 
    3157       116578 :   struct lim_aux_data *lim_data = get_lim_data (loc->stmt);
    3158       116578 :   if (!lim_data)
    3159              :     return false;
    3160              : 
    3161       116578 :   class loop *must_exec = lim_data->always_executed_in;
    3162       116578 :   if (!must_exec)
    3163              :     return false;
    3164              : 
    3165        37364 :   if (must_exec == loop
    3166        37364 :       || flow_loop_nested_p (must_exec, loop))
    3167        34304 :     return true;
    3168              : 
    3169              :   return false;
    3170              : }
    3171              : 
    3172              : /* Returns true if REF is always stored in LOOP.  */
    3173              : 
    3174              : static bool
    3175        91911 : ref_always_stored_p (class loop *loop, im_mem_ref *ref)
    3176              : {
    3177        91911 :   return for_all_locs_in_loop (loop, ref, ref_always_stored (loop));
    3178              : }
    3179              : 
    3180              : /* Returns true if LOAD_REF and STORE_REF form a "self write" pattern
    3181              :    where the stored value comes from the loaded value via SSA.
    3182              :    Example: a[i] = a[0] is safe to hoist a[0] even when i==0.  */
    3183              : 
    3184              : static bool
    3185       325688 : is_self_write (im_mem_ref *load_ref, im_mem_ref *store_ref)
    3186              : {
    3187              :   /* Only handle the simple case with a single access per ref.
    3188              :      Bail out on multiple accesses to be conservative.  */
    3189       325688 :   if (load_ref->accesses_in_loop.length () != 1
    3190       410501 :       || store_ref->accesses_in_loop.length () != 1)
    3191              :     return false;
    3192              : 
    3193        84830 :   gimple *load_stmt = load_ref->accesses_in_loop[0].stmt;
    3194        84830 :   gimple *store_stmt = store_ref->accesses_in_loop[0].stmt;
    3195              : 
    3196        84830 :   if (!is_gimple_assign (load_stmt) || !is_gimple_assign (store_stmt))
    3197              :     return false;
    3198              : 
    3199        84830 :   tree loaded_val = gimple_assign_lhs (load_stmt);
    3200        84830 :   tree stored_val = gimple_assign_rhs1 (store_stmt);
    3201              : 
    3202        84830 :   if (TREE_CODE (loaded_val) != SSA_NAME || TREE_CODE (stored_val) != SSA_NAME)
    3203              :     return false;
    3204              : 
    3205              :   /* Self write: stored value is the loaded value.  */
    3206        61634 :   if (stored_val != loaded_val)
    3207              :     return false;
    3208              : 
    3209              : 
    3210              :   /* TODO: Try to factor this out with mem_ref_hasher::equal
    3211              :      into im_compare_access_position_and_size
    3212              :      or a similar helper to centralize this delicate handling
    3213              :      complete for MEM_REF offsets and base pointer equality.
    3214              : 
    3215              :      TODO: Also ensure max_size_known_p agrees or resort to
    3216              :      alignment considerations to rule out partial overlaps.
    3217              : 
    3218              :      See:
    3219              :      https://gcc.gnu.org/pipermail/gcc-patches/2025-December/704155.html
    3220              :      For more context on TODOs above.  */
    3221              : 
    3222              :   /* They may alias.  Verify exact same location.  */
    3223         1735 :   return (operand_equal_p (load_ref->mem.base, store_ref->mem.base, 0)
    3224           46 :           && known_eq (load_ref->mem.size, store_ref->mem.size)
    3225         1781 :           && known_eq (load_ref->mem.offset, store_ref->mem.offset));
    3226              : 
    3227              : }
    3228              : 
    3229              : /* Returns true if REF1 and REF2 are independent.  */
    3230              : 
    3231              : static bool
    3232       604692 : refs_independent_p (im_mem_ref *ref1, im_mem_ref *ref2, bool tbaa_p)
    3233              : {
    3234       604692 :   if (ref1 == ref2)
    3235              :     return true;
    3236              : 
    3237       547389 :   if (dump_file && (dump_flags & TDF_DETAILS))
    3238         3043 :     fprintf (dump_file, "Querying dependency of refs %u and %u: ",
    3239         3043 :              ref1->id, ref2->id);
    3240              : 
    3241       547389 :   if (mem_refs_may_alias_p (ref1, ref2, &memory_accesses.ttae_cache, tbaa_p))
    3242              :     {
    3243        63586 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3244           96 :         fprintf (dump_file, "dependent.\n");
    3245              :       return false;
    3246              :     }
    3247              :   else
    3248              :     {
    3249       483803 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3250         2947 :         fprintf (dump_file, "independent.\n");
    3251              :       return true;
    3252              :     }
    3253              : }
    3254              : 
    3255              : /* Returns true if REF is independent on all other accessess in LOOP.
    3256              :    KIND specifies the kind of dependence to consider.
    3257              :      lim_raw assumes REF is not stored in LOOP and disambiguates RAW
    3258              :              dependences so if true REF can be hoisted out of LOOP
    3259              :      sm_war disambiguates a store REF against all other loads to see
    3260              :             whether the store can be sunk across loads out of LOOP
    3261              :      sm_waw disambiguates a store REF against all other stores to see
    3262              :             whether the store can be sunk across stores out of LOOP.  */
    3263              : 
    3264              : static bool
    3265      2101414 : ref_indep_loop_p (class loop *loop, im_mem_ref *ref, dep_kind kind)
    3266              : {
    3267      2101414 :   bool indep_p = true;
    3268      2101414 :   bitmap refs_to_check;
    3269              : 
    3270      2101414 :   if (kind == sm_war)
    3271       984363 :     refs_to_check = &memory_accesses.refs_loaded_in_loop[loop->num];
    3272              :   else
    3273      1117051 :     refs_to_check = &memory_accesses.refs_stored_in_loop[loop->num];
    3274              : 
    3275      2101414 :   if (bitmap_bit_p (refs_to_check, UNANALYZABLE_MEM_ID)
    3276      2101414 :       || ref->mem.ref == error_mark_node)
    3277              :     indep_p = false;
    3278              :   else
    3279              :     {
    3280              :       /* tri-state, { unknown, independent, dependent }  */
    3281       664427 :       dep_state state = query_loop_dependence (loop, ref, kind);
    3282       664427 :       if (state != dep_unknown)
    3283            0 :         return state == dep_independent;
    3284              : 
    3285       664427 :       class loop *inner = loop->inner;
    3286       820338 :       while (inner)
    3287              :         {
    3288       453639 :           if (!ref_indep_loop_p (inner, ref, kind))
    3289              :             {
    3290              :               indep_p = false;
    3291              :               break;
    3292              :             }
    3293       155911 :           inner = inner->next;
    3294              :         }
    3295              : 
    3296       664427 :       if (indep_p)
    3297              :         {
    3298       366699 :           unsigned i;
    3299       366699 :           bitmap_iterator bi;
    3300       929125 :           EXECUTE_IF_SET_IN_BITMAP (refs_to_check, 0, i, bi)
    3301              :             {
    3302       630280 :               im_mem_ref *aref = memory_accesses.refs_list[i];
    3303       630280 :               if (aref->mem.ref == error_mark_node)
    3304              :                 {
    3305        26368 :                   gimple *stmt = aref->accesses_in_loop[0].stmt;
    3306        26368 :                   if ((kind == sm_war
    3307         9477 :                        && ref_maybe_used_by_stmt_p (stmt, &ref->mem,
    3308              :                                                     kind != sm_waw))
    3309        35221 :                       || stmt_may_clobber_ref_p_1 (stmt, &ref->mem,
    3310              :                                                    kind != sm_waw))
    3311              :                     {
    3312              :                       indep_p = false;
    3313              :                       break;
    3314              :                     }
    3315              :                 }
    3316              :               /* For hoisting loads (lim_raw), allow "self write": the store
    3317              :                  writes back the loaded value.  Example: a[i] = a[0]
    3318              :                  is safe even when i==0 causes aliasing.  */
    3319       603912 :               else if (kind == lim_raw
    3320       325688 :                        && ref->loaded && aref->stored
    3321       929600 :                        && is_self_write (ref, aref))
    3322              :                 {
    3323           17 :                   if (dump_file && (dump_flags & TDF_DETAILS))
    3324            2 :                     fprintf (dump_file,
    3325              :                              "Dependency of refs %u and %u: "
    3326              :                              "independent (self write).\n",
    3327            2 :                              ref->id, aref->id);
    3328              :                 }
    3329              : 
    3330       603895 :               else if (!refs_independent_p (ref, aref, kind != sm_waw))
    3331              :                 {
    3332              :                   indep_p = false;
    3333              :                   break;
    3334              :                 }
    3335              :             }
    3336              :         }
    3337              :     }
    3338              : 
    3339      2101414 :   if (dump_file && (dump_flags & TDF_DETAILS))
    3340          769 :     fprintf (dump_file, "Querying %s dependencies of ref %u in loop %d: %s\n",
    3341              :              kind == lim_raw ? "RAW" : (kind == sm_war ? "SM WAR" : "SM WAW"),
    3342          374 :              ref->id, loop->num, indep_p ? "independent" : "dependent");
    3343              : 
    3344              :   /* Record the computed result in the cache.  */
    3345      2101414 :   record_loop_dependence (loop, ref, kind,
    3346              :                           indep_p ? dep_independent : dep_dependent);
    3347              : 
    3348      2101414 :   return indep_p;
    3349              : }
    3350              : 
    3351              : class ref_in_loop_hot_body
    3352              : {
    3353              : public:
    3354        41832 :   ref_in_loop_hot_body (class loop *loop_) : l (loop_) {}
    3355              :   bool operator () (mem_ref_loc *loc);
    3356              :   class loop *l;
    3357              : };
    3358              : 
    3359              : /* Check the coldest loop between loop L and innermost loop.  If there is one
    3360              :    cold loop between L and INNER_LOOP, store motion can be performed, otherwise
    3361              :    no cold loop means no store motion.  get_coldest_out_loop also handles cases
    3362              :    when l is inner_loop.  */
    3363              : bool
    3364        42525 : ref_in_loop_hot_body::operator () (mem_ref_loc *loc)
    3365              : {
    3366        42525 :   basic_block curr_bb = gimple_bb (loc->stmt);
    3367        42525 :   class loop *inner_loop = curr_bb->loop_father;
    3368        42525 :   return get_coldest_out_loop (l, inner_loop, curr_bb);
    3369              : }
    3370              : 
    3371              : 
    3372              : /* Returns true if we can perform store motion of REF from LOOP.  */
    3373              : 
    3374              : static bool
    3375      2937752 : can_sm_ref_p (class loop *loop, im_mem_ref *ref)
    3376              : {
    3377      2937752 :   bool store_could_trap;
    3378              : 
    3379              :   /* Can't hoist unanalyzable refs.  */
    3380      2937752 :   if (!MEM_ANALYZABLE (ref))
    3381              :     return false;
    3382              : 
    3383              :   /* Can't hoist/sink aggregate copies.  */
    3384      2574853 :   if (ref->mem.ref == error_mark_node)
    3385              :     return false;
    3386              : 
    3387              :   /* It should be movable.  */
    3388      2131001 :   if (!is_gimple_reg_type (TREE_TYPE (ref->mem.ref))
    3389      2130715 :       || TREE_THIS_VOLATILE (ref->mem.ref)
    3390      4241976 :       || !for_each_index (&ref->mem.ref, may_move_till, loop))
    3391              :     return false;
    3392              : 
    3393       962912 :   store_could_trap = lhs_could_trap_p (ref->mem.ref);
    3394              : 
    3395              :   /* Do not move a load or store that can throw.  Store motion does not
    3396              :      update EH information.  */
    3397       962912 :   if (tree_could_throw_p (ref->mem.ref)
    3398       962912 :       || (flag_exceptions
    3399       689179 :           && cfun->can_throw_non_call_exceptions
    3400       541292 :           && store_could_trap))
    3401              :     return false;
    3402              : 
    3403              :   /* If a store can trap, it must be always executed in LOOP.  */
    3404       939611 :   if (store_could_trap
    3405              :       /* ???  We can at least use false here, allowing loads?  We
    3406              :          are forcing conditional stores if the ref is not always
    3407              :          stored to later anyway.  So this would only guard
    3408              :          the load we need to emit.  Thus when the ref is not
    3409              :          loaded we can elide this completely?  */
    3410       997223 :       && !ref_always_stored_p (loop, ref))
    3411              :     return false;
    3412              : 
    3413              :   /* Verify all loads of ref can be hoisted.  */
    3414       892906 :   if (ref->loaded
    3415        90352 :       && bitmap_bit_p (ref->loaded, loop->num)
    3416       978102 :       && !ref_indep_loop_p (loop, ref, lim_raw))
    3417              :     return false;
    3418              : 
    3419              :   /* Verify the candidate can be disambiguated against all loads,
    3420              :      that is, we can elide all in-loop stores.  Disambiguation
    3421              :      against stores is done later when we cannot guarantee preserving
    3422              :      the order of stores.  */
    3423       829874 :   if (!ref_indep_loop_p (loop, ref, sm_war))
    3424              :     return false;
    3425              : 
    3426              :   /* Verify whether the candidate is hot for LOOP.  Only do store motion if the
    3427              :     candidate's profile count is hot.  Statement in cold BB shouldn't be moved
    3428              :     out of it's loop_father.  */
    3429        41832 :   if (!for_all_locs_in_loop (loop, ref, ref_in_loop_hot_body (loop)))
    3430              :     return false;
    3431              : 
    3432              :   return true;
    3433              : }
    3434              : 
    3435              : /* Marks the references in LOOP for that store motion should be performed
    3436              :    in REFS_TO_SM.  SM_EXECUTED is the set of references for that store
    3437              :    motion was performed in one of the outer loops.  */
    3438              : 
    3439              : static void
    3440      1297601 : find_refs_for_sm (class loop *loop, bitmap sm_executed, bitmap refs_to_sm)
    3441              : {
    3442      1297601 :   bitmap refs = &memory_accesses.all_refs_stored_in_loop[loop->num];
    3443      1297601 :   unsigned i;
    3444      1297601 :   bitmap_iterator bi;
    3445      1297601 :   im_mem_ref *ref;
    3446              : 
    3447      4235353 :   EXECUTE_IF_AND_COMPL_IN_BITMAP (refs, sm_executed, 0, i, bi)
    3448              :     {
    3449      2937752 :       ref = memory_accesses.refs_list[i];
    3450      2937752 :       if (can_sm_ref_p (loop, ref) && dbg_cnt (lim))
    3451        40846 :         bitmap_set_bit (refs_to_sm, i);
    3452              :     }
    3453      1297601 : }
    3454              : 
    3455              : /* Checks whether LOOP (with exits stored in EXITS array) is suitable
    3456              :    for a store motion optimization (i.e. whether we can insert statement
    3457              :    on its exits).  */
    3458              : 
    3459              : static bool
    3460      1343287 : loop_suitable_for_sm (class loop *loop ATTRIBUTE_UNUSED,
    3461              :                       const vec<edge> &exits)
    3462              : {
    3463      1343287 :   unsigned i;
    3464      1343287 :   edge ex;
    3465              : 
    3466      3488400 :   FOR_EACH_VEC_ELT (exits, i, ex)
    3467      2190799 :     if (ex->flags & (EDGE_ABNORMAL | EDGE_EH))
    3468              :       return false;
    3469              : 
    3470              :   return true;
    3471              : }
    3472              : 
    3473              : /* Try to perform store motion for all memory references modified inside
    3474              :    LOOP.  SM_EXECUTED is the bitmap of the memory references for that
    3475              :    store motion was executed in one of the outer loops.  */
    3476              : 
    3477              : static void
    3478      1343287 : store_motion_loop (class loop *loop, bitmap sm_executed)
    3479              : {
    3480      1343287 :   auto_vec<edge> exits = get_loop_exit_edges (loop);
    3481      1343287 :   class loop *subloop;
    3482      1343287 :   bitmap sm_in_loop = BITMAP_ALLOC (&lim_bitmap_obstack);
    3483              : 
    3484      1343287 :   if (loop_suitable_for_sm (loop, exits))
    3485              :     {
    3486      1297601 :       find_refs_for_sm (loop, sm_executed, sm_in_loop);
    3487      1297601 :       if (!bitmap_empty_p (sm_in_loop))
    3488        21148 :         hoist_memory_references (loop, sm_in_loop, exits);
    3489              :     }
    3490              : 
    3491      1343287 :   bitmap_ior_into (sm_executed, sm_in_loop);
    3492      1646926 :   for (subloop = loop->inner; subloop != NULL; subloop = subloop->next)
    3493       303639 :     store_motion_loop (subloop, sm_executed);
    3494      1343287 :   bitmap_and_compl_into (sm_executed, sm_in_loop);
    3495      1343287 :   BITMAP_FREE (sm_in_loop);
    3496      1343287 : }
    3497              : 
    3498              : /* Try to perform store motion for all memory references modified inside
    3499              :    loops.  */
    3500              : 
    3501              : static void
    3502       496745 : do_store_motion (void)
    3503              : {
    3504       496745 :   class loop *loop;
    3505       496745 :   bitmap sm_executed = BITMAP_ALLOC (&lim_bitmap_obstack);
    3506              : 
    3507      1536393 :   for (loop = current_loops->tree_root->inner; loop != NULL; loop = loop->next)
    3508      1039648 :     store_motion_loop (loop, sm_executed);
    3509              : 
    3510       496745 :   BITMAP_FREE (sm_executed);
    3511       496745 : }
    3512              : 
    3513              : /* Fills ALWAYS_EXECUTED_IN information for basic blocks of LOOP, i.e.
    3514              :    for each such basic block bb records the outermost loop for that execution
    3515              :    of its header implies execution of bb.  CONTAINS_CALL is the bitmap of
    3516              :    blocks that contain a nonpure call.  */
    3517              : 
    3518              : static void
    3519      1350631 : fill_always_executed_in_1 (class loop *loop, sbitmap contains_call)
    3520              : {
    3521      1350631 :   basic_block bb = NULL, last = NULL;
    3522      1350631 :   edge e;
    3523      1350631 :   class loop *inn_loop = loop;
    3524              : 
    3525      1656635 :   for (class loop *inner = loop->inner; inner; inner = inner->next)
    3526       306004 :     fill_always_executed_in_1 (inner, contains_call);
    3527              : 
    3528      1350631 :   auto_vec<basic_block, 64> worklist;
    3529      1350631 :   worklist.reserve_exact (loop->num_nodes);
    3530      1350631 :   worklist.quick_push (loop->header);
    3531      3034530 :   do
    3532              :     {
    3533      3034530 :       edge_iterator ei;
    3534      3034530 :       bb = worklist.pop ();
    3535              : 
    3536      3034530 :       if (!flow_bb_inside_loop_p (inn_loop, bb))
    3537              :         {
    3538              :           /* When we are leaving a possibly infinite inner loop
    3539              :              we have to stop processing.  */
    3540       188342 :           if (!finite_loop_p (inn_loop))
    3541              :             break;
    3542              :           /* If the loop was finite we can continue with processing
    3543              :              the loop we exited to.  */
    3544       179065 :           inn_loop = bb->loop_father;
    3545              :         }
    3546              : 
    3547      3025253 :       if (dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
    3548      1744141 :         last = bb;
    3549              : 
    3550      3025253 :       if (bitmap_bit_p (contains_call, bb->index))
    3551              :         break;
    3552              : 
    3553              :       /* If LOOP exits from this BB stop processing.  */
    3554      5858422 :       FOR_EACH_EDGE (e, ei, bb->succs)
    3555      4163708 :         if (!flow_bb_inside_loop_p (loop, e->dest))
    3556              :           break;
    3557      2683084 :       if (e)
    3558              :         break;
    3559              : 
    3560              :       /* A loop might be infinite (TODO use simple loop analysis
    3561              :          to disprove this if possible).  */
    3562      1694714 :       if (bb->flags & BB_IRREDUCIBLE_LOOP)
    3563              :         break;
    3564              : 
    3565      1694586 :       if (bb->loop_father->header == bb)
    3566              :         /* Record that we enter into a subloop since it might not
    3567              :            be finite.  */
    3568              :         /* ???  Entering into a not always executed subloop makes
    3569              :            fill_always_executed_in quadratic in loop depth since
    3570              :            we walk those loops N times.  This is not a problem
    3571              :            in practice though, see PR102253 for a worst-case testcase.  */
    3572       632504 :         inn_loop = bb->loop_father;
    3573              : 
    3574              :       /* Walk the body of LOOP sorted by dominance relation.  Additionally,
    3575              :          if a basic block S dominates the latch, then only blocks dominated
    3576              :          by S are after it.
    3577              :          This is get_loop_body_in_dom_order using a worklist algorithm and
    3578              :          stopping once we are no longer interested in visiting further
    3579              :          blocks.  */
    3580      1694586 :       unsigned old_len = worklist.length ();
    3581      1694586 :       unsigned postpone = 0;
    3582      1694586 :       for (basic_block son = first_dom_son (CDI_DOMINATORS, bb);
    3583      3674721 :            son;
    3584      1980135 :            son = next_dom_son (CDI_DOMINATORS, son))
    3585              :         {
    3586      1980135 :           if (!flow_bb_inside_loop_p (loop, son))
    3587        22377 :             continue;
    3588      1957758 :           if (dominated_by_p (CDI_DOMINATORS, loop->latch, son))
    3589       540413 :             postpone = worklist.length ();
    3590      1957758 :           worklist.quick_push (son);
    3591              :         }
    3592      1694586 :       if (postpone)
    3593              :         /* Postponing the block that dominates the latch means
    3594              :            processing it last and thus putting it earliest in the
    3595              :            worklist.  */
    3596       110544 :         std::swap (worklist[old_len], worklist[postpone]);
    3597              :     }
    3598      3389172 :   while (!worklist.is_empty ());
    3599              : 
    3600      2137651 :   while (1)
    3601              :     {
    3602      1744141 :       if (last->loop_father == loop
    3603      1744141 :           || (ALWAYS_EXECUTED_IN (last)
    3604       158966 :               && loop_outer (ALWAYS_EXECUTED_IN (last)) == loop))
    3605              :         {
    3606      1743465 :           if (dump_enabled_p ())
    3607         2477 :             dump_printf (MSG_NOTE, "BB %d is always executed in loop %d\n",
    3608              :                          last->index, loop->num);
    3609      1743465 :           SET_ALWAYS_EXECUTED_IN (last, loop);
    3610              :         }
    3611      1744141 :       if (last == loop->header)
    3612              :         break;
    3613       393510 :       last = get_immediate_dominator (CDI_DOMINATORS, last);
    3614              :     }
    3615      1350631 : }
    3616              : 
    3617              : /* Fills ALWAYS_EXECUTED_IN information for basic blocks, i.e.
    3618              :    for each such basic block bb records the outermost loop for that execution
    3619              :    of its header implies execution of bb.  */
    3620              : 
    3621              : static void
    3622       498242 : fill_always_executed_in (void)
    3623              : {
    3624       498242 :   basic_block bb;
    3625       498242 :   class loop *loop;
    3626              : 
    3627       498242 :   auto_sbitmap contains_call (last_basic_block_for_fn (cfun));
    3628       498242 :   bitmap_clear (contains_call);
    3629     15473690 :   FOR_EACH_BB_FN (bb, cfun)
    3630              :     {
    3631     14975448 :       if (loop_depth (bb->loop_father) == 0)
    3632              :         {
    3633              :           /* Outside of loops we can skip scanning all stmts.  */
    3634      8687793 :           bitmap_set_bit (contains_call, bb->index);
    3635      8687793 :           continue;
    3636              :         }
    3637      6287655 :       gimple_stmt_iterator gsi;
    3638     54666858 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    3639              :         {
    3640     44228327 :           if (nonpure_call_p (gsi_stmt (gsi)))
    3641              :             break;
    3642              :         }
    3643              : 
    3644      6287655 :       if (!gsi_end_p (gsi))
    3645      1005621 :         bitmap_set_bit (contains_call, bb->index);
    3646              :     }
    3647              : 
    3648      1542869 :   for (loop = current_loops->tree_root->inner; loop; loop = loop->next)
    3649      1044627 :     fill_always_executed_in_1 (loop, contains_call);
    3650       498242 : }
    3651              : 
    3652              : /* Find the coldest loop preheader for LOOP, also find the nearest hotter loop
    3653              :    to LOOP.  Then recursively iterate each inner loop.  */
    3654              : 
    3655              : void
    3656      1350631 : fill_coldest_and_hotter_out_loop (class loop *coldest_loop,
    3657              :                                   class loop *hotter_loop, class loop *loop)
    3658              : {
    3659      1350631 :   if (bb_colder_than_loop_preheader (loop_preheader_edge (loop)->src,
    3660              :                                      coldest_loop))
    3661        36189 :     coldest_loop = loop;
    3662              : 
    3663      1350631 :   coldest_outermost_loop[loop->num] = coldest_loop;
    3664              : 
    3665      1350631 :   hotter_than_inner_loop[loop->num] = NULL;
    3666      1350631 :   class loop *outer_loop = loop_outer (loop);
    3667      1350631 :   if (hotter_loop
    3668      1350631 :       && bb_colder_than_loop_preheader (loop_preheader_edge (loop)->src,
    3669              :                                         hotter_loop))
    3670         4448 :     hotter_than_inner_loop[loop->num] = hotter_loop;
    3671              : 
    3672      1350631 :   if (outer_loop && outer_loop != current_loops->tree_root
    3673      1656635 :       && bb_colder_than_loop_preheader (loop_preheader_edge (loop)->src,
    3674              :                                         outer_loop))
    3675        38222 :     hotter_than_inner_loop[loop->num] = outer_loop;
    3676              : 
    3677      1350631 :   if (dump_enabled_p ())
    3678              :     {
    3679         1948 :       dump_printf (MSG_NOTE, "loop %d's coldest_outermost_loop is %d, ",
    3680              :                    loop->num, coldest_loop->num);
    3681         1948 :       if (hotter_than_inner_loop[loop->num])
    3682          319 :         dump_printf (MSG_NOTE, "hotter_than_inner_loop is %d\n",
    3683          319 :                      hotter_than_inner_loop[loop->num]->num);
    3684              :       else
    3685         1629 :         dump_printf (MSG_NOTE, "hotter_than_inner_loop is NULL\n");
    3686              :     }
    3687              : 
    3688      1350631 :   class loop *inner_loop;
    3689      1656635 :   for (inner_loop = loop->inner; inner_loop; inner_loop = inner_loop->next)
    3690       612008 :     fill_coldest_and_hotter_out_loop (coldest_loop,
    3691       306004 :                                       hotter_than_inner_loop[loop->num],
    3692              :                                       inner_loop);
    3693      1350631 : }
    3694              : 
    3695              : /* Compute the global information needed by the loop invariant motion pass.  */
    3696              : 
    3697              : static void
    3698       498242 : tree_ssa_lim_initialize (bool store_motion)
    3699              : {
    3700       498242 :   unsigned i;
    3701              : 
    3702       498242 :   bitmap_obstack_initialize (&lim_bitmap_obstack);
    3703       498242 :   gcc_obstack_init (&mem_ref_obstack);
    3704       498242 :   lim_aux_data_map = new hash_map<gimple *, lim_aux_data *>;
    3705              : 
    3706       498242 :   if (flag_tm)
    3707          104 :     compute_transaction_bits ();
    3708              : 
    3709       498242 :   memory_accesses.refs = new hash_table<mem_ref_hasher> (100);
    3710       498242 :   memory_accesses.refs_list.create (100);
    3711              :   /* Allocate a special, unanalyzable mem-ref with ID zero.  */
    3712       498242 :   memory_accesses.refs_list.quick_push
    3713       498242 :     (mem_ref_alloc (NULL, 0, UNANALYZABLE_MEM_ID));
    3714              : 
    3715       996484 :   memory_accesses.refs_loaded_in_loop.create (number_of_loops (cfun));
    3716       996484 :   memory_accesses.refs_loaded_in_loop.quick_grow_cleared (number_of_loops (cfun));
    3717       996484 :   memory_accesses.refs_stored_in_loop.create (number_of_loops (cfun));
    3718       996484 :   memory_accesses.refs_stored_in_loop.quick_grow_cleared (number_of_loops (cfun));
    3719       498242 :   if (store_motion)
    3720              :     {
    3721       993490 :       memory_accesses.all_refs_stored_in_loop.create (number_of_loops (cfun));
    3722       496745 :       memory_accesses.all_refs_stored_in_loop.quick_grow_cleared
    3723       993490 :                                                       (number_of_loops (cfun));
    3724              :     }
    3725              : 
    3726      6187092 :   for (i = 0; i < number_of_loops (cfun); i++)
    3727              :     {
    3728      2595304 :       bitmap_initialize (&memory_accesses.refs_loaded_in_loop[i],
    3729              :                          &lim_bitmap_obstack);
    3730      2595304 :       bitmap_initialize (&memory_accesses.refs_stored_in_loop[i],
    3731              :                          &lim_bitmap_obstack);
    3732      2595304 :       if (store_motion)
    3733      2582944 :         bitmap_initialize (&memory_accesses.all_refs_stored_in_loop[i],
    3734              :                            &lim_bitmap_obstack);
    3735              :     }
    3736              : 
    3737       498242 :   memory_accesses.ttae_cache = NULL;
    3738              : 
    3739              :   /* Initialize bb_loop_postorder with a mapping from loop->num to
    3740              :      its postorder index.  */
    3741       498242 :   i = 0;
    3742       996484 :   bb_loop_postorder = XNEWVEC (unsigned, number_of_loops (cfun));
    3743      2845357 :   for (auto loop : loops_list (cfun, LI_FROM_INNERMOST))
    3744      1350631 :     bb_loop_postorder[loop->num] = i++;
    3745       498242 : }
    3746              : 
    3747              : /* Cleans up after the invariant motion pass.  */
    3748              : 
    3749              : static void
    3750       498242 : tree_ssa_lim_finalize (void)
    3751              : {
    3752       498242 :   basic_block bb;
    3753       498242 :   unsigned i;
    3754       498242 :   im_mem_ref *ref;
    3755              : 
    3756     15512765 :   FOR_EACH_BB_FN (bb, cfun)
    3757     15014523 :     SET_ALWAYS_EXECUTED_IN (bb, NULL);
    3758              : 
    3759       498242 :   bitmap_obstack_release (&lim_bitmap_obstack);
    3760       996484 :   delete lim_aux_data_map;
    3761              : 
    3762       498242 :   delete memory_accesses.refs;
    3763       498242 :   memory_accesses.refs = NULL;
    3764              : 
    3765      5942972 :   FOR_EACH_VEC_ELT (memory_accesses.refs_list, i, ref)
    3766      5444730 :     memref_free (ref);
    3767       498242 :   memory_accesses.refs_list.release ();
    3768       498242 :   obstack_free (&mem_ref_obstack, NULL);
    3769              : 
    3770       498242 :   memory_accesses.refs_loaded_in_loop.release ();
    3771       498242 :   memory_accesses.refs_stored_in_loop.release ();
    3772       498242 :   memory_accesses.all_refs_stored_in_loop.release ();
    3773              : 
    3774       498242 :   if (memory_accesses.ttae_cache)
    3775         4877 :     free_affine_expand_cache (&memory_accesses.ttae_cache);
    3776              : 
    3777       498242 :   free (bb_loop_postorder);
    3778              : 
    3779       498242 :   coldest_outermost_loop.release ();
    3780       498242 :   hotter_than_inner_loop.release ();
    3781       498242 : }
    3782              : 
    3783              : /* Moves invariants from loops.  Only "expensive" invariants are moved out --
    3784              :    i.e. those that are likely to be win regardless of the register pressure.
    3785              :    Only perform store motion if STORE_MOTION is true.  */
    3786              : 
    3787              : unsigned int
    3788       498242 : loop_invariant_motion_in_fun (function *fun, bool store_motion)
    3789              : {
    3790       498242 :   unsigned int todo = 0;
    3791              : 
    3792       498242 :   tree_ssa_lim_initialize (store_motion);
    3793              : 
    3794       498242 :   mark_ssa_maybe_undefs ();
    3795              : 
    3796              :   /* Gathers information about memory accesses in the loops.  */
    3797       498242 :   analyze_memory_references (store_motion);
    3798              : 
    3799              :   /* Fills ALWAYS_EXECUTED_IN information for basic blocks.  */
    3800       498242 :   fill_always_executed_in ();
    3801              : 
    3802              :   /* Pre-compute coldest outermost loop and nearest hotter loop of each loop.
    3803              :    */
    3804       498242 :   class loop *loop;
    3805       996484 :   coldest_outermost_loop.create (number_of_loops (cfun));
    3806       996484 :   coldest_outermost_loop.safe_grow_cleared (number_of_loops (cfun));
    3807       996484 :   hotter_than_inner_loop.create (number_of_loops (cfun));
    3808       996484 :   hotter_than_inner_loop.safe_grow_cleared (number_of_loops (cfun));
    3809      1542869 :   for (loop = current_loops->tree_root->inner; loop != NULL; loop = loop->next)
    3810      1044627 :     fill_coldest_and_hotter_out_loop (loop, NULL, loop);
    3811              : 
    3812       498242 :   int *rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
    3813       498242 :   int n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);
    3814              : 
    3815              :   /* For each statement determine the outermost loop in that it is
    3816              :      invariant and cost for computing the invariant.  */
    3817     15971932 :   for (int i = 0; i < n; ++i)
    3818     14975448 :     compute_invariantness (BASIC_BLOCK_FOR_FN (fun, rpo[i]));
    3819              : 
    3820              :   /* Execute store motion.  Force the necessary invariants to be moved
    3821              :      out of the loops as well.  */
    3822       498242 :   if (store_motion)
    3823       496745 :     do_store_motion ();
    3824              : 
    3825       498242 :   free (rpo);
    3826       498242 :   rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
    3827       498242 :   n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);
    3828              : 
    3829              :   /* Move the expressions that are expensive enough.  */
    3830     16011007 :   for (int i = 0; i < n; ++i)
    3831     15014523 :     todo |= move_computations_worker (BASIC_BLOCK_FOR_FN (fun, rpo[i]));
    3832              : 
    3833       498242 :   free (rpo);
    3834              : 
    3835       498242 :   gsi_commit_edge_inserts ();
    3836       498242 :   if (need_ssa_update_p (fun))
    3837        14680 :     rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
    3838              : 
    3839       498242 :   tree_ssa_lim_finalize ();
    3840              : 
    3841       498242 :   return todo;
    3842              : }
    3843              : 
    3844              : /* Loop invariant motion pass.  */
    3845              : 
    3846              : namespace {
    3847              : 
    3848              : const pass_data pass_data_lim =
    3849              : {
    3850              :   GIMPLE_PASS, /* type */
    3851              :   "lim", /* name */
    3852              :   OPTGROUP_LOOP, /* optinfo_flags */
    3853              :   TV_LIM, /* tv_id */
    3854              :   PROP_cfg, /* properties_required */
    3855              :   0, /* properties_provided */
    3856              :   0, /* properties_destroyed */
    3857              :   0, /* todo_flags_start */
    3858              :   0, /* todo_flags_finish */
    3859              : };
    3860              : 
    3861              : class pass_lim : public gimple_opt_pass
    3862              : {
    3863              : public:
    3864      1178144 :   pass_lim (gcc::context *ctxt)
    3865      2356288 :     : gimple_opt_pass (pass_data_lim, ctxt)
    3866              :   {}
    3867              : 
    3868              :   /* opt_pass methods: */
    3869       883608 :   opt_pass * clone () final override { return new pass_lim (m_ctxt); }
    3870      1317559 :   bool gate (function *) final override { return flag_tree_loop_im != 0; }
    3871              :   unsigned int execute (function *) final override;
    3872              : 
    3873              : }; // class pass_lim
    3874              : 
    3875              : unsigned int
    3876      1317196 : pass_lim::execute (function *fun)
    3877              : {
    3878      1317196 :   in_loop_pipeline = scev_initialized_p ();
    3879      1317196 :   if (!in_loop_pipeline)
    3880      1069032 :     loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
    3881              : 
    3882      2634392 :   if (number_of_loops (fun) <= 1)
    3883              :     return 0;
    3884       496763 :   unsigned int todo = loop_invariant_motion_in_fun (fun, flag_move_loop_stores);
    3885              : 
    3886       496763 :   if (!in_loop_pipeline)
    3887       248599 :     loop_optimizer_finalize ();
    3888              :   else
    3889       248164 :     scev_reset ();
    3890              :   return todo;
    3891              : }
    3892              : 
    3893              : } // anon namespace
    3894              : 
    3895              : gimple_opt_pass *
    3896       294536 : make_pass_lim (gcc::context *ctxt)
    3897              : {
    3898       294536 :   return new pass_lim (ctxt);
    3899              : }
    3900              : 
        

Generated by: LCOV version 2.5.0-beta

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