Home | History | Annotate | Line # | Download | only in gcc
store-motion.cc revision 1.1
      1 /* Store motion via Lazy Code Motion on the reverse CFG.
      2    Copyright (C) 1997-2022 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 under
      7 the terms of the GNU General Public License as published by the Free
      8 Software Foundation; either version 3, or (at your option) any later
      9 version.
     10 
     11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     12 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 "rtl.h"
     25 #include "tree.h"
     26 #include "predict.h"
     27 #include "df.h"
     28 #include "toplev.h"
     29 
     30 #include "cfgrtl.h"
     31 #include "cfganal.h"
     32 #include "lcm.h"
     33 #include "cfgcleanup.h"
     34 #include "expr.h"
     35 #include "tree-pass.h"
     36 #include "dbgcnt.h"
     37 #include "rtl-iter.h"
     38 #include "print-rtl.h"
     39 
     40 /* This pass implements downward store motion.
     41    As of May 1, 2009, the pass is not enabled by default on any target,
     42    but bootstrap completes on ia64 and x86_64 with the pass enabled.  */
     43 
     44 /* TODO:
     45    - remove_reachable_equiv_notes is an incomprehensible pile of goo and
     46      a compile time hog that needs a rewrite (maybe cache st_exprs to
     47      invalidate REG_EQUAL/REG_EQUIV notes for?).
     48    - pattern_regs in st_expr should be a regset (on its own obstack).
     49    - store_motion_mems should be a vec instead of a list.
     50    - there should be an alloc pool for struct st_expr objects.
     51    - investigate whether it is helpful to make the address of an st_expr
     52      a cselib VALUE.
     53    - when GIMPLE alias information is exported, the effectiveness of this
     54      pass should be re-evaluated.
     55 */
     56 
     57 /* This is a list of store expressions (MEMs).  The structure is used
     58    as an expression table to track stores which look interesting, and
     59    might be moveable towards the exit block.  */
     60 
     61 struct st_expr
     62 {
     63   /* Pattern of this mem.  */
     64   rtx pattern;
     65   /* List of registers mentioned by the mem.  */
     66   vec<rtx> pattern_regs;
     67   /* INSN list of stores that are locally anticipatable.  */
     68   vec<rtx_insn *> antic_stores;
     69   /* INSN list of stores that are locally available.  */
     70   vec<rtx_insn *> avail_stores;
     71   /* Next in the list.  */
     72   struct st_expr * next;
     73   /* Store ID in the dataflow bitmaps.  */
     74   int index;
     75   /* Hash value for the hash table.  */
     76   unsigned int hash_index;
     77   /* Register holding the stored expression when a store is moved.
     78      This field is also used as a cache in find_moveable_store, see
     79      LAST_AVAIL_CHECK_FAILURE below.  */
     80   rtx reaching_reg;
     81 };
     82 
     83 /* Head of the list of load/store memory refs.  */
     84 static struct st_expr * store_motion_mems = NULL;
     85 
     86 /* These bitmaps will hold the local dataflow properties per basic block.  */
     87 static sbitmap *st_kill, *st_avloc, *st_antloc, *st_transp;
     88 
     89 /* Nonzero for expressions which should be inserted on a specific edge.  */
     90 static sbitmap *st_insert_map;
     91 
     92 /* Nonzero for expressions which should be deleted in a specific block.  */
     93 static sbitmap *st_delete_map;
     94 
     95 /* Global holding the number of store expressions we are dealing with.  */
     96 static int num_stores;
     97 
     98 /* Contains the edge_list returned by pre_edge_lcm.  */
     99 static struct edge_list *edge_list;
    100 
    101 /* Hashtable helpers.  */
    102 
    103 struct st_expr_hasher : nofree_ptr_hash <st_expr>
    104 {
    105   static inline hashval_t hash (const st_expr *);
    106   static inline bool equal (const st_expr *, const st_expr *);
    107 };
    108 
    109 inline hashval_t
    110 st_expr_hasher::hash (const st_expr *x)
    111 {
    112   int do_not_record_p = 0;
    113   return hash_rtx (x->pattern, GET_MODE (x->pattern), &do_not_record_p, NULL, false);
    114 }
    115 
    116 inline bool
    117 st_expr_hasher::equal (const st_expr *ptr1, const st_expr *ptr2)
    118 {
    119   return exp_equiv_p (ptr1->pattern, ptr2->pattern, 0, true);
    120 }
    121 
    122 /* Hashtable for the load/store memory refs.  */
    123 static hash_table<st_expr_hasher> *store_motion_mems_table;
    124 
    125 /* This will search the st_expr list for a matching expression. If it
    126    doesn't find one, we create one and initialize it.  */
    127 
    128 static struct st_expr *
    129 st_expr_entry (rtx x)
    130 {
    131   int do_not_record_p = 0;
    132   struct st_expr * ptr;
    133   unsigned int hash;
    134   st_expr **slot;
    135   struct st_expr e;
    136 
    137   hash = hash_rtx (x, GET_MODE (x), &do_not_record_p,
    138 		   NULL,  /*have_reg_qty=*/false);
    139 
    140   e.pattern = x;
    141   slot = store_motion_mems_table->find_slot_with_hash (&e, hash, INSERT);
    142   if (*slot)
    143     return *slot;
    144 
    145   ptr = XNEW (struct st_expr);
    146 
    147   ptr->next         = store_motion_mems;
    148   ptr->pattern      = x;
    149   ptr->pattern_regs.create (0);
    150   ptr->antic_stores.create (0);
    151   ptr->avail_stores.create (0);
    152   ptr->reaching_reg = NULL_RTX;
    153   ptr->index        = 0;
    154   ptr->hash_index   = hash;
    155   store_motion_mems = ptr;
    156   *slot = ptr;
    157 
    158   return ptr;
    159 }
    160 
    161 /* Free up an individual st_expr entry.  */
    162 
    163 static void
    164 free_st_expr_entry (struct st_expr * ptr)
    165 {
    166   ptr->antic_stores.release ();
    167   ptr->avail_stores.release ();
    168   ptr->pattern_regs.release ();
    169 
    170   free (ptr);
    171 }
    172 
    173 /* Free up all memory associated with the st_expr list.  */
    174 
    175 static void
    176 free_store_motion_mems (void)
    177 {
    178   delete store_motion_mems_table;
    179   store_motion_mems_table = NULL;
    180 
    181   while (store_motion_mems)
    182     {
    183       struct st_expr * tmp = store_motion_mems;
    184       store_motion_mems = store_motion_mems->next;
    185       free_st_expr_entry (tmp);
    186     }
    187   store_motion_mems = NULL;
    188 }
    189 
    190 /* Assign each element of the list of mems a monotonically increasing value.  */
    191 
    192 static int
    193 enumerate_store_motion_mems (void)
    194 {
    195   struct st_expr * ptr;
    196   int n = 0;
    197 
    198   for (ptr = store_motion_mems; ptr != NULL; ptr = ptr->next)
    199     ptr->index = n++;
    200 
    201   return n;
    202 }
    203 
    204 /* Return first item in the list.  */
    205 
    206 static inline struct st_expr *
    207 first_st_expr (void)
    208 {
    209   return store_motion_mems;
    210 }
    211 
    212 /* Return the next item in the list after the specified one.  */
    213 
    214 static inline struct st_expr *
    215 next_st_expr (struct st_expr * ptr)
    216 {
    217   return ptr->next;
    218 }
    219 
    220 /* Dump debugging info about the store_motion_mems list.  */
    221 
    222 static void
    223 print_store_motion_mems (FILE * file)
    224 {
    225   struct st_expr * ptr;
    226 
    227   fprintf (dump_file, "STORE_MOTION list of MEM exprs considered:\n");
    228 
    229   for (ptr = first_st_expr (); ptr != NULL; ptr = next_st_expr (ptr))
    230     {
    231       fprintf (file, "  Pattern (%3d): ", ptr->index);
    232 
    233       print_rtl (file, ptr->pattern);
    234 
    235       fprintf (file, "\n	 ANTIC stores : ");
    236       print_rtx_insn_vec (file, ptr->antic_stores);
    237 
    238       fprintf (file, "\n	 AVAIL stores : ");
    239 
    240 	print_rtx_insn_vec (file, ptr->avail_stores);
    241 
    242       fprintf (file, "\n\n");
    243     }
    244 
    245   fprintf (file, "\n");
    246 }
    247 
    248 /* Return zero if some of the registers in list X are killed
    250    due to set of registers in bitmap REGS_SET.  */
    251 
    252 static bool
    253 store_ops_ok (const vec<rtx> &x, int *regs_set)
    254 {
    255   for (rtx temp : x)
    256     if (regs_set[REGNO (temp)])
    257       return false;
    258 
    259   return true;
    260 }
    261 
    262 /* Returns a list of registers mentioned in X.
    263    FIXME: A regset would be prettier and less expensive.  */
    264 
    265 static void
    266 extract_mentioned_regs (rtx x, vec<rtx> *mentioned_regs)
    267 {
    268   subrtx_var_iterator::array_type array;
    269   FOR_EACH_SUBRTX_VAR (iter, array, x, NONCONST)
    270     {
    271       rtx x = *iter;
    272       if (REG_P (x))
    273 	mentioned_regs->safe_push (x);
    274     }
    275 }
    276 
    277 /* Check to see if the load X is aliased with STORE_PATTERN.
    278    AFTER is true if we are checking the case when STORE_PATTERN occurs
    279    after the X.  */
    280 
    281 static bool
    282 load_kills_store (const_rtx x, const_rtx store_pattern, int after)
    283 {
    284   if (after)
    285     return anti_dependence (x, store_pattern);
    286   else
    287     return true_dependence (store_pattern, GET_MODE (store_pattern), x);
    288 }
    289 
    290 /* Go through the entire rtx X, looking for any loads which might alias
    291    STORE_PATTERN.  Return true if found.
    292    AFTER is true if we are checking the case when STORE_PATTERN occurs
    293    after the insn X.  */
    294 
    295 static bool
    296 find_loads (const_rtx x, const_rtx store_pattern, int after)
    297 {
    298   const char * fmt;
    299   int i, j;
    300   int ret = false;
    301 
    302   if (!x)
    303     return false;
    304 
    305   if (GET_CODE (x) == SET)
    306     x = SET_SRC (x);
    307 
    308   if (MEM_P (x))
    309     {
    310       if (load_kills_store (x, store_pattern, after))
    311 	return true;
    312     }
    313 
    314   /* Recursively process the insn.  */
    315   fmt = GET_RTX_FORMAT (GET_CODE (x));
    316 
    317   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0 && !ret; i--)
    318     {
    319       if (fmt[i] == 'e')
    320 	ret |= find_loads (XEXP (x, i), store_pattern, after);
    321       else if (fmt[i] == 'E')
    322 	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
    323 	  ret |= find_loads (XVECEXP (x, i, j), store_pattern, after);
    324     }
    325   return ret;
    326 }
    327 
    328 /* Go through pattern PAT looking for any loads which might kill the
    329    store in X.  Return true if found.
    330    AFTER is true if we are checking the case when loads kill X occurs
    331    after the insn for PAT.  */
    332 
    333 static inline bool
    334 store_killed_in_pat (const_rtx x, const_rtx pat, int after)
    335 {
    336   if (GET_CODE (pat) == SET)
    337     {
    338       rtx dest = SET_DEST (pat);
    339 
    340       if (GET_CODE (dest) == ZERO_EXTRACT)
    341 	dest = XEXP (dest, 0);
    342 
    343       /* Check for memory stores to aliased objects.  */
    344       if (MEM_P (dest)
    345 	  && !exp_equiv_p (dest, x, 0, true))
    346 	{
    347 	  if (after)
    348 	    {
    349 	      if (output_dependence (dest, x))
    350 		return true;
    351 	    }
    352 	  else
    353 	    {
    354 	      if (output_dependence (x, dest))
    355 		return true;
    356 	    }
    357 	}
    358     }
    359 
    360   if (find_loads (pat, x, after))
    361     return true;
    362 
    363   return false;
    364 }
    365 
    366 /* Check if INSN kills the store pattern X (is aliased with it).
    367    AFTER is true if we are checking the case when store X occurs
    368    after the insn.  Return true if it does.  */
    369 
    370 static bool
    371 store_killed_in_insn (const_rtx x, const vec<rtx> &x_regs,
    372 		      const rtx_insn *insn, int after)
    373 {
    374   const_rtx note, pat;
    375 
    376   if (! NONDEBUG_INSN_P (insn))
    377     return false;
    378 
    379   if (CALL_P (insn))
    380     {
    381       /* A normal or pure call might read from pattern,
    382 	 but a const call will not.  */
    383       if (!RTL_CONST_CALL_P (insn))
    384 	return true;
    385 
    386       /* But even a const call reads its parameters.  Check whether the
    387 	 base of some of registers used in mem is stack pointer.  */
    388       for (rtx temp : x_regs)
    389 	if (may_be_sp_based_p (temp))
    390 	  return true;
    391 
    392       return false;
    393     }
    394 
    395   pat = PATTERN (insn);
    396   if (GET_CODE (pat) == SET)
    397     {
    398       if (store_killed_in_pat (x, pat, after))
    399 	return true;
    400     }
    401   else if (GET_CODE (pat) == PARALLEL)
    402     {
    403       int i;
    404 
    405       for (i = 0; i < XVECLEN (pat, 0); i++)
    406 	if (store_killed_in_pat (x, XVECEXP (pat, 0, i), after))
    407 	  return true;
    408     }
    409   else if (find_loads (PATTERN (insn), x, after))
    410     return true;
    411 
    412   /* If this insn has a REG_EQUAL or REG_EQUIV note referencing a memory
    413      location aliased with X, then this insn kills X.  */
    414   note = find_reg_equal_equiv_note (insn);
    415   if (! note)
    416     return false;
    417   note = XEXP (note, 0);
    418 
    419   /* However, if the note represents a must alias rather than a may
    420      alias relationship, then it does not kill X.  */
    421   if (exp_equiv_p (note, x, 0, true))
    422     return false;
    423 
    424   /* See if there are any aliased loads in the note.  */
    425   return find_loads (note, x, after);
    426 }
    427 
    428 /* Returns true if the expression X is loaded or clobbered on or after INSN
    429    within basic block BB.  REGS_SET_AFTER is bitmap of registers set in
    430    or after the insn.  X_REGS is list of registers mentioned in X. If the store
    431    is killed, return the last insn in that it occurs in FAIL_INSN.  */
    432 
    433 static bool
    434 store_killed_after (const_rtx x, const vec<rtx> &x_regs,
    435 		    const rtx_insn *insn, const_basic_block bb,
    436 		    int *regs_set_after, rtx *fail_insn)
    437 {
    438   rtx_insn *last = BB_END (bb), *act;
    439 
    440   if (!store_ops_ok (x_regs, regs_set_after))
    441     {
    442       /* We do not know where it will happen.  */
    443       if (fail_insn)
    444 	*fail_insn = NULL_RTX;
    445       return true;
    446     }
    447 
    448   /* Scan from the end, so that fail_insn is determined correctly.  */
    449   for (act = last; act != PREV_INSN (insn); act = PREV_INSN (act))
    450     if (store_killed_in_insn (x, x_regs, act, false))
    451       {
    452 	if (fail_insn)
    453 	  *fail_insn = act;
    454 	return true;
    455       }
    456 
    457   return false;
    458 }
    459 
    460 /* Returns true if the expression X is loaded or clobbered on or before INSN
    461    within basic block BB. X_REGS is list of registers mentioned in X.
    462    REGS_SET_BEFORE is bitmap of registers set before or in this insn.  */
    463 static bool
    464 store_killed_before (const_rtx x, const vec<rtx> &x_regs,
    465 		     const rtx_insn *insn, const_basic_block bb,
    466 		     int *regs_set_before)
    467 {
    468   rtx_insn *first = BB_HEAD (bb);
    469 
    470   if (!store_ops_ok (x_regs, regs_set_before))
    471     return true;
    472 
    473   for ( ; insn != PREV_INSN (first); insn = PREV_INSN (insn))
    474     if (store_killed_in_insn (x, x_regs, insn, true))
    475       return true;
    476 
    477   return false;
    478 }
    479 
    480 /* The last insn in the basic block that compute_store_table is processing,
    481    where store_killed_after is true for X.
    482    Since we go through the basic block from BB_END to BB_HEAD, this is
    483    also the available store at the end of the basic block.  Therefore
    484    this is in effect a cache, to avoid calling store_killed_after for
    485    equivalent aliasing store expressions.
    486    This value is only meaningful during the computation of the store
    487    table.  We hi-jack the REACHING_REG field of struct st_expr to save
    488    a bit of memory.  */
    489 #define LAST_AVAIL_CHECK_FAILURE(x)	((x)->reaching_reg)
    490 
    491 /* Determine whether INSN is MEM store pattern that we will consider moving.
    492    REGS_SET_BEFORE is bitmap of registers set before (and including) the
    493    current insn, REGS_SET_AFTER is bitmap of registers set after (and
    494    including) the insn in this basic block.  We must be passing through BB from
    495    head to end, as we are using this fact to speed things up.
    496 
    497    The results are stored this way:
    498 
    499    -- the first anticipatable expression is added into ANTIC_STORES
    500    -- if the processed expression is not anticipatable, NULL_RTX is added
    501       there instead, so that we can use it as indicator that no further
    502       expression of this type may be anticipatable
    503    -- if the expression is available, it is added as head of AVAIL_STORES;
    504       consequently, all of them but this head are dead and may be deleted.
    505    -- if the expression is not available, the insn due to that it fails to be
    506       available is stored in REACHING_REG (via LAST_AVAIL_CHECK_FAILURE).
    507 
    508    The things are complicated a bit by fact that there already may be stores
    509    to the same MEM from other blocks; also caller must take care of the
    510    necessary cleanup of the temporary markers after end of the basic block.
    511    */
    512 
    513 static void
    514 find_moveable_store (rtx_insn *insn, int *regs_set_before, int *regs_set_after)
    515 {
    516   struct st_expr * ptr;
    517   rtx dest, set;
    518   int check_anticipatable, check_available;
    519   basic_block bb = BLOCK_FOR_INSN (insn);
    520 
    521   set = single_set (insn);
    522   if (!set)
    523     return;
    524 
    525   dest = SET_DEST (set);
    526 
    527   if (! MEM_P (dest) || MEM_VOLATILE_P (dest)
    528       || GET_MODE (dest) == BLKmode)
    529     return;
    530 
    531   if (side_effects_p (dest))
    532     return;
    533 
    534   /* If we are handling exceptions, we must be careful with memory references
    535      that may trap.  If we are not, the behavior is undefined, so we may just
    536      continue.  */
    537   if (cfun->can_throw_non_call_exceptions && may_trap_p (dest))
    538     return;
    539 
    540   /* Even if the destination cannot trap, the source may.  In this case we'd
    541      need to handle updating the REG_EH_REGION note.  */
    542   if (find_reg_note (insn, REG_EH_REGION, NULL_RTX))
    543     return;
    544 
    545   /* Make sure that the SET_SRC of this store insns can be assigned to
    546      a register, or we will fail later on in replace_store_insn, which
    547      assumes that we can do this.  But sometimes the target machine has
    548      oddities like MEM read-modify-write instruction.  See for example
    549      PR24257.  */
    550   if (!can_assign_to_reg_without_clobbers_p (SET_SRC (set),
    551 					      GET_MODE (SET_SRC (set))))
    552     return;
    553 
    554   ptr = st_expr_entry (dest);
    555   if (ptr->pattern_regs.is_empty ())
    556     extract_mentioned_regs (dest, &ptr->pattern_regs);
    557 
    558   /* Do not check for anticipatability if we either found one anticipatable
    559      store already, or tested for one and found out that it was killed.  */
    560   check_anticipatable = 0;
    561   if (ptr->antic_stores.is_empty ())
    562     check_anticipatable = 1;
    563   else
    564     {
    565       rtx_insn *tmp = ptr->antic_stores.last ();
    566       if (tmp != NULL_RTX
    567 	  && BLOCK_FOR_INSN (tmp) != bb)
    568 	check_anticipatable = 1;
    569     }
    570   if (check_anticipatable)
    571     {
    572       rtx_insn *tmp;
    573       if (store_killed_before (dest, ptr->pattern_regs, insn, bb, regs_set_before))
    574 	tmp = NULL;
    575       else
    576 	tmp = insn;
    577       ptr->antic_stores.safe_push (tmp);
    578     }
    579 
    580   /* It is not necessary to check whether store is available if we did
    581      it successfully before; if we failed before, do not bother to check
    582      until we reach the insn that caused us to fail.  */
    583   check_available = 0;
    584   if (ptr->avail_stores.is_empty ())
    585     check_available = 1;
    586   else
    587     {
    588       rtx_insn *tmp = ptr->avail_stores.last ();
    589       if (BLOCK_FOR_INSN (tmp) != bb)
    590 	check_available = 1;
    591     }
    592   if (check_available)
    593     {
    594       /* Check that we have already reached the insn at that the check
    595 	 failed last time.  */
    596       if (LAST_AVAIL_CHECK_FAILURE (ptr))
    597 	{
    598 	  rtx_insn *tmp;
    599 	  for (tmp = BB_END (bb);
    600 	       tmp != insn && tmp != LAST_AVAIL_CHECK_FAILURE (ptr);
    601 	       tmp = PREV_INSN (tmp))
    602 	    continue;
    603 	  if (tmp == insn)
    604 	    check_available = 0;
    605 	}
    606       else
    607 	check_available = store_killed_after (dest, ptr->pattern_regs, insn,
    608 					      bb, regs_set_after,
    609 					      &LAST_AVAIL_CHECK_FAILURE (ptr));
    610     }
    611   if (!check_available)
    612     ptr->avail_stores.safe_push (insn);
    613 }
    614 
    615 /* Find available and anticipatable stores.  */
    616 
    617 static int
    618 compute_store_table (void)
    619 {
    620   int ret;
    621   basic_block bb;
    622   rtx_insn *insn;
    623   rtx_insn *tmp;
    624   df_ref def;
    625   int *last_set_in, *already_set;
    626   struct st_expr * ptr, **prev_next_ptr_ptr;
    627   unsigned int max_gcse_regno = max_reg_num ();
    628 
    629   store_motion_mems = NULL;
    630   store_motion_mems_table = new hash_table<st_expr_hasher> (13);
    631   last_set_in = XCNEWVEC (int, max_gcse_regno);
    632   already_set = XNEWVEC (int, max_gcse_regno);
    633 
    634   /* Find all the stores we care about.  */
    635   FOR_EACH_BB_FN (bb, cfun)
    636     {
    637       /* First compute the registers set in this block.  */
    638       FOR_BB_INSNS (bb, insn)
    639 	{
    640 
    641 	  if (! NONDEBUG_INSN_P (insn))
    642 	    continue;
    643 
    644 	  FOR_EACH_INSN_DEF (def, insn)
    645 	    last_set_in[DF_REF_REGNO (def)] = INSN_UID (insn);
    646 	}
    647 
    648       /* Now find the stores.  */
    649       memset (already_set, 0, sizeof (int) * max_gcse_regno);
    650       FOR_BB_INSNS (bb, insn)
    651 	{
    652 	  if (! NONDEBUG_INSN_P (insn))
    653 	    continue;
    654 
    655 	  FOR_EACH_INSN_DEF (def, insn)
    656 	    already_set[DF_REF_REGNO (def)] = INSN_UID (insn);
    657 
    658 	  /* Now that we've marked regs, look for stores.  */
    659 	  find_moveable_store (insn, already_set, last_set_in);
    660 
    661 	  /* Unmark regs that are no longer set.  */
    662 	  FOR_EACH_INSN_DEF (def, insn)
    663 	    if (last_set_in[DF_REF_REGNO (def)] == INSN_UID (insn))
    664 	      last_set_in[DF_REF_REGNO (def)] = 0;
    665 	}
    666 
    667       if (flag_checking)
    668 	{
    669 	  /* last_set_in should now be all-zero.  */
    670 	  for (unsigned regno = 0; regno < max_gcse_regno; regno++)
    671 	    gcc_assert (!last_set_in[regno]);
    672 	}
    673 
    674       /* Clear temporary marks.  */
    675       for (ptr = first_st_expr (); ptr != NULL; ptr = next_st_expr (ptr))
    676 	{
    677 	  LAST_AVAIL_CHECK_FAILURE (ptr) = NULL_RTX;
    678 	  if (!ptr->antic_stores.is_empty ()
    679 	      && (tmp = ptr->antic_stores.last ()) == NULL)
    680 	    ptr->antic_stores.pop ();
    681 	}
    682     }
    683 
    684   /* Remove the stores that are not available anywhere, as there will
    685      be no opportunity to optimize them.  */
    686   for (ptr = store_motion_mems, prev_next_ptr_ptr = &store_motion_mems;
    687        ptr != NULL;
    688        ptr = *prev_next_ptr_ptr)
    689     {
    690       if (ptr->avail_stores.is_empty ())
    691 	{
    692 	  *prev_next_ptr_ptr = ptr->next;
    693 	  store_motion_mems_table->remove_elt_with_hash (ptr, ptr->hash_index);
    694 	  free_st_expr_entry (ptr);
    695 	}
    696       else
    697 	prev_next_ptr_ptr = &ptr->next;
    698     }
    699 
    700   ret = enumerate_store_motion_mems ();
    701 
    702   if (dump_file)
    703     print_store_motion_mems (dump_file);
    704 
    705   free (last_set_in);
    706   free (already_set);
    707   return ret;
    708 }
    709 
    710 /* In all code following after this, REACHING_REG has its original
    711    meaning again.  Avoid confusion, and undef the accessor macro for
    712    the temporary marks usage in compute_store_table.  */
    713 #undef LAST_AVAIL_CHECK_FAILURE
    714 
    715 /* Insert an instruction at the beginning of a basic block, and update
    716    the BB_HEAD if needed.  */
    717 
    718 static void
    719 insert_insn_start_basic_block (rtx_insn *insn, basic_block bb)
    720 {
    721   /* Insert at start of successor block.  */
    722   rtx_insn *prev = PREV_INSN (BB_HEAD (bb));
    723   rtx_insn *before = BB_HEAD (bb);
    724   while (before != 0)
    725     {
    726       if (! LABEL_P (before)
    727 	  && !NOTE_INSN_BASIC_BLOCK_P (before))
    728 	break;
    729       prev = before;
    730       if (prev == BB_END (bb))
    731 	break;
    732       before = NEXT_INSN (before);
    733     }
    734 
    735   insn = emit_insn_after_noloc (insn, prev, bb);
    736 
    737   if (dump_file)
    738     {
    739       fprintf (dump_file, "STORE_MOTION  insert store at start of BB %d:\n",
    740 	       bb->index);
    741       print_inline_rtx (dump_file, insn, 6);
    742       fprintf (dump_file, "\n");
    743     }
    744 }
    745 
    746 /* This routine will insert a store on an edge. EXPR is the st_expr entry for
    747    the memory reference, and E is the edge to insert it on.  Returns nonzero
    748    if an edge insertion was performed.  */
    749 
    750 static int
    751 insert_store (struct st_expr * expr, edge e)
    752 {
    753   rtx reg;
    754   rtx_insn *insn;
    755   basic_block bb;
    756   edge tmp;
    757   edge_iterator ei;
    758 
    759   /* We did all the deleted before this insert, so if we didn't delete a
    760      store, then we haven't set the reaching reg yet either.  */
    761   if (expr->reaching_reg == NULL_RTX)
    762     return 0;
    763 
    764   if (e->flags & EDGE_FAKE)
    765     return 0;
    766 
    767   reg = expr->reaching_reg;
    768   insn = gen_move_insn (copy_rtx (expr->pattern), reg);
    769 
    770   /* If we are inserting this expression on ALL predecessor edges of a BB,
    771      insert it at the start of the BB, and reset the insert bits on the other
    772      edges so we don't try to insert it on the other edges.  */
    773   bb = e->dest;
    774   FOR_EACH_EDGE (tmp, ei, e->dest->preds)
    775     if (!(tmp->flags & EDGE_FAKE))
    776       {
    777 	int index = EDGE_INDEX (edge_list, tmp->src, tmp->dest);
    778 
    779 	gcc_assert (index != EDGE_INDEX_NO_EDGE);
    780 	if (! bitmap_bit_p (st_insert_map[index], expr->index))
    781 	  break;
    782       }
    783 
    784   /* If tmp is NULL, we found an insertion on every edge, blank the
    785      insertion vector for these edges, and insert at the start of the BB.  */
    786   if (!tmp && bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
    787     {
    788       FOR_EACH_EDGE (tmp, ei, e->dest->preds)
    789 	{
    790 	  int index = EDGE_INDEX (edge_list, tmp->src, tmp->dest);
    791 	  bitmap_clear_bit (st_insert_map[index], expr->index);
    792 	}
    793       insert_insn_start_basic_block (insn, bb);
    794       return 0;
    795     }
    796 
    797   /* We can't put stores in the front of blocks pointed to by abnormal
    798      edges since that may put a store where one didn't used to be.  */
    799   gcc_assert (!(e->flags & EDGE_ABNORMAL));
    800 
    801   insert_insn_on_edge (insn, e);
    802 
    803   if (dump_file)
    804     {
    805       fprintf (dump_file, "STORE_MOTION  insert insn on edge (%d, %d):\n",
    806 	       e->src->index, e->dest->index);
    807       print_inline_rtx (dump_file, insn, 6);
    808       fprintf (dump_file, "\n");
    809     }
    810 
    811   return 1;
    812 }
    813 
    814 /* Remove any REG_EQUAL or REG_EQUIV notes containing a reference to the
    815    memory location in SMEXPR set in basic block BB.
    816 
    817    This could be rather expensive.  */
    818 
    819 static void
    820 remove_reachable_equiv_notes (basic_block bb, struct st_expr *smexpr)
    821 {
    822   edge_iterator *stack, ei;
    823   int sp;
    824   edge act;
    825   auto_sbitmap visited (last_basic_block_for_fn (cfun));
    826   rtx note;
    827   rtx_insn *insn;
    828   rtx mem = smexpr->pattern;
    829 
    830   stack = XNEWVEC (edge_iterator, n_basic_blocks_for_fn (cfun));
    831   sp = 0;
    832   ei = ei_start (bb->succs);
    833 
    834   bitmap_clear (visited);
    835 
    836   act = (EDGE_COUNT (ei_container (ei))
    837 	 ? EDGE_I (ei_container (ei), 0)
    838 	 : NULL);
    839   for (;;)
    840     {
    841       if (!act)
    842 	{
    843 	  if (!sp)
    844 	    {
    845 	      free (stack);
    846 	      return;
    847 	    }
    848 	  act = ei_edge (stack[--sp]);
    849 	}
    850       bb = act->dest;
    851 
    852       if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
    853 	  || bitmap_bit_p (visited, bb->index))
    854 	{
    855 	  if (!ei_end_p (ei))
    856 	      ei_next (&ei);
    857 	  act = (! ei_end_p (ei)) ? ei_edge (ei) : NULL;
    858 	  continue;
    859 	}
    860       bitmap_set_bit (visited, bb->index);
    861 
    862       rtx_insn *last;
    863       if (bitmap_bit_p (st_antloc[bb->index], smexpr->index))
    864 	{
    865 	  unsigned int i;
    866 	  FOR_EACH_VEC_ELT_REVERSE (smexpr->antic_stores, i, last)
    867 	    if (BLOCK_FOR_INSN (last) == bb)
    868 	      break;
    869 	}
    870       else
    871 	last = NEXT_INSN (BB_END (bb));
    872 
    873       for (insn = BB_HEAD (bb); insn != last; insn = NEXT_INSN (insn))
    874 	if (NONDEBUG_INSN_P (insn))
    875 	  {
    876 	    note = find_reg_equal_equiv_note (insn);
    877 	    if (!note || !exp_equiv_p (XEXP (note, 0), mem, 0, true))
    878 	      continue;
    879 
    880 	    if (dump_file)
    881 	      fprintf (dump_file,
    882 		       "STORE_MOTION  drop REG_EQUAL note at insn %d:\n",
    883 		       INSN_UID (insn));
    884 	    remove_note (insn, note);
    885 	  }
    886 
    887       if (!ei_end_p (ei))
    888 	ei_next (&ei);
    889       act = (! ei_end_p (ei)) ? ei_edge (ei) : NULL;
    890 
    891       if (EDGE_COUNT (bb->succs) > 0)
    892 	{
    893 	  if (act)
    894 	    stack[sp++] = ei;
    895 	  ei = ei_start (bb->succs);
    896 	  act = (EDGE_COUNT (ei_container (ei))
    897 		 ? EDGE_I (ei_container (ei), 0)
    898 		 : NULL);
    899 	}
    900     }
    901 }
    902 
    903 /* This routine will replace a store with a SET to a specified register.  */
    904 
    905 static void
    906 replace_store_insn (rtx reg, rtx_insn *del, basic_block bb,
    907 		    struct st_expr *smexpr)
    908 {
    909   rtx_insn *insn;
    910   rtx mem, note, set;
    911 
    912   insn = prepare_copy_insn (reg, SET_SRC (single_set (del)));
    913 
    914   unsigned int i;
    915   rtx_insn *temp;
    916   FOR_EACH_VEC_ELT_REVERSE (smexpr->antic_stores, i, temp)
    917     if (temp == del)
    918       {
    919 	smexpr->antic_stores[i] = insn;
    920 	break;
    921       }
    922 
    923   /* Move the notes from the deleted insn to its replacement.  */
    924   REG_NOTES (insn) = REG_NOTES (del);
    925 
    926   /* Emit the insn AFTER all the notes are transferred.
    927      This is cheaper since we avoid df rescanning for the note change.  */
    928   insn = emit_insn_after (insn, del);
    929 
    930   if (dump_file)
    931     {
    932       fprintf (dump_file,
    933 	       "STORE_MOTION  delete insn in BB %d:\n      ", bb->index);
    934       print_inline_rtx (dump_file, del, 6);
    935       fprintf (dump_file, "\nSTORE_MOTION  replaced with insn:\n      ");
    936       print_inline_rtx (dump_file, insn, 6);
    937       fprintf (dump_file, "\n");
    938     }
    939 
    940   delete_insn (del);
    941 
    942   /* Now we must handle REG_EQUAL notes whose contents is equal to the mem;
    943      they are no longer accurate provided that they are reached by this
    944      definition, so drop them.  */
    945   mem = smexpr->pattern;
    946   for (; insn != NEXT_INSN (BB_END (bb)); insn = NEXT_INSN (insn))
    947     if (NONDEBUG_INSN_P (insn))
    948       {
    949 	set = single_set (insn);
    950 	if (!set)
    951 	  continue;
    952 	if (exp_equiv_p (SET_DEST (set), mem, 0, true))
    953 	  return;
    954 	note = find_reg_equal_equiv_note (insn);
    955 	if (!note || !exp_equiv_p (XEXP (note, 0), mem, 0, true))
    956 	  continue;
    957 
    958 	if (dump_file)
    959 	  fprintf (dump_file, "STORE_MOTION  drop REG_EQUAL note at insn %d:\n",
    960 		   INSN_UID (insn));
    961 	remove_note (insn, note);
    962       }
    963   remove_reachable_equiv_notes (bb, smexpr);
    964 }
    965 
    966 
    967 /* Delete a store, but copy the value that would have been stored into
    968    the reaching_reg for later storing.  */
    969 
    970 static void
    971 delete_store (struct st_expr * expr, basic_block bb)
    972 {
    973   rtx reg;
    974 
    975   if (expr->reaching_reg == NULL_RTX)
    976     expr->reaching_reg = gen_reg_rtx_and_attrs (expr->pattern);
    977 
    978   reg = expr->reaching_reg;
    979 
    980   unsigned int len = expr->avail_stores.length ();
    981   for (unsigned int i = len - 1; i < len; i--)
    982     {
    983       rtx_insn *del = expr->avail_stores[i];
    984       if (BLOCK_FOR_INSN (del) == bb)
    985 	{
    986 	  /* We know there is only one since we deleted redundant
    987 	     ones during the available computation.  */
    988 	  replace_store_insn (reg, del, bb, expr);
    989 	  break;
    990 	}
    991     }
    992 }
    993 
    994 /* Fill in available, anticipatable, transparent and kill vectors in
    995    STORE_DATA, based on lists of available and anticipatable stores.  */
    996 static void
    997 build_store_vectors (void)
    998 {
    999   basic_block bb;
   1000   int *regs_set_in_block;
   1001   rtx_insn *insn;
   1002   struct st_expr * ptr;
   1003   unsigned int max_gcse_regno = max_reg_num ();
   1004 
   1005   /* Build the gen_vector. This is any store in the table which is not killed
   1006      by aliasing later in its block.  */
   1007   st_avloc = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
   1008 				   num_stores);
   1009   bitmap_vector_clear (st_avloc, last_basic_block_for_fn (cfun));
   1010 
   1011   st_antloc = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
   1012 				    num_stores);
   1013   bitmap_vector_clear (st_antloc, last_basic_block_for_fn (cfun));
   1014 
   1015   for (ptr = first_st_expr (); ptr != NULL; ptr = next_st_expr (ptr))
   1016     {
   1017       unsigned int len = ptr->avail_stores.length ();
   1018       for (unsigned int i = len - 1; i < len; i--)
   1019 	{
   1020 	  insn = ptr->avail_stores[i];
   1021 	  bb = BLOCK_FOR_INSN (insn);
   1022 
   1023 	  /* If we've already seen an available expression in this block,
   1024 	     we can delete this one (It occurs earlier in the block). We'll
   1025 	     copy the SRC expression to an unused register in case there
   1026 	     are any side effects.  */
   1027 	  if (bitmap_bit_p (st_avloc[bb->index], ptr->index))
   1028 	    {
   1029 	      rtx r = gen_reg_rtx_and_attrs (ptr->pattern);
   1030 	      if (dump_file)
   1031 		fprintf (dump_file, "Removing redundant store:\n");
   1032 	      replace_store_insn (r, insn, bb, ptr);
   1033 	      continue;
   1034 	    }
   1035 	  bitmap_set_bit (st_avloc[bb->index], ptr->index);
   1036 	}
   1037 
   1038       unsigned int i;
   1039       FOR_EACH_VEC_ELT_REVERSE (ptr->antic_stores, i, insn)
   1040 	{
   1041 	  bb = BLOCK_FOR_INSN (insn);
   1042 	  bitmap_set_bit (st_antloc[bb->index], ptr->index);
   1043 	}
   1044     }
   1045 
   1046   st_kill = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), num_stores);
   1047   bitmap_vector_clear (st_kill, last_basic_block_for_fn (cfun));
   1048 
   1049   st_transp = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), num_stores);
   1050   bitmap_vector_clear (st_transp, last_basic_block_for_fn (cfun));
   1051   regs_set_in_block = XNEWVEC (int, max_gcse_regno);
   1052 
   1053   FOR_EACH_BB_FN (bb, cfun)
   1054     {
   1055       memset (regs_set_in_block, 0, sizeof (int) * max_gcse_regno);
   1056 
   1057       FOR_BB_INSNS (bb, insn)
   1058 	if (NONDEBUG_INSN_P (insn))
   1059 	  {
   1060 	    df_ref def;
   1061 	    FOR_EACH_INSN_DEF (def, insn)
   1062 	      {
   1063 		unsigned int ref_regno = DF_REF_REGNO (def);
   1064 		if (ref_regno < max_gcse_regno)
   1065 		  regs_set_in_block[DF_REF_REGNO (def)] = 1;
   1066 	      }
   1067 	  }
   1068 
   1069       for (ptr = first_st_expr (); ptr != NULL; ptr = next_st_expr (ptr))
   1070 	{
   1071 	  if (store_killed_after (ptr->pattern, ptr->pattern_regs, BB_HEAD (bb),
   1072 				  bb, regs_set_in_block, NULL))
   1073 	    {
   1074 	      /* It should not be necessary to consider the expression
   1075 		 killed if it is both anticipatable and available.  */
   1076 	      if (!bitmap_bit_p (st_antloc[bb->index], ptr->index)
   1077 		  || !bitmap_bit_p (st_avloc[bb->index], ptr->index))
   1078 		bitmap_set_bit (st_kill[bb->index], ptr->index);
   1079 	    }
   1080 	  else
   1081 	    bitmap_set_bit (st_transp[bb->index], ptr->index);
   1082 	}
   1083     }
   1084 
   1085   free (regs_set_in_block);
   1086 
   1087   if (dump_file)
   1088     {
   1089       dump_bitmap_vector (dump_file, "st_antloc", "", st_antloc,
   1090 			  last_basic_block_for_fn (cfun));
   1091       dump_bitmap_vector (dump_file, "st_kill", "", st_kill,
   1092 			  last_basic_block_for_fn (cfun));
   1093       dump_bitmap_vector (dump_file, "st_transp", "", st_transp,
   1094 			  last_basic_block_for_fn (cfun));
   1095       dump_bitmap_vector (dump_file, "st_avloc", "", st_avloc,
   1096 			  last_basic_block_for_fn (cfun));
   1097     }
   1098 }
   1099 
   1100 /* Free memory used by store motion.  */
   1101 
   1102 static void
   1103 free_store_memory (void)
   1104 {
   1105   free_store_motion_mems ();
   1106 
   1107   if (st_avloc)
   1108     sbitmap_vector_free (st_avloc);
   1109   if (st_kill)
   1110     sbitmap_vector_free (st_kill);
   1111   if (st_transp)
   1112     sbitmap_vector_free (st_transp);
   1113   if (st_antloc)
   1114     sbitmap_vector_free (st_antloc);
   1115   if (st_insert_map)
   1116     sbitmap_vector_free (st_insert_map);
   1117   if (st_delete_map)
   1118     sbitmap_vector_free (st_delete_map);
   1119 
   1120   st_avloc = st_kill = st_transp = st_antloc = NULL;
   1121   st_insert_map = st_delete_map = NULL;
   1122 }
   1123 
   1124 /* Perform store motion. Much like gcse, except we move expressions the
   1125    other way by looking at the flowgraph in reverse.
   1126    Return non-zero if transformations are performed by the pass.  */
   1127 
   1128 static int
   1129 one_store_motion_pass (void)
   1130 {
   1131   basic_block bb;
   1132   int x;
   1133   struct st_expr * ptr;
   1134   int did_edge_inserts = 0;
   1135   int n_stores_deleted = 0;
   1136   int n_stores_created = 0;
   1137 
   1138   init_alias_analysis ();
   1139 
   1140   /* Find all the available and anticipatable stores.  */
   1141   num_stores = compute_store_table ();
   1142   if (num_stores == 0)
   1143     {
   1144       delete store_motion_mems_table;
   1145       store_motion_mems_table = NULL;
   1146       end_alias_analysis ();
   1147       return 0;
   1148     }
   1149 
   1150   /* Now compute kill & transp vectors.  */
   1151   build_store_vectors ();
   1152   connect_infinite_loops_to_exit ();
   1153 
   1154   edge_list = pre_edge_rev_lcm (num_stores, st_transp, st_avloc,
   1155 				st_antloc, st_kill, &st_insert_map,
   1156 				&st_delete_map);
   1157 
   1158   /* Now we want to insert the new stores which are going to be needed.  */
   1159   for (ptr = first_st_expr (); ptr != NULL; ptr = next_st_expr (ptr))
   1160     {
   1161       /* If any of the edges we have above are abnormal, we can't move this
   1162 	 store.  */
   1163       for (x = NUM_EDGES (edge_list) - 1; x >= 0; x--)
   1164 	if (bitmap_bit_p (st_insert_map[x], ptr->index)
   1165 	    && (INDEX_EDGE (edge_list, x)->flags & EDGE_ABNORMAL))
   1166 	  break;
   1167 
   1168       if (x >= 0)
   1169 	{
   1170 	  if (dump_file != NULL)
   1171 	    fprintf (dump_file,
   1172 		     "Can't replace store %d: abnormal edge from %d to %d\n",
   1173 		     ptr->index, INDEX_EDGE (edge_list, x)->src->index,
   1174 		     INDEX_EDGE (edge_list, x)->dest->index);
   1175 	  continue;
   1176 	}
   1177 
   1178       /* Now we want to insert the new stores which are going to be needed.  */
   1179 
   1180       FOR_EACH_BB_FN (bb, cfun)
   1181 	if (bitmap_bit_p (st_delete_map[bb->index], ptr->index))
   1182 	  {
   1183 	    delete_store (ptr, bb);
   1184 	    n_stores_deleted++;
   1185 	  }
   1186 
   1187       for (x = 0; x < NUM_EDGES (edge_list); x++)
   1188 	if (bitmap_bit_p (st_insert_map[x], ptr->index))
   1189 	  {
   1190 	    did_edge_inserts |= insert_store (ptr, INDEX_EDGE (edge_list, x));
   1191 	    n_stores_created++;
   1192 	  }
   1193     }
   1194 
   1195   if (did_edge_inserts)
   1196     commit_edge_insertions ();
   1197 
   1198   free_store_memory ();
   1199   free_edge_list (edge_list);
   1200   remove_fake_exit_edges ();
   1201   end_alias_analysis ();
   1202 
   1203   if (dump_file)
   1204     {
   1205       fprintf (dump_file, "STORE_MOTION of %s, %d basic blocks, ",
   1206 	       current_function_name (), n_basic_blocks_for_fn (cfun));
   1207       fprintf (dump_file, "%d insns deleted, %d insns created\n",
   1208 	       n_stores_deleted, n_stores_created);
   1209     }
   1210 
   1211   return (n_stores_deleted > 0 || n_stores_created > 0);
   1212 }
   1213 
   1214 
   1215 static unsigned int
   1217 execute_rtl_store_motion (void)
   1218 {
   1219   delete_unreachable_blocks ();
   1220   df_analyze ();
   1221   flag_rerun_cse_after_global_opts |= one_store_motion_pass ();
   1222   return 0;
   1223 }
   1224 
   1225 namespace {
   1226 
   1227 const pass_data pass_data_rtl_store_motion =
   1228 {
   1229   RTL_PASS, /* type */
   1230   "store_motion", /* name */
   1231   OPTGROUP_NONE, /* optinfo_flags */
   1232   TV_LSM, /* tv_id */
   1233   PROP_cfglayout, /* properties_required */
   1234   0, /* properties_provided */
   1235   0, /* properties_destroyed */
   1236   0, /* todo_flags_start */
   1237   TODO_df_finish, /* todo_flags_finish */
   1238 };
   1239 
   1240 class pass_rtl_store_motion : public rtl_opt_pass
   1241 {
   1242 public:
   1243   pass_rtl_store_motion (gcc::context *ctxt)
   1244     : rtl_opt_pass (pass_data_rtl_store_motion, ctxt)
   1245   {}
   1246 
   1247   /* opt_pass methods: */
   1248   virtual bool gate (function *);
   1249   virtual unsigned int execute (function *)
   1250     {
   1251       return execute_rtl_store_motion ();
   1252     }
   1253 
   1254 }; // class pass_rtl_store_motion
   1255 
   1256 bool
   1257 pass_rtl_store_motion::gate (function *fun)
   1258 {
   1259   return optimize > 0 && flag_gcse_sm
   1260     && !fun->calls_setjmp
   1261     && optimize_function_for_speed_p (fun)
   1262     && dbg_cnt (store_motion);
   1263 }
   1264 
   1265 } // anon namespace
   1266 
   1267 rtl_opt_pass *
   1268 make_pass_rtl_store_motion (gcc::context *ctxt)
   1269 {
   1270   return new pass_rtl_store_motion (ctxt);
   1271 }
   1272