/* Post reload partially redundant load elimination
   Copyright (C) 2004-2025 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "predict.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "insn-config.h"
#include "emit-rtl.h"
#include "recog.h"

#include "cfgrtl.h"
#include "profile.h"
#include "expr.h"
#include "tree-pass.h"
#include "dbgcnt.h"
#include "intl.h"
#include "gcse-common.h"
#include "gcse.h"
#include "regs.h"
#include "function-abi.h"

/* The following code implements gcse after reload, the purpose of this
   pass is to cleanup redundant loads generated by reload and other
   optimizations that come after gcse. It searches for simple inter-block
   redundancies and tries to eliminate them by adding moves and loads
   in cold places.

   Perform partially redundant load elimination, try to eliminate redundant
   loads created by the reload pass.  We try to look for full or partial
   redundant loads fed by one or more loads/stores in predecessor BBs,
   and try adding loads to make them fully redundant.  We also check if
   it's worth adding loads to be able to delete the redundant load.

   Algorithm:
   1. Build available expressions hash table:
       For each load/store instruction, if the loaded/stored memory didn't
       change until the end of the basic block add this memory expression to
       the hash table.
   2. Perform Redundancy elimination:
      For each load instruction do the following:
	 perform partial redundancy elimination, check if it's worth adding
	 loads to make the load fully redundant.  If so add loads and
	 register copies and delete the load.
   3. Delete instructions made redundant in step 2.

   Future enhancement:
     If the loaded register is used/defined between load and some store,
     look for some other free register between load and all its stores,
     and replace the load with a copy from this register to the loaded
     register.
*/


/* Keep statistics of this pass.  */
static struct
{
  int moves_inserted;
  int copies_inserted;
  int insns_deleted;
} stats;

/* We need to keep a hash table of expressions.  The table entries are of
   type 'struct expr', and for each expression there is a single linked
   list of occurrences.  */

/* Expression elements in the hash table.  */
struct expr
{
  /* The expression (SET_SRC for expressions, PATTERN for assignments).  */
  rtx expr;

  /* The same hash for this entry.  */
  hashval_t hash;

  /* Index in the transparent bitmaps.  */
  unsigned int bitmap_index;

  /* List of available occurrence in basic blocks in the function.  */
  struct occr *avail_occr;
};

/* Hashtable helpers.  */

struct expr_hasher : nofree_ptr_hash <expr>
{
  static inline hashval_t hash (const expr *);
  static inline bool equal (const expr *, const expr *);
};


/* Hash expression X.
   DO_NOT_RECORD_P is a boolean indicating if a volatile operand is found
   or if the expression contains something we don't want to insert in the
   table.  */

static hashval_t
hash_expr (rtx x, int *do_not_record_p)
{
  *do_not_record_p = 0;
  return hash_rtx (x, GET_MODE (x), do_not_record_p,
		   NULL,  /*have_reg_qty=*/false);
}

/* Callback for hashtab.
   Return the hash value for expression EXP.  We don't actually hash
   here, we just return the cached hash value.  */

inline hashval_t
expr_hasher::hash (const expr *exp)
{
  return exp->hash;
}

/* Callback for hashtab.
   Return nonzero if exp1 is equivalent to exp2.  */

inline bool
expr_hasher::equal (const expr *exp1, const expr *exp2)
{
  bool equiv_p = exp_equiv_p (exp1->expr, exp2->expr, 0, true);

  gcc_assert (!equiv_p || exp1->hash == exp2->hash);
  return equiv_p;
}

/* The table itself.  */
static hash_table<expr_hasher> *expr_table;


static struct obstack expr_obstack;

/* Occurrence of an expression.
   There is at most one occurrence per basic block.  If a pattern appears
   more than once, the last appearance is used.  */

struct occr
{
  /* Next occurrence of this expression.  */
  struct occr *next;
  /* The insn that computes the expression.  */
  rtx_insn *insn;
  /* Nonzero if this [anticipatable] occurrence has been deleted.  */
  char deleted_p;
};

static struct obstack occr_obstack;

/* The following structure holds the information about the occurrences of
   the redundant instructions.  */
struct unoccr
{
  struct unoccr *next;
  edge pred;
  rtx_insn *insn;
};

static struct obstack unoccr_obstack;

/* Array where each element is the CUID if the insn that last set the hard
   register with the number of the element, since the start of the current
   basic block.

   This array is used during the building of the hash table (step 1) to
   determine if a reg is killed before the end of a basic block.

   It is also used when eliminating partial redundancies (step 2) to see
   if a reg was modified since the start of a basic block.  */
static int *reg_avail_info;

/* A list of insns that may modify memory within the current basic block.  */
struct modifies_mem
{
  rtx_insn *insn;
  struct modifies_mem *next;
};
static struct modifies_mem *modifies_mem_list;

/* The modifies_mem structs also go on an obstack, only this obstack is
   freed each time after completing the analysis or transformations on
   a basic block.  So we allocate a dummy modifies_mem_obstack_bottom
   object on the obstack to keep track of the bottom of the obstack.  */
static struct obstack modifies_mem_obstack;
static struct modifies_mem  *modifies_mem_obstack_bottom;

/* Mapping of insn UIDs to CUIDs.
   CUIDs are like UIDs except they increase monotonically in each basic
   block, have no gaps, and only apply to real insns.  */
static int *uid_cuid;
#define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)])

/* Bitmap of blocks which have memory stores.  */
static bitmap modify_mem_list_set;

/* Bitmap of blocks which have calls.  */
static bitmap blocks_with_calls;

/* Vector indexed by block # with a list of all the insns that
   modify memory within the block.  */
static vec<rtx_insn *> *modify_mem_list;

