/* Post reload partially redundant load elimination
   Copyright (C) 2004, 2005
   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 2, 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 COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "toplev.h"

#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "flags.h"
#include "real.h"
#include "insn-config.h"
#include "recog.h"
#include "basic-block.h"
#include "output.h"
#include "function.h"
#include "expr.h"
#include "except.h"
#include "intl.h"
#include "obstack.h"
#include "hashtab.h"
#include "params.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.  */

/* The table itself.  */
static htab_t expr_table;

/* 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;

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

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;
  /* 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;
};

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;
  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)])


/* 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, bool);
static void record_last_reg_set_info (rtx, int);
static void record_last_mem_set_info (rtx);
static void record_last_set_info (rtx, rtx, void *);
static void record_opr_changes (rtx);

static void find_mem_conflicts (rtx, rtx, void *);
static int 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 hashval_t hash_expr_for_htab (const void *);
static int expr_equiv_p (const void *, const void *);
static void insert_expr_in_table (rtx, rtx);
static struct expr *lookup_expr_in_table (rtx);
static int dump_hash_table_entry (void **, void *);
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 reg_set_between_after_reload_p (rtx, rtx, rtx);
static rtx reg_used_between_after_reload_p (rtx, rtx, rtx);
static rtx get_avail_load_store_reg (rtx);

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

/* The work horses of this pass.  */
static void eliminate_partially_redundant_load (basic_block,
						rtx,
						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;

  /* Find the largest UID and create a mapping from UIDs to CUIDs.  */
  uid_cuid = xcalloc (get_max_uid () + 1, sizeof (int));
  /* APPLE LOCAL 412984 mainline */
  i = 1;
  FOR_EACH_BB (bb)
    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.c relic, and seems like a
     reasonable choice.  */
  expr_table = htab_create (MAX (i / 4, 13),
			    hash_expr_for_htab, expr_equiv_p, NULL);

  /* 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));
}

/* Free memory allocated by alloc_mem.  */

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

  htab_delete (expr_table);

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

  free (reg_avail_info);
}


/* 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.  */

static hashval_t
hash_expr_for_htab (const void *expp)
{
  struct expr *exp = (struct expr *) expp;
  return exp->hash;
}

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

static int
expr_equiv_p (const void *exp1p, const void *exp2p)
{
  struct expr *exp1 = (struct expr *) exp1p;
  struct expr *exp2 = (struct expr *) exp2p;
  int equiv_p = exp_equiv_p (exp1->expr, exp2->expr, 0, true);
  if (equiv_p
      && exp1->hash != exp2->hash)
    abort ();
  return equiv_p;
}


/* 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)
{
  int do_not_record_p;
  hashval_t hash;
  struct expr *cur_expr, **slot;
  struct occr *avail_occr, *last_occr = NULL;

  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 = (struct expr **) htab_find_slot_with_hash (expr_table, cur_expr,
						    hash, INSERT);
  
  if (! (*slot))
    /* The expression isn't found, so insert it.  */
    *slot = cur_expr;
  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.  */
  avail_occr = cur_expr->avail_occr;
  while (avail_occr && BLOCK_NUM (avail_occr->insn) != BLOCK_NUM (insn))
    {
      /* If an occurrence isn't found, save a pointer to the end of
	 the list.  */
      last_occr = avail_occr;
      avail_occr = avail_occr->next;
    }

  if (avail_occr)
    /* Found another instance of the expression in the same basic block.
       Prefer this occurrence to the currently recorded one.  We want
       the last one in the block and the block is scanned from start
       to end.  */
    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));

      /* First occurrence of this expression in any block?  */
      if (cur_expr->avail_occr == NULL)
        cur_expr->avail_occr = avail_occr;
      else
        last_occr->next = avail_occr;

      avail_occr->insn = insn;
      avail_occr->next = NULL;
      avail_occr->deleted_p = 0;
    }
}


/* 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 = (struct expr **) htab_find_slot_with_hash (expr_table, tmp_expr,
                                                    hash, 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.  */
static int
dump_hash_table_entry (void **slot, void *filep)
{
  struct expr *expr = (struct expr *) *slot;
  FILE *file = (FILE *) filep;
  struct occr *occr;

  fprintf (file, "expr: ");
  print_rtl (file, expr->expr);
  fprintf (file,"\nhashcode: %u\n", expr->hash);
  fprintf (file,"list of occurences:\n");
  occr = expr->avail_occr;
  while (occr)
    {
      rtx 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 %ld, %ld elements, %f collision/search ratio\n",
           (long) htab_size (expr_table),
           (long) htab_elements (expr_table),
           htab_collisions (expr_table));
  if (htab_elements (expr_table) > 0)
    {
      fprintf (file, "\n\ntable entries:\n");
      htab_traverse (expr_table, dump_hash_table_entry, file);
    }
  fprintf (file, "\n");
}