/* Vector indexed by block # with a canonicalized list of insns
   that modify memory in the block.  */
static vec<modify_pair> *canon_modify_mem_list;

/* Vector of simple bitmaps indexed by block number.  Each component sbitmap
   indicates which expressions are transparent through the block.  */
static sbitmap *transp;


/* Helpers for memory allocation/freeing.  */
static void alloc_mem (void);
static void free_mem (void);

/* Support for hash table construction and transformations.  */
static bool oprs_unchanged_p (rtx, rtx_insn *, bool);
static void record_last_reg_set_info (rtx_insn *, rtx);
static void record_last_reg_set_info_regno (rtx_insn *, int);
static void record_last_mem_set_info (rtx_insn *);
static void record_last_set_info (rtx, const_rtx, void *);
static void record_opr_changes (rtx_insn *);

static void find_mem_conflicts (rtx, const_rtx, void *);
static bool load_killed_in_block_p (int, rtx, bool);
static void reset_opr_set_tables (void);

/* Hash table support.  */
static hashval_t hash_expr (rtx, int *);
static void insert_expr_in_table (rtx, rtx_insn *);
static struct expr *lookup_expr_in_table (rtx);
static void dump_hash_table (FILE *);

/* Helpers for eliminate_partially_redundant_load.  */
static bool reg_killed_on_edge (rtx, edge);
static bool reg_used_on_edge (rtx, edge);

static rtx get_avail_load_store_reg (rtx_insn *);

static bool bb_has_well_behaved_predecessors (basic_block);
static struct occr* get_bb_avail_insn (basic_block, struct occr *, int);
static void hash_scan_set (rtx_insn *);
static void compute_hash_table (void);

/* The work horses of this pass.  */
static void eliminate_partially_redundant_load (basic_block,
						rtx_insn *,
						struct expr *);
static void eliminate_partially_redundant_loads (void);


/* Allocate memory for the CUID mapping array and register/memory
   tracking tables.  */

static void
alloc_mem (void)
{
  int i;
  basic_block bb;
  rtx_insn *insn;

  /* Find the largest UID and create a mapping from UIDs to CUIDs.  */
  uid_cuid = XCNEWVEC (int, get_max_uid () + 1);
  i = 1;
  FOR_EACH_BB_FN (bb, cfun)
    FOR_BB_INSNS (bb, insn)
      {
        if (INSN_P (insn))
	  uid_cuid[INSN_UID (insn)] = i++;
	else
	  uid_cuid[INSN_UID (insn)] = i;
      }

  /* Allocate the available expressions hash table.  We don't want to
     make the hash table too small, but unnecessarily making it too large
     also doesn't help.  The i/4 is a gcse.cc relic, and seems like a
     reasonable choice.  */
  expr_table = new hash_table<expr_hasher> (MAX (i / 4, 13));

  /* We allocate everything on obstacks because we often can roll back
     the whole obstack to some point.  Freeing obstacks is very fast.  */
  gcc_obstack_init (&expr_obstack);
  gcc_obstack_init (&occr_obstack);
  gcc_obstack_init (&unoccr_obstack);
  gcc_obstack_init (&modifies_mem_obstack);

  /* Working array used to track the last set for each register
     in the current block.  */
  reg_avail_info = (int *) xmalloc (FIRST_PSEUDO_REGISTER * sizeof (int));

  /* Put a dummy modifies_mem object on the modifies_mem_obstack, so we
     can roll it back in reset_opr_set_tables.  */
  modifies_mem_obstack_bottom =
    (struct modifies_mem *) obstack_alloc (&modifies_mem_obstack,
					   sizeof (struct modifies_mem));

  blocks_with_calls = BITMAP_ALLOC (NULL);
  modify_mem_list_set = BITMAP_ALLOC (NULL);

  modify_mem_list = (vec_rtx_heap *) xcalloc (last_basic_block_for_fn (cfun),
					      sizeof (vec_rtx_heap));
  canon_modify_mem_list
    = (vec_modify_pair_heap *) xcalloc (last_basic_block_for_fn (cfun),
					sizeof (vec_modify_pair_heap));
}

/* Free memory allocated by alloc_mem.  */

static void
free_mem (void)
{
  free (uid_cuid);

  delete expr_table;
  expr_table = NULL;

  obstack_free (&expr_obstack, NULL);
  obstack_free (&occr_obstack, NULL);
  obstack_free (&unoccr_obstack, NULL);
  obstack_free (&modifies_mem_obstack, NULL);

  unsigned i;
  bitmap_iterator bi;
  EXECUTE_IF_SET_IN_BITMAP (modify_mem_list_set, 0, i, bi)
    {
      modify_mem_list[i].release ();
      canon_modify_mem_list[i].release ();
    }

  BITMAP_FREE (blocks_with_calls);
  BITMAP_FREE (modify_mem_list_set);
  free (reg_avail_info);
  free (modify_mem_list);
  free (canon_modify_mem_list);
}


/* Insert expression X in INSN in the hash TABLE.
   If it is already present, record it as the last occurrence in INSN's
   basic block.  */

static void
insert_expr_in_table (rtx x, rtx_insn *insn)
{
  int do_not_record_p;
  hashval_t hash;
  struct expr *cur_expr, **slot;
  struct occr *avail_occr;

  hash = hash_expr (x, &do_not_record_p);

  /* Do not insert expression in the table if it contains volatile operands,
     or if hash_expr determines the expression is something we don't want
     to or can't handle.  */
  if (do_not_record_p)
    return;

  /* We anticipate that redundant expressions are rare, so for convenience
     allocate a new hash table element here already and set its fields.
     If we don't do this, we need a hack with a static struct expr.  Anyway,
     obstack_free is really fast and one more obstack_alloc doesn't hurt if
     we're going to see more expressions later on.  */
  cur_expr = (struct expr *) obstack_alloc (&expr_obstack,
					    sizeof (struct expr));
  cur_expr->expr = x;
  cur_expr->hash = hash;
  cur_expr->avail_occr = NULL;

  slot = expr_table->find_slot_with_hash (cur_expr, hash, INSERT);

  if (! (*slot))
    {
      /* The expression isn't found, so insert it.  */
      *slot = cur_expr;

      /* Anytime we add an entry to the table, record the index
	 of the new entry.  The bitmap index starts counting
	 at zero.  */
      cur_expr->bitmap_index = expr_table->elements () - 1;
    }
  else
    {
      /* The expression is already in the table, so roll back the
	 obstack and use the existing table entry.  */
      obstack_free (&expr_obstack, cur_expr);
      cur_expr = *slot;
    }

  /* Search for another occurrence in the same basic block.  We insert
     insns blockwise from start to end, so keep appending to the
     start of the list so we have to check only a single element.  */
  avail_occr = cur_expr->avail_occr;
  if (avail_occr
      && BLOCK_FOR_INSN (avail_occr->insn) == BLOCK_FOR_INSN (insn))
    avail_occr->insn = insn;
  else
    {
      /* First occurrence of this expression in this basic block.  */
      avail_occr = (struct occr *) obstack_alloc (&occr_obstack,
						  sizeof (struct occr));
      avail_occr->insn = insn;
      avail_occr->next = cur_expr->avail_occr;
      avail_occr->deleted_p = 0;
      cur_expr->avail_occr = avail_occr;
    }
}


/* Lookup pattern PAT in the expression hash table.
   The result is a pointer to the table entry, or NULL if not found.  */

static struct expr *
lookup_expr_in_table (rtx pat)
{
  int do_not_record_p;
  struct expr **slot, *tmp_expr;
  hashval_t hash = hash_expr (pat, &do_not_record_p);

  if (do_not_record_p)
    return NULL;

  tmp_expr = (struct expr *) obstack_alloc (&expr_obstack,
					    sizeof (struct expr));
  tmp_expr->expr = pat;
  tmp_expr->hash = hash;
  tmp_expr->avail_occr = NULL;

  slot = expr_table->find_slot_with_hash (tmp_expr, hash, NO_INSERT);
  obstack_free (&expr_obstack, tmp_expr);

  if (!slot)
    return NULL;
  else
    return (*slot);
}


/* Dump all expressions and occurrences that are currently in the
   expression hash table to FILE.  */

/* This helper is called via htab_traverse.  */
int
dump_expr_hash_table_entry (expr **slot, FILE *file)
{
  struct expr *exprs = *slot;
  struct occr *occr;

  fprintf (file, "expr: ");
  print_rtl (file, exprs->expr);
  fprintf (file,"\nhashcode: %u\n", exprs->hash);
  fprintf (file,"list of occurrences:\n");
  occr = exprs->avail_occr;
  while (occr)
    {
      rtx_insn *insn = occr->insn;
      print_rtl_single (file, insn);
      fprintf (file, "\n");
      occr = occr->next;
    }
  fprintf (file, "\n");
  return 1;
}

static void
dump_hash_table (FILE *file)
{
  fprintf (file, "\n\nexpression hash table\n");
  fprintf (file, "size " HOST_SIZE_T_PRINT_DEC ", " HOST_SIZE_T_PRINT_DEC
	   " elements, %f collision/search ratio\n",
           (fmt_size_t) expr_table->size (),
           (fmt_size_t) expr_table->elements (),
           expr_table->collisions ());
  if (!expr_table->is_empty ())
    {
      fprintf (file, "\n\ntable entries:\n");
      expr_table->traverse <FILE *, dump_expr_hash_table_entry> (file);
    }
  fprintf (file, "\n");
}

/* Return true if register X is recorded as being set by an instruction
   whose CUID is greater than the one given.  */

static bool
reg_changed_after_insn_p (rtx x, int cuid)
{
  unsigned int regno, end_regno;

  regno = REGNO (x);
  end_regno = END_REGNO (x);
  do
    if (reg_avail_info[regno] > cuid)
      return true;
  while (++regno < end_regno);
  return false;
}

/* Return nonzero if the operands of expression X are unchanged
   1) from the start of INSN's basic block up to but not including INSN
      if AFTER_INSN is false, or
   2) from INSN to the end of INSN's basic block if AFTER_INSN is true.  */

static bool
oprs_unchanged_p (rtx x, rtx_insn *insn, bool after_insn)
{
  int i, j;
  enum rtx_code code;
  const char *fmt;

  if (x == 0)
    return true;

  code = GET_CODE (x);
  switch (code)
    {
    case REG:
      /* We are called after register allocation.  */
      gcc_assert (REGNO (x) < FIRST_PSEUDO_REGISTER);
      if (after_insn)
	return !reg_changed_after_insn_p (x, INSN_CUID (insn) - 1);
      else
	return !reg_changed_after_insn_p (x, 0);

    case MEM:
      if (load_killed_in_block_p (INSN_CUID (insn), x, after_insn))
	return false;
      else
	return oprs_unchanged_p (XEXP (x, 0), insn, after_insn);

    case PC:
    case CONST:
    CASE_CONST_ANY:
    case SYMBOL_REF:
    case LABEL_REF:
    case ADDR_VEC:
    case ADDR_DIFF_VEC:
      return true;

    case PRE_DEC:
    case PRE_INC:
    case POST_DEC:
    case POST_INC:
    case PRE_MODIFY:
    case POST_MODIFY:
      if (after_insn)
	return false;
      break;

    default:
      break;
    }

  for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
    {
      if (fmt[i] == 'e')
	{
	  if (! oprs_unchanged_p (XEXP (x, i), insn, after_insn))
	    return false;
	}
      else if (fmt[i] == 'E')
	for (j = 0; j < XVECLEN (x, i); j++)
	  if (! oprs_unchanged_p (XVECEXP (x, i, j), insn, after_insn))
	    return false;
    }

  return true;
}