/* 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, bool after_insn)
{
  int i, j;
  enum rtx_code code;
  const char *fmt;

  if (x == 0)
    return 1;

  code = GET_CODE (x);
  switch (code)
    {
    case REG:
#ifdef ENABLE_CHECKING
      /* We are called after register allocation.  */
      if (REGNO (x) >= FIRST_PSEUDO_REGISTER)
	abort ();
#endif
      if (after_insn)
	/* If the last CUID setting the insn is less than the CUID of
	   INSN, then reg X is not changed in or after INSN.  */
	return reg_avail_info[REGNO (x)] < INSN_CUID (insn);
      else
	/* Reg X is not set before INSN in the current basic block if
	   we have not yet recorded the CUID of an insn that touches
	   the reg.  */
	return reg_avail_info[REGNO (x)] == 0;

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

    case PC:
    case CC0: /*FIXME*/
    case CONST:
    case CONST_INT:
    case CONST_DOUBLE:
    case CONST_VECTOR:
    case SYMBOL_REF:
    case LABEL_REF:
    case ADDR_VEC:
    case ADDR_DIFF_VEC:
      return 1;

    case PRE_DEC:
    case PRE_INC:
    case POST_DEC:
    case POST_INC:
    case PRE_MODIFY:
    case POST_MODIFY:
      if (after_insn)
	return 0;
      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 0;
	}
      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 0;
    }

  return 1;
}


/* 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, 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,
		       rtx_addr_varies_p))
    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 int
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 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 1;

      /* 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 (PATTERN (setter), find_mem_conflicts, x);
      if (mems_conflict_p)
	return 1;

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

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

static inline void
record_last_reg_set_info (rtx 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)
{
  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;
}

/* 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, rtx setter ATTRIBUTE_UNUSED, void *data)
{
  rtx last_set_insn = (rtx) data;

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

  if (REG_P (dest))
    record_last_reg_set_info (last_set_insn, REGNO (dest));
  else if (MEM_P (dest)
	   /* Ignore pushes, they clobber nothing.  */
	   && ! push_operand (dest, GET_MODE (dest)))
    record_last_mem_set_info (last_set_insn);
}


/* 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)
{
  rtx note;

  /* Find all stores and record them.  */
  note_stores (PATTERN (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, REGNO (XEXP (note, 0)));

  /* Finally, if this is a call, record all call clobbers.  */
  if (CALL_P (insn))
    {
      unsigned int regno;

      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
	if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
	  record_last_reg_set_info (insn, regno);

      if (! CONST_OR_PURE_CALL_P (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)
{
  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;

#ifdef ENABLE_CHEKCING
  /* We shouldn't have any EH_REGION notes post reload.  */
  if (find_reg_note (insn, REG_EH_REGION, NULL_RTX))
    abort ();
#endif

  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))
	  /* 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))
	  && ! (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 (bb)
    {
      rtx 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;

  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;

  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 insn that sets register REG or clobbers it in between
   FROM_INSN and TO_INSN (exclusive of those two).
   Just like reg_set_between but for hard registers and not pseudos.  */

static rtx
reg_set_between_after_reload_p (rtx reg, rtx from_insn, rtx to_insn)
{
  rtx insn;

#ifdef ENABLE_CHECKING
  /* We are called after register allocation.  */
  if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
    abort ();
#endif

  if (from_insn == to_insn)
    return NULL_RTX;

  for (insn = NEXT_INSN (from_insn);
       insn != to_insn;
       insn = NEXT_INSN (insn))
    if (INSN_P (insn))
      {
	if (set_of (reg, insn) != NULL_RTX)
	  return insn;
	if ((CALL_P (insn)
	      && call_used_regs[REGNO (reg)])
	    || find_reg_fusage (insn, CLOBBER, reg))
	  return insn;

	if (FIND_REG_INC_NOTE (insn, reg))
	  return insn;
      }

  return NULL_RTX;
}

/* Return the insn that uses register REG in between FROM_INSN and TO_INSN
   (exclusive of those two). Similar to reg_used_between but for hard
   registers and not pseudos.  */

static rtx
reg_used_between_after_reload_p (rtx reg, rtx from_insn, rtx to_insn)
{
  rtx insn;

#ifdef ENABLE_CHECKING
  /* We are called after register allocation.  */
  if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
    abort ();
#endif

  if (from_insn == to_insn)
    return NULL_RTX;

  for (insn = NEXT_INSN (from_insn);
       insn != to_insn;
       insn = NEXT_INSN (insn))
    if (INSN_P (insn))
      {
	if (reg_overlap_mentioned_p (reg, PATTERN (insn))
	    || (CALL_P (insn)
		&& call_used_regs[REGNO (reg)])
	    || find_reg_fusage (insn, USE, reg)
	    || find_reg_fusage (insn, CLOBBER, reg))
	  return insn;

	if (FIND_REG_INC_NOTE (insn, reg))
	  return insn;
      }

  return NULL_RTX;
}

/* Return true if REG is used, set, or killed between the beginning of
   basic block BB and UP_TO_INSN.  Caches the result in reg_avail_info.  */

static bool
reg_set_or_used_since_bb_start (rtx reg, basic_block bb, rtx up_to_insn)
{
  rtx insn, start = PREV_INSN (BB_HEAD (bb));

  if (reg_avail_info[REGNO (reg)] != 0)
    return true;

  insn = reg_used_between_after_reload_p (reg, start, up_to_insn);
  if (! insn)
    insn = reg_set_between_after_reload_p (reg, start, up_to_insn);

  if (insn)
    reg_avail_info[REGNO (reg)] = INSN_CUID (insn);

  return insn != NULL_RTX;
}

/* Return the loaded/stored register of a load/store instruction.  */

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

/* Return nonzero 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)
    {
      if ((pred->flags & EDGE_ABNORMAL) && EDGE_CRITICAL_P (pred))
	return false;

      if (JUMP_TABLE_DATA_P (BB_END (pred->src)))
	return false;
    }
  return true;
}


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

static struct occr*
get_bb_avail_insn (basic_block bb, struct occr *occr)
{
  for (; occr != NULL; occr = occr->next)
    if (BLOCK_FOR_INSN (occr->insn) == bb)
      return occr;
  return NULL;
}


/* 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,
				    struct expr *expr)
{
  edge pred;
  rtx avail_insn = NULL_RTX;
  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;
  gcov_type ok_count = 0; /* Redundant load execution count.  */
  gcov_type critical_count = 0; /* Execution count of critical edges.  */
  edge_iterator ei;

  /* The execution count of the loads to be added to make the
     load fully redundant.  */
  gcov_type not_ok_count = 0;
  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_set_or_used_since_bb_start (dest, bb, insn))
    return;

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

      avail_insn = NULL_RTX;
      pred_bb = pred->src;
      next_pred_bb_end = NEXT_INSN (BB_END (pred_bb));
      for (a_occr = get_bb_avail_insn (pred_bb, expr->avail_occr); a_occr;
	   a_occr = get_bb_avail_insn (pred_bb, a_occr->next))
	{
	  /* Check if the loaded register is not used.  */
	  avail_insn = a_occr->insn;
	  if (! (avail_reg = get_avail_load_store_reg (avail_insn)))
	    abort ();
	  /* Make sure we can generate a move from register avail_reg to
	     dest.  */
	  extract_insn (gen_move_insn (copy_rtx (dest),
				       copy_rtx (avail_reg)));
	  if (! constrain_operands (1)
	      || reg_killed_on_edge (avail_reg, pred)
	      || reg_used_on_edge (dest, pred))
	    {
	      avail_insn = NULL;
	      continue;
	    }
	  if (! reg_set_between_after_reload_p (avail_reg, avail_insn,
						next_pred_bb_end))
	    /* AVAIL_INSN remains non-null.  */
	    break;
	  else
	    avail_insn = NULL;
	}

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

      if (avail_insn != NULL_RTX)
	{
	  npred_ok++;
	  ok_count += pred->count;
	  occr = (struct unoccr *) obstack_alloc (&unoccr_obstack,
						  sizeof (struct occr));
	  occr->insn = avail_insn;
	  occr->pred = pred;
	  occr->next = avail_occrs;
	  avail_occrs = occr;
	  if (! rollback_unoccr)
	    rollback_unoccr = occr;
	}
      else
	{
	  not_ok_count += pred->count;
	  unoccr = (struct unoccr *) obstack_alloc (&unoccr_obstack,
						    sizeof (struct unoccr));
	  unoccr->insn = NULL_RTX;
	  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_size && npred_ok > 1))
    goto cleanup;

  /* Check if it's worth applying the partial redundancy elimination.  */
  if (ok_count < GCSE_AFTER_RELOAD_PARTIAL_FRACTION * not_ok_count)
    goto cleanup;
  if (ok_count < GCSE_AFTER_RELOAD_CRITICAL_FRACTION * critical_count)
    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);
      if (! avail_reg)
	abort ();

      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);
       a_occr && (a_occr->insn != insn);
       a_occr = get_bb_avail_insn (bb, a_occr->next));

  if (!a_occr)
    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;
  basic_block bb;

  /* Note we start at block 1.  */

  if (ENTRY_BLOCK_PTR->next_bb == EXIT_BLOCK_PTR)
    return;

  FOR_BB_BETWEEN (bb,
		  ENTRY_BLOCK_PTR->next_bb->next_bb,
		  EXIT_BLOCK_PTR,
		  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 (probably_cold_bb_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)
		  && !(flag_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.  */
static int
delete_redundant_insns_1 (void **slot, void *data ATTRIBUTE_UNUSED)
{
  struct expr *expr = (struct expr *) *slot;
  struct occr *occr;

  for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
    {
      if (occr->deleted_p)
	{
	  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)
{
  htab_traverse (expr_table, 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.  */

void
gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED)
{
  memset (&stats, 0, sizeof (stats));

  /* Allocate ememory 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 (htab_elements (expr_table) > 0)
    {
      eliminate_partially_redundant_loads ();
      delete_redundant_insns ();

      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");
	}
    }
    
  /* We are finished with alias.  */
  end_alias_analysis ();

  free_mem ();
}