/* Used for communication between find_mem_conflicts and
   load_killed_in_block_p.  Nonzero if find_mem_conflicts finds a
   conflict between two memory references.
   This is a bit of a hack to work around the limitations of note_stores.  */
static int mems_conflict_p;

/* DEST is the output of an instruction.  If it is a memory reference, and
   possibly conflicts with the load found in DATA, then set mems_conflict_p
   to a nonzero value.  */

static void
find_mem_conflicts (rtx dest, const_rtx setter ATTRIBUTE_UNUSED,
		    void *data)
{
  rtx mem_op = (rtx) data;

  while (GET_CODE (dest) == SUBREG
	 || GET_CODE (dest) == ZERO_EXTRACT
	 || GET_CODE (dest) == STRICT_LOW_PART)
    dest = XEXP (dest, 0);

  /* If DEST is not a MEM, then it will not conflict with the load.  Note
     that function calls are assumed to clobber memory, but are handled
     elsewhere.  */
  if (! MEM_P (dest))
    return;

  if (true_dependence (dest, GET_MODE (dest), mem_op))
    mems_conflict_p = 1;
}


/* Return nonzero if the expression in X (a memory reference) is killed
   in the current basic block before (if AFTER_INSN is false) or after
   (if AFTER_INSN is true) the insn with the CUID in UID_LIMIT.

   This function assumes that the modifies_mem table is flushed when
   the hash table construction or redundancy elimination phases start
   processing a new basic block.  */

static bool
load_killed_in_block_p (int uid_limit, rtx x, bool after_insn)
{
  struct modifies_mem *list_entry = modifies_mem_list;

  while (list_entry)
    {
      rtx_insn *setter = list_entry->insn;

      /* Ignore entries in the list that do not apply.  */
      if ((after_insn
	   && INSN_CUID (setter) < uid_limit)
	  || (! after_insn
	      && INSN_CUID (setter) > uid_limit))
	{
	  list_entry = list_entry->next;
	  continue;
	}

      /* If SETTER is a call everything is clobbered.  Note that calls
	 to pure functions are never put on the list, so we need not
	 worry about them.  */
      if (CALL_P (setter))
	return true;

      /* SETTER must be an insn of some kind that sets memory.  Call
	 note_stores to examine each hunk of memory that is modified.
	 It will set mems_conflict_p to nonzero if there may be a
	 conflict between X and SETTER.  */
      mems_conflict_p = 0;
      note_stores (setter, find_mem_conflicts, x);
      if (mems_conflict_p)
	return true;

      list_entry = list_entry->next;
    }
  return false;
}


/* Record register first/last/block set information for REGNO in INSN.  */

static inline void
record_last_reg_set_info (rtx_insn *insn, rtx reg)
{
  unsigned int regno, end_regno;

  regno = REGNO (reg);
  end_regno = END_REGNO (reg);
  do
    reg_avail_info[regno] = INSN_CUID (insn);
  while (++regno < end_regno);
}

static inline void
record_last_reg_set_info_regno (rtx_insn *insn, int regno)
{
  reg_avail_info[regno] = INSN_CUID (insn);
}


/* Record memory modification information for INSN.  We do not actually care
   about the memory location(s) that are set, or even how they are set (consider
   a CALL_INSN).  We merely need to record which insns modify memory.  */

static void
record_last_mem_set_info (rtx_insn *insn)
{
  struct modifies_mem *list_entry;

  list_entry = (struct modifies_mem *) obstack_alloc (&modifies_mem_obstack,
						      sizeof (struct modifies_mem));
  list_entry->insn = insn;
  list_entry->next = modifies_mem_list;
  modifies_mem_list = list_entry;

  record_last_mem_set_info_common (insn, modify_mem_list,
				   canon_modify_mem_list,
				   modify_mem_list_set,
				   blocks_with_calls);
}

/* Called from compute_hash_table via note_stores to handle one
   SET or CLOBBER in an insn.  DATA is really the instruction in which
   the SET is taking place.  */

static void
record_last_set_info (rtx dest, const_rtx setter ATTRIBUTE_UNUSED, void *data)
{
  rtx_insn *last_set_insn = (rtx_insn *) data;

  if (GET_CODE (dest) == SUBREG)
    dest = SUBREG_REG (dest);

  if (REG_P (dest))
    record_last_reg_set_info (last_set_insn, dest);
  else if (MEM_P (dest))
    {
      /* Ignore pushes, they don't clobber memory.  They may still
	 clobber the stack pointer though.  Some targets do argument
	 pushes without adding REG_INC notes.  See e.g. PR25196,
	 where a pushsi2 on i386 doesn't have REG_INC notes.  Note
	 such changes here too.  */
      if (! push_operand (dest, GET_MODE (dest)))
	record_last_mem_set_info (last_set_insn);
      else
	record_last_reg_set_info_regno (last_set_insn, STACK_POINTER_REGNUM);
    }
}


/* Reset tables used to keep track of what's still available since the
   start of the block.  */

static void
reset_opr_set_tables (void)
{
  memset (reg_avail_info, 0, FIRST_PSEUDO_REGISTER * sizeof (int));
  obstack_free (&modifies_mem_obstack, modifies_mem_obstack_bottom);
  modifies_mem_list = NULL;
}


/* Record things set by INSN.
   This data is used by oprs_unchanged_p.  */

static void
record_opr_changes (rtx_insn *insn)
{
  rtx note;

  /* Find all stores and record them.  */
  note_stores (insn, record_last_set_info, insn);

  /* Also record autoincremented REGs for this insn as changed.  */
  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    if (REG_NOTE_KIND (note) == REG_INC)
      record_last_reg_set_info (insn, XEXP (note, 0));

  /* Finally, if this is a call, record all call clobbers.  */
  if (CALL_P (insn))
    {
      unsigned int regno;
      hard_reg_set_iterator hrsi;
      /* We don't track modes of hard registers, so we need to be
	 conservative and assume that partial kills are full kills.  */
      HARD_REG_SET callee_clobbers
	= insn_callee_abi (insn).full_and_partial_reg_clobbers ();
      EXECUTE_IF_SET_IN_HARD_REG_SET (callee_clobbers, 0, regno, hrsi)
	record_last_reg_set_info_regno (insn, regno);

      if (! RTL_CONST_OR_PURE_CALL_P (insn)
	  || RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
	  || can_throw_external (insn))
	record_last_mem_set_info (insn);
    }
}


/* Scan the pattern of INSN and add an entry to the hash TABLE.
   After reload we are interested in loads/stores only.  */

static void
hash_scan_set (rtx_insn *insn)
{
  rtx pat = PATTERN (insn);
  rtx src = SET_SRC (pat);
  rtx dest = SET_DEST (pat);

  /* We are only interested in loads and stores.  */
  if (! MEM_P (src) && ! MEM_P (dest))
    return;

  /* Don't mess with jumps and nops.  */
  if (JUMP_P (insn) || set_noop_p (pat))
    return;

  if (REG_P (dest))
    {
      if (/* Don't CSE something if we can't do a reg/reg copy.  */
	  can_copy_p (GET_MODE (dest))
	  /* Is SET_SRC something we want to gcse?  */
	  && general_operand (src, GET_MODE (src))
#ifdef STACK_REGS
	  /* Never consider insns touching the register stack.  It may
	     create situations that reg-stack cannot handle (e.g. a stack
	     register live across an abnormal edge).  */
	  && (REGNO (dest) < FIRST_STACK_REG || REGNO (dest) > LAST_STACK_REG)
#endif
	  /* An expression is not available if its operands are
	     subsequently modified, including this insn.  */
	  && oprs_unchanged_p (src, insn, true))
	{
	  insert_expr_in_table (src, insn);
	}
    }
  else if (REG_P (src))
    {
      /* Only record sets of pseudo-regs in the hash table.  */
      if (/* Don't CSE something if we can't do a reg/reg copy.  */
	  can_copy_p (GET_MODE (src))
	  /* Is SET_DEST something we want to gcse?  */
	  && general_operand (dest, GET_MODE (dest))
#ifdef STACK_REGS
	  /* As above for STACK_REGS.  */
	  && (REGNO (src) < FIRST_STACK_REG || REGNO (src) > LAST_STACK_REG)
#endif
	  && ! (flag_float_store && FLOAT_MODE_P (GET_MODE (dest)))
	  /* Check if the memory expression is killed after insn.  */
	  && ! load_killed_in_block_p (INSN_CUID (insn) + 1, dest, true)
	  && oprs_unchanged_p (XEXP (dest, 0), insn, true))
	{
	  insert_expr_in_table (dest, insn);
	}
    }
}


/* Create hash table of memory expressions available at end of basic
   blocks.  Basically you should think of this hash table as the
   representation of AVAIL_OUT.  This is the set of expressions that
   is generated in a basic block and not killed before the end of the
   same basic block.  Notice that this is really a local computation.  */

static void
compute_hash_table (void)
{
  basic_block bb;

  FOR_EACH_BB_FN (bb, cfun)
    {
      rtx_insn *insn;

      /* First pass over the instructions records information used to
	 determine when registers and memory are last set.
	 Since we compute a "local" AVAIL_OUT, reset the tables that
	 help us keep track of what has been modified since the start
	 of the block.  */
      reset_opr_set_tables ();
      FOR_BB_INSNS (bb, insn)
	{
	  if (INSN_P (insn))
            record_opr_changes (insn);
	}

      /* The next pass actually builds the hash table.  */
      FOR_BB_INSNS (bb, insn)
	if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == SET)
	  hash_scan_set (insn);
    }
}


/* Check if register REG is killed in any insn waiting to be inserted on
   edge E.  This function is required to check that our data flow analysis
   is still valid prior to commit_edge_insertions.  */

static bool
reg_killed_on_edge (rtx reg, edge e)
{
  rtx_insn *insn;

  for (insn = e->insns.r; insn; insn = NEXT_INSN (insn))
    if (INSN_P (insn) && reg_set_p (reg, insn))
      return true;

  return false;
}

/* Similar to above - check if register REG is used in any insn waiting
   to be inserted on edge E.
   Assumes no such insn can be a CALL_INSN; if so call reg_used_between_p
   with PREV(insn),NEXT(insn) instead of calling reg_overlap_mentioned_p.  */

static bool
reg_used_on_edge (rtx reg, edge e)
{
  rtx_insn *insn;

  for (insn = e->insns.r; insn; insn = NEXT_INSN (insn))
    if (INSN_P (insn) && reg_overlap_mentioned_p (reg, PATTERN (insn)))
      return true;

  return false;
}

/* Return the loaded/stored register of a load/store instruction.  */

static rtx
get_avail_load_store_reg (rtx_insn *insn)
{
  if (REG_P (SET_DEST (PATTERN (insn))))
    /* A load.  */
    return SET_DEST (PATTERN (insn));
  else
    {
      /* A store.  */
      gcc_assert (REG_P (SET_SRC (PATTERN (insn))));
      return SET_SRC (PATTERN (insn));
    }
}

/* Return true if the predecessors of BB are "well behaved".  */

static bool
bb_has_well_behaved_predecessors (basic_block bb)
{
  edge pred;
  edge_iterator ei;

  if (EDGE_COUNT (bb->preds) == 0)
    return false;

  FOR_EACH_EDGE (pred, ei, bb->preds)
    {
      /* commit_one_edge_insertion refuses to insert on abnormal edges even if
	 the source has only one successor so EDGE_CRITICAL_P is too weak.  */
      if ((pred->flags & EDGE_ABNORMAL) && !single_pred_p (pred->dest))
	return false;

      if ((pred->flags & EDGE_ABNORMAL_CALL) && cfun->has_nonlocal_label)
	return false;

      if (tablejump_p (BB_END (pred->src), NULL, NULL))
	return false;
    }
  return true;
}


/* Search for the occurrences of expression in BB.  */

static struct occr*
get_bb_avail_insn (basic_block bb, struct occr *orig_occr, int bitmap_index)
{
  struct occr *occr = orig_occr;

  for (; occr != NULL; occr = occr->next)
    if (BLOCK_FOR_INSN (occr->insn) == bb)
      return occr;

  /* If we could not find an occurrence in BB, see if BB
     has a single predecessor with an occurrence that is
     transparent through BB.  */
  if (transp
      && single_pred_p (bb)
      && bitmap_bit_p (transp[bb->index], bitmap_index)
      && (occr = get_bb_avail_insn (single_pred (bb), orig_occr, bitmap_index)))
    {
      rtx avail_reg = get_avail_load_store_reg (occr->insn);
      if (!reg_set_between_p (avail_reg,
			      PREV_INSN (BB_HEAD (bb)),
			      NEXT_INSN (BB_END (bb)))
	  && !reg_killed_on_edge (avail_reg, single_pred_edge (bb)))
	return occr;
    }

  return NULL;
}


/* This helper is called via htab_traverse.  */
int
compute_expr_transp (expr **slot, FILE *dump_file ATTRIBUTE_UNUSED)
{
  struct expr *expr = *slot;

  compute_transp (expr->expr, expr->bitmap_index, transp,
		  blocks_with_calls, modify_mem_list_set,
		  canon_modify_mem_list);
  return 1;
}

/* This handles the case where several stores feed a partially redundant
   load. It checks if the redundancy elimination is possible and if it's
   worth it.

   Redundancy elimination is possible if,
   1) None of the operands of an insn have been modified since the start
      of the current basic block.
   2) In any predecessor of the current basic block, the same expression
      is generated.

   See the function body for the heuristics that determine if eliminating
   a redundancy is also worth doing, assuming it is possible.  */

static void
eliminate_partially_redundant_load (basic_block bb, rtx_insn *insn,
				    struct expr *expr)
{
  edge pred;
  rtx_insn *avail_insn = NULL;
  rtx avail_reg;
  rtx dest, pat;
  struct occr *a_occr;
  struct unoccr *occr, *avail_occrs = NULL;
  struct unoccr *unoccr, *unavail_occrs = NULL, *rollback_unoccr = NULL;
  int npred_ok = 0;
  profile_count ok_count = profile_count::zero ();
		 /* Redundant load execution count.  */
  profile_count critical_count = profile_count::zero ();
		 /* Execution count of critical edges.  */
  edge_iterator ei;
  bool critical_edge_split = false;

  /* The execution count of the loads to be added to make the
     load fully redundant.  */
  profile_count not_ok_count = profile_count::zero ();
  basic_block pred_bb;

  pat = PATTERN (insn);
  dest = SET_DEST (pat);

  /* Check that the loaded register is not used, set, or killed from the
     beginning of the block.  */
  if (reg_changed_after_insn_p (dest, 0)
      || reg_used_between_p (dest, PREV_INSN (BB_HEAD (bb)), insn))
    return;

  /* Check potential for replacing load with copy for predecessors.  */
  FOR_EACH_EDGE (pred, ei, bb->preds)
    {
      rtx_insn *next_pred_bb_end;

      avail_insn = NULL;
      avail_reg = NULL_RTX;
      pred_bb = pred->src;
      for (a_occr = get_bb_avail_insn (pred_bb,
				       expr->avail_occr,
				       expr->bitmap_index);
	   a_occr;
	   a_occr = get_bb_avail_insn (pred_bb,
				       a_occr->next,
				       expr->bitmap_index))
	{
	  /* Check if the loaded register is not used.  */
	  avail_insn = a_occr->insn;
	  avail_reg = get_avail_load_store_reg (avail_insn);
	  gcc_assert (avail_reg);

	  /* Make sure we can generate a move from register avail_reg to
	     dest.  */
	  rtx_insn *move = gen_move_insn (copy_rtx (dest),
					  copy_rtx (avail_reg));
	  extract_insn (move);
	  if (! constrain_operands (1, get_preferred_alternatives (insn,
								   pred_bb))
	      || reg_killed_on_edge (avail_reg, pred)
	      || reg_used_on_edge (dest, pred))
	    {
	      avail_insn = NULL;
	      continue;
	    }
	  next_pred_bb_end = NEXT_INSN (BB_END (BLOCK_FOR_INSN (avail_insn)));
	  if (!reg_set_between_p (avail_reg, avail_insn, next_pred_bb_end))
	    /* AVAIL_INSN remains non-null.  */
	    break;
	  else
	    avail_insn = NULL;
	}

      if (EDGE_CRITICAL_P (pred) && pred->count ().initialized_p ())
	critical_count += pred->count ();

      if (avail_insn != NULL_RTX)
	{
	  npred_ok++;
	  if (pred->count ().initialized_p ())
	    ok_count = ok_count + pred->count ();
	  if (! set_noop_p (PATTERN (gen_move_insn (copy_rtx (dest),
						    copy_rtx (avail_reg)))))
	    {
	      /* Check if there is going to be a split.  */
	      if (EDGE_CRITICAL_P (pred))
		critical_edge_split = true;
	    }
	  else /* Its a dead move no need to generate.  */
	    continue;
	  occr = (struct unoccr *) obstack_alloc (&unoccr_obstack,
						  sizeof (struct unoccr));
	  occr->insn = avail_insn;
	  occr->pred = pred;
	  occr->next = avail_occrs;
	  avail_occrs = occr;
	  if (! rollback_unoccr)
	    rollback_unoccr = occr;
	}
      else
	{
	  /* Adding a load on a critical edge will cause a split.  */
	  if (EDGE_CRITICAL_P (pred))
	    critical_edge_split = true;
	  if (pred->count ().initialized_p ())
	    not_ok_count = not_ok_count + pred->count ();
	  unoccr = (struct unoccr *) obstack_alloc (&unoccr_obstack,
						    sizeof (struct unoccr));
	  unoccr->insn = NULL;
	  unoccr->pred = pred;
	  unoccr->next = unavail_occrs;
	  unavail_occrs = unoccr;
	  if (! rollback_unoccr)
	    rollback_unoccr = unoccr;
	}
    }

  if (/* No load can be replaced by copy.  */
      npred_ok == 0
      /* Prevent exploding the code.  */
      || (optimize_bb_for_size_p (bb) && npred_ok > 1)
      /* If we don't have profile information we cannot tell if splitting
         a critical edge is profitable or not so don't do it.  */
      || ((!profile_info || profile_status_for_fn (cfun) != PROFILE_READ
	   || targetm.cannot_modify_jumps_p ())
	  && critical_edge_split))
    goto cleanup;

  /* Check if it's worth applying the partial redundancy elimination.  */
  if (ok_count.to_gcov_type ()
      < param_gcse_after_reload_partial_fraction * not_ok_count.to_gcov_type ())
    goto cleanup;

  gcov_type threshold;
#if (GCC_VERSION >= 5000)
  if (__builtin_mul_overflow (param_gcse_after_reload_critical_fraction,
			      critical_count.to_gcov_type (), &threshold))
    threshold = profile_count::max_count;
#else
  threshold
    = (param_gcse_after_reload_critical_fraction
       * critical_count.to_gcov_type ());
#endif

  if (ok_count.to_gcov_type () < threshold)
    goto cleanup;

  /* Generate moves to the loaded register from where
     the memory is available.  */
  for (occr = avail_occrs; occr; occr = occr->next)
    {
      avail_insn = occr->insn;
      pred = occr->pred;
      /* Set avail_reg to be the register having the value of the
	 memory.  */
      avail_reg = get_avail_load_store_reg (avail_insn);
      gcc_assert (avail_reg);

      insert_insn_on_edge (gen_move_insn (copy_rtx (dest),
					  copy_rtx (avail_reg)),
			   pred);
      stats.moves_inserted++;

      if (dump_file)
	fprintf (dump_file,
		 "generating move from %d to %d on edge from %d to %d\n",
		 REGNO (avail_reg),
		 REGNO (dest),
		 pred->src->index,
		 pred->dest->index);
    }

  /* Regenerate loads where the memory is unavailable.  */
  for (unoccr = unavail_occrs; unoccr; unoccr = unoccr->next)
    {
      pred = unoccr->pred;
      insert_insn_on_edge (copy_insn (PATTERN (insn)), pred);
      stats.copies_inserted++;

      if (dump_file)
	{
	  fprintf (dump_file,
		   "generating on edge from %d to %d a copy of load: ",
		   pred->src->index,
		   pred->dest->index);
	  print_rtl (dump_file, PATTERN (insn));
	  fprintf (dump_file, "\n");
	}
    }

  /* Delete the insn if it is not available in this block and mark it
     for deletion if it is available. If insn is available it may help
     discover additional redundancies, so mark it for later deletion.  */
  for (a_occr = get_bb_avail_insn (bb, expr->avail_occr, expr->bitmap_index);
       a_occr && (a_occr->insn != insn);
       a_occr = get_bb_avail_insn (bb, a_occr->next, expr->bitmap_index))
    ;

  if (!a_occr)
    {
      stats.insns_deleted++;

      if (dump_file)
	{
	  fprintf (dump_file, "deleting insn:\n");
          print_rtl_single (dump_file, insn);
          fprintf (dump_file, "\n");
	}
      delete_insn (insn);
    }
  else
    a_occr->deleted_p = 1;

cleanup:
  if (rollback_unoccr)
    obstack_free (&unoccr_obstack, rollback_unoccr);
}

/* Performing the redundancy elimination as described before.  */

static void
eliminate_partially_redundant_loads (void)
{
  rtx_insn *insn;
  basic_block bb;

  /* Note we start at block 1.  */

  if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
    return;

  FOR_BB_BETWEEN (bb,
		  ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb->next_bb,
		  EXIT_BLOCK_PTR_FOR_FN (cfun),
		  next_bb)
    {
      /* Don't try anything on basic blocks with strange predecessors.  */
      if (! bb_has_well_behaved_predecessors (bb))
	continue;

      /* Do not try anything on cold basic blocks.  */
      if (optimize_bb_for_size_p (bb))
	continue;

      /* Reset the table of things changed since the start of the current
	 basic block.  */
      reset_opr_set_tables ();

      /* Look at all insns in the current basic block and see if there are
	 any loads in it that we can record.  */
      FOR_BB_INSNS (bb, insn)
	{
	  /* Is it a load - of the form (set (reg) (mem))?  */
	  if (NONJUMP_INSN_P (insn)
              && GET_CODE (PATTERN (insn)) == SET
	      && REG_P (SET_DEST (PATTERN (insn)))
	      && MEM_P (SET_SRC (PATTERN (insn))))
	    {
	      rtx pat = PATTERN (insn);
	      rtx src = SET_SRC (pat);
	      struct expr *expr;

	      if (!MEM_VOLATILE_P (src)
		  && GET_MODE (src) != BLKmode
		  && general_operand (src, GET_MODE (src))
		  /* Are the operands unchanged since the start of the
		     block?  */
		  && oprs_unchanged_p (src, insn, false)
		  && !(cfun->can_throw_non_call_exceptions && may_trap_p (src))
		  && !side_effects_p (src)
		  /* Is the expression recorded?  */
		  && (expr = lookup_expr_in_table (src)) != NULL)
		{
		  /* We now have a load (insn) and an available memory at
		     its BB start (expr). Try to remove the loads if it is
		     redundant.  */
		  eliminate_partially_redundant_load (bb, insn, expr);
		}
	    }

	  /* Keep track of everything modified by this insn, so that we
	     know what has been modified since the start of the current
	     basic block.  */
	  if (INSN_P (insn))
	    record_opr_changes (insn);
	}
    }

  commit_edge_insertions ();
}

/* Go over the expression hash table and delete insns that were
   marked for later deletion.  */

/* This helper is called via htab_traverse.  */
int
delete_redundant_insns_1 (expr **slot, void *data ATTRIBUTE_UNUSED)
{
  struct expr *exprs = *slot;
  struct occr *occr;

  for (occr = exprs->avail_occr; occr != NULL; occr = occr->next)
    {
      if (occr->deleted_p && dbg_cnt (gcse2_delete))
	{
	  delete_insn (occr->insn);
	  stats.insns_deleted++;

	  if (dump_file)
	    {
	      fprintf (dump_file, "deleting insn:\n");
	      print_rtl_single (dump_file, occr->insn);
	      fprintf (dump_file, "\n");
	    }
	}
    }

  return 1;
}

static void
delete_redundant_insns (void)
{
  expr_table->traverse <void *, delete_redundant_insns_1> (NULL);
  if (dump_file)
    fprintf (dump_file, "\n");
}

/* Main entry point of the GCSE after reload - clean some redundant loads
   due to spilling.  */

static void
gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED)
{
  /* Disable computing transparentness if it is too expensive.  */
  bool do_transp
    = !gcse_or_cprop_is_too_expensive (_("using simple load CSE after register "
					 "allocation"));

  memset (&stats, 0, sizeof (stats));

  /* Allocate memory for this pass.
     Also computes and initializes the insns' CUIDs.  */
  alloc_mem ();

  /* We need alias analysis.  */
  init_alias_analysis ();

  compute_hash_table ();

  if (dump_file)
    dump_hash_table (dump_file);

  if (!expr_table->is_empty ())
    {
      /* Knowing which MEMs are transparent through a block can signifiantly
	 increase the number of redundant loads found.  So compute transparency
	 information for each memory expression in the hash table.  */
      df_analyze ();
      if (do_transp)
	{
	  /* This cannot be part of the normal allocation routine because
	     we have to know the number of elements in the hash table.  */
	  transp = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
					 expr_table->elements ());
	  bitmap_vector_ones (transp, last_basic_block_for_fn (cfun));
	  expr_table->traverse <FILE *, compute_expr_transp> (dump_file);
	}
      else
	transp = NULL;
      eliminate_partially_redundant_loads ();
      delete_redundant_insns ();
      if (do_transp)
	sbitmap_vector_free (transp);

      if (dump_file)
	{
	  fprintf (dump_file, "GCSE AFTER RELOAD stats:\n");
	  fprintf (dump_file, "copies inserted: %d\n", stats.copies_inserted);
	  fprintf (dump_file, "moves inserted:  %d\n", stats.moves_inserted);
	  fprintf (dump_file, "insns deleted:   %d\n", stats.insns_deleted);
	  fprintf (dump_file, "\n\n");
	}

      statistics_counter_event (cfun, "copies inserted",
				stats.copies_inserted);
      statistics_counter_event (cfun, "moves inserted",
				stats.moves_inserted);
      statistics_counter_event (cfun, "insns deleted",
				stats.insns_deleted);
    }

  /* We are finished with alias.  */
  end_alias_analysis ();

  free_mem ();
}



static void
rest_of_handle_gcse2 (void)
{
  gcse_after_reload_main (get_insns ());
  rebuild_jump_labels (get_insns ());
}

namespace {

const pass_data pass_data_gcse2 =
{
  RTL_PASS, /* type */
  "gcse2", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_GCSE_AFTER_RELOAD, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_gcse2 : public rtl_opt_pass
{
public:
  pass_gcse2 (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_gcse2, ctxt)
  {}

  /* opt_pass methods: */
  bool gate (function *fun) final override
    {
      return (optimize > 0 && flag_gcse_after_reload
	      && optimize_function_for_speed_p (fun));
    }

  unsigned int execute (function *) final override
  {
    rest_of_handle_gcse2 ();
    return 0;
  }

}; // class pass_gcse2

} // anon namespace

rtl_opt_pass *
make_pass_gcse2 (gcc::context *ctxt)
{
  return new pass_gcse2 (ctxt);
}
