/* Routines for performing Temporary Expression Replacement (TER) in SSA trees.
   Copyright (C) 2003-2021 Free Software Foundation, Inc.
   Contributed by Andrew MacLeod  <amacleod@redhat.com>

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 "tree.h"
#include "gimple.h"
#include "ssa.h"
#include "gimple-pretty-print.h"
#include "gimple-iterator.h"
#include "dumpfile.h"
#include "tree-ssa-live.h"
#include "tree-ssa-ter.h"
#include "tree-outof-ssa.h"
#include "gimple-walk.h"


/* Temporary Expression Replacement (TER)

   Replace SSA version variables during out-of-ssa with their defining
   expression if there is only one use of the variable.

   This pass is required in order for the RTL expansion pass to see larger
   chunks of code.  This allows it to make better choices on RTL pattern
   selection.  When expand is rewritten and merged with out-of-ssa, and
   understands SSA, this should be eliminated.

   A pass is made through the function, one block at a time.  No cross block
   information is tracked.

   Variables which only have one use, and whose defining stmt is considered
   a replaceable expression (see ssa_is_replaceable_p) are tracked to see whether
   they can be replaced at their use location.

   n_12 = C * 10
   a_2 = b_5 + 6
   v_9 = a_2 * n_12

   if there are the only use of n_12 and a_2, TER will substitute in their
   expressions in v_9, and end up with:

   v_9 = (b_5 + 6) * (C * 10)

   which will then have the ssa_name assigned to regular variables, and the
   resulting code which will be passed to the expander looks something like:

   v = (b + 6) * (C * 10)


   This requires ensuring that none of the variables used by the expression
   change between the def point and where it is used.  Furthermore, if any
   of the ssa_names used in this expression are themselves replaceable, we
   have to ensure none of that expressions' arguments change either.
   Although SSA_NAMES themselves don't change, this pass is performed after
   coalescing has coalesced different SSA_NAMES together, so there could be a
   definition of an SSA_NAME which is coalesced with a use that causes a
   problem, i.e.,

   PHI b_5 = <b_8(2), b_14(1)>
   <...>
   a_2 = b_5 + 6
   b_8 = c_4 + 4
   v_9 = a_2 * n_12
   <...>

   If b_5, b_8 and b_14 are all coalesced together...
   The expression b_5 + 6 CANNOT replace the use in the statement defining v_9
   because b_8 is in fact killing the value of b_5 since they share a partition
   and will be assigned the same memory or register location.

   TER implements this but stepping through the instructions in a block and
   tracking potential expressions for replacement, and the partitions they are
   dependent on.  Expressions are represented by the SSA_NAME_VERSION of the
   DEF on the LHS of a GIMPLE_ASSIGN and the expression is the RHS.

   When a stmt is determined to be a possible replacement expression, the
   following steps are taken:

   EXPR_DECL_UID bitmap is allocated and set to the base variable UID of the
   def and any uses in the expression.  non-NULL means the expression is being
   tracked.  The UID's themselves are used to prevent TER substitution into
   accumulating sequences, i.e.,

   x = x + y
   x = x + z
   x = x + w
   etc.
   this can result in very large expressions which don't accomplish anything
   see PR tree-optimization/17549.

   PARTITION_DEPENDENCIES is another bitmap array, and it has a bit set for any
   partition which is used in the expression.  This is primarily used to remove
   an expression from the partition kill lists when a decision is made whether
   to replace it or not.  This is indexed by ssa version number as well, and
   indicates a partition number.  virtual operands are not tracked individually,
   but they are summarized by an artificial partition called VIRTUAL_PARTITION.
   This means a MAY or MUST def will kill *ALL* expressions that are dependent
   on a virtual operand.
   Note that the EXPR_DECL_UID and this bitmap represent very similar
   information, but the info in one is not easy to obtain from the other.

   KILL_LIST is yet another bitmap array, this time it is indexed by partition
   number, and represents a list of active expressions which will no
   longer be valid if a definition into this partition takes place.

   PARTITION_IN_USE is simply a bitmap which is used to track which partitions
   currently have something in their kill list.  This is used at the end of
   a block to clear out the KILL_LIST bitmaps at the end of each block.

   NEW_REPLACEABLE_DEPENDENCIES is used as a temporary place to store
   dependencies which will be reused by the current definition. All the uses
   on an expression are processed before anything else is done. If a use is
   determined to be a replaceable expression AND the current stmt is also going
   to be replaceable, all the dependencies of this replaceable use will be
   picked up by the current stmt's expression. Rather than recreate them, they
   are simply copied here and then copied into the new expression when it is
   processed.

   a_2 = b_5 + 6
   v_8 = a_2 + c_4

   a_2's expression 'b_5 + 6' is determined to be replaceable at the use
   location. It is dependent on the partition 'b_5' is in. This is cached into
   the NEW_REPLACEABLE_DEPENDENCIES bitmap, and when v_8 is examined for
   replaceability, it is a candidate, and it is dependent on the partition
   b_5 is in *NOT* a_2, as well as c_4's partition.

   if v_8 is also replaceable:

   x_9 = v_8 * 5

   x_9 is dependent on partitions b_5, and c_4

   if a statement is found which has either of those partitions written to
   before x_9 is used, then x_9 itself is NOT replaceable.  */


/* Temporary Expression Replacement (TER) table information.  */

struct temp_expr_table
{
  var_map map;
  bitmap *partition_dependencies;	/* Partitions expr is dependent on.  */
  bitmap replaceable_expressions;	/* Replacement expression table.  */
  bitmap *expr_decl_uids;		/* Base uids of exprs.  */
  bitmap *kill_list;			/* Expr's killed by a partition.  */
  int virtual_partition;		/* Pseudo partition for virtual ops.  */
  bitmap partition_in_use;		/* Partitions with kill entries.  */
  bitmap new_replaceable_dependencies;	/* Holding place for pending dep's.  */
  int *num_in_part;			/* # of ssa_names in a partition.  */
  int *call_cnt;			/* Call count at definition.  */
  int *reg_vars_cnt;			/* Number of register variable
					   definitions encountered.  */
};

/* Used to indicate a dependency on VDEFs.  */
#define VIRTUAL_PARTITION(table)	(table->virtual_partition)

/* A place for the many, many bitmaps we create.  */
static bitmap_obstack ter_bitmap_obstack;

extern void debug_ter (FILE *, temp_expr_table *);


/* Create a new TER table for MAP.  */

static temp_expr_table *
new_temp_expr_table (var_map map)
{
  temp_expr_table *t = XNEW (struct temp_expr_table);
  t->map = map;

  t->partition_dependencies = XCNEWVEC (bitmap, num_ssa_names + 1);
  t->expr_decl_uids = XCNEWVEC (bitmap, num_ssa_names + 1);
  t->kill_list = XCNEWVEC (bitmap, num_var_partitions (map) + 1);

  t->partition_in_use = BITMAP_ALLOC (&ter_bitmap_obstack);

  t->virtual_partition = num_var_partitions (map);
  t->new_replaceable_dependencies = BITMAP_ALLOC (&ter_bitmap_obstack);

  t->replaceable_expressions = NULL;
  t->num_in_part = XCNEWVEC (int, num_var_partitions (map));

  unsigned x;
  tree name;

  FOR_EACH_SSA_NAME (x, name, cfun)
    {
      int p;
      p = var_to_partition (map, name);
      if (p != NO_PARTITION)
        t->num_in_part[p]++;
    }
  t->call_cnt = XCNEWVEC (int, num_ssa_names + 1);
  t->reg_vars_cnt = XCNEWVEC (int, num_ssa_names + 1);

  return t;
}


/* Free TER table T.  If there are valid replacements, return the expression
   vector.  */

static bitmap
free_temp_expr_table (temp_expr_table *t)
{
  bitmap ret = NULL;

  if (flag_checking)
    {
      for (unsigned x = 0; x <= num_var_partitions (t->map); x++)
	gcc_assert (!t->kill_list[x]);
      for (unsigned x = 0; x < num_ssa_names; x++)
	{
	  gcc_assert (t->expr_decl_uids[x] == NULL);
	  gcc_assert (t->partition_dependencies[x] == NULL);
	}
    }

  BITMAP_FREE (t->partition_in_use);
  BITMAP_FREE (t->new_replaceable_dependencies);

  free (t->expr_decl_uids);
  free (t->kill_list);
  free (t->partition_dependencies);
  free (t->num_in_part);
  free (t->call_cnt);
  free (t->reg_vars_cnt);

  if (t->replaceable_expressions)
    ret = t->replaceable_expressions;

  free (t);
  return ret;
}


/* Return TRUE if VERSION is to be replaced by an expression in TAB.  */

static inline bool
version_to_be_replaced_p (temp_expr_table *tab, int version)
{
  if (!tab->replaceable_expressions)
    return false;
  return bitmap_bit_p (tab->replaceable_expressions, version);
}


/* Add partition P to the list if partitions VERSION is dependent on.  TAB is
   the expression table */

static inline void
make_dependent_on_partition (temp_expr_table *tab, int version, int p)
{
  if (!tab->partition_dependencies[version])
    tab->partition_dependencies[version] = BITMAP_ALLOC (&ter_bitmap_obstack);

  bitmap_set_bit (tab->partition_dependencies[version], p);
}


/* Add VER to the kill list for P.  TAB is the expression table */

static inline void
add_to_partition_kill_list (temp_expr_table *tab, int p, int ver)
{
  if (!tab->kill_list[p])
    {
      tab->kill_list[p] = BITMAP_ALLOC (&ter_bitmap_obstack);
      bitmap_set_bit (tab->partition_in_use, p);
    }
  bitmap_set_bit (tab->kill_list[p], ver);
}


/* Remove VER from the partition kill list for P.  TAB is the expression
   table.  */

static inline void
remove_from_partition_kill_list (temp_expr_table *tab, int p, int version)
{
  gcc_checking_assert (tab->kill_list[p]);
  bitmap_clear_bit (tab->kill_list[p], version);
  if (bitmap_empty_p (tab->kill_list[p]))
    {
      bitmap_clear_bit (tab->partition_in_use, p);
      BITMAP_FREE (tab->kill_list[p]);
    }
}


/* Add a dependency between the def of ssa VERSION and VAR.  If VAR is
   replaceable by an expression, add a dependence each of the elements of the
   expression.  These are contained in the new_replaceable list.  TAB is the
   expression table.  */

static void
add_dependence (temp_expr_table *tab, int version, tree var)
{
  int i;
  bitmap_iterator bi;
  unsigned x;

  i = SSA_NAME_VERSION (var);
  if (version_to_be_replaced_p (tab, i))
    {
      if (!bitmap_empty_p (tab->new_replaceable_dependencies))
        {
	  /* Version will now be killed by a write to any partition the
	     substituted expression would have been killed by.  */
	  EXECUTE_IF_SET_IN_BITMAP (tab->new_replaceable_dependencies, 0, x, bi)
	    add_to_partition_kill_list (tab, x, version);

	  /* Rather than set partition_dependencies and in_use lists bit by
	     bit, simply OR in the new_replaceable_dependencies bits.  */
	  if (!tab->partition_dependencies[version])
	    tab->partition_dependencies[version] =
	      BITMAP_ALLOC (&ter_bitmap_obstack);
	  bitmap_ior_into (tab->partition_dependencies[version],
			   tab->new_replaceable_dependencies);
	  bitmap_ior_into (tab->partition_in_use,
			   tab->new_replaceable_dependencies);
	  /* It is only necessary to add these once.  */
	  bitmap_clear (tab->new_replaceable_dependencies);
	}
    }
  else
    {
      i = var_to_partition (tab->map, var);
      gcc_checking_assert (i != NO_PARTITION);
      gcc_checking_assert (tab->num_in_part[i] != 0);
      /* Only dependencies on ssa_names which are coalesced with something need
         to be tracked.  Partitions with containing only a single SSA_NAME
	 *cannot* have their value changed.  */
      if (tab->num_in_part[i] > 1)
        {
	  add_to_partition_kill_list (tab, i, version);
	  make_dependent_on_partition (tab, version, i);
	}
    }
}


/* This function will remove the expression for VERSION from replacement
   consideration in table TAB.  If FREE_EXPR is true, then remove the
   expression from consideration as well by freeing the decl uid bitmap.  */

static void
finished_with_expr (temp_expr_table *tab, int version, bool free_expr)
{
  unsigned i;
  bitmap_iterator bi;

  /* Remove this expression from its dependent lists.  The partition dependence
     list is retained and transferred later to whomever uses this version.  */
  if (tab->partition_dependencies[version])
    {
      EXECUTE_IF_SET_IN_BITMAP (tab->partition_dependencies[version], 0, i, bi)
	remove_from_partition_kill_list (tab, i, version);
      BITMAP_FREE (tab->partition_dependencies[version]);
    }
  if (free_expr)
    BITMAP_FREE (tab->expr_decl_uids[version]);
}


/* Return TRUE if expression STMT is suitable for replacement.
   In addition to ssa_is_replaceable_p, require the same bb, and for -O0
   same locus and same BLOCK), Considers memory loads as replaceable if aliasing
   is available.  */

static inline bool
ter_is_replaceable_p (gimple *stmt)
{

  if (ssa_is_replaceable_p (stmt))
    {
      use_operand_p use_p;
      tree def;
      gimple *use_stmt;
      location_t locus1, locus2;
      tree block1, block2;

      /* Only consider definitions which have a single use.  ssa_is_replaceable_p
	 already performed this check, but the use stmt pointer is required for
	 further checks.  */
      def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
      if (!single_imm_use (def, &use_p, &use_stmt))
	  return false;

      /* If the use isn't in this block, it wont be replaced either.  */
      if (gimple_bb (use_stmt) != gimple_bb (stmt))
        return false;

      locus1 = gimple_location (stmt);
      block1 = LOCATION_BLOCK (locus1);
      locus1 = LOCATION_LOCUS (locus1);

      if (gphi *phi = dyn_cast <gphi *> (use_stmt))
	locus2 = gimple_phi_arg_location (phi,
					  PHI_ARG_INDEX_FROM_USE (use_p));
      else
	locus2 = gimple_location (use_stmt);
      block2 = LOCATION_BLOCK (locus2);
      locus2 = LOCATION_LOCUS (locus2);

      if ((!optimize || optimize_debug)
	  && ((locus1 != UNKNOWN_LOCATION && locus1 != locus2)
	      || (block1 != NULL_TREE && block1 != block2)))
	return false;

      return true;
    }
  return false;
}


/* Create an expression entry for a replaceable expression.  */

static void
process_replaceable (temp_expr_table *tab, gimple *stmt, int call_cnt,
		     int reg_vars_cnt)
{
  tree var, def, basevar;
  int version;
  ssa_op_iter iter;
  bitmap def_vars, use_vars;

  gcc_checking_assert (ter_is_replaceable_p (stmt));

  def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
  version = SSA_NAME_VERSION (def);
  def_vars = BITMAP_ALLOC (&ter_bitmap_obstack);

  basevar = SSA_NAME_VAR (def);
  if (basevar)
    bitmap_set_bit (def_vars, DECL_UID (basevar));

  /* Add this expression to the dependency list for each use partition.  */
  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
    {
      int var_version = SSA_NAME_VERSION (var);

      use_vars = tab->expr_decl_uids[var_version];
      add_dependence (tab, version, var);
      if (use_vars)
        {
	  bitmap_ior_into (def_vars, use_vars);
	  BITMAP_FREE (tab->expr_decl_uids[var_version]);
	}
      else if (SSA_NAME_VAR (var))
	bitmap_set_bit (def_vars, DECL_UID (SSA_NAME_VAR (var)));
    }
  tab->expr_decl_uids[version] = def_vars;

  /* If there are VUSES, add a dependence on virtual defs.  */
  if (gimple_vuse (stmt))
    {
      make_dependent_on_partition (tab, version, VIRTUAL_PARTITION (tab));
      add_to_partition_kill_list (tab, VIRTUAL_PARTITION (tab), version);
    }

  tab->call_cnt[version] = call_cnt;
  tab->reg_vars_cnt[version] = reg_vars_cnt;
}


/* This function removes any expression in TAB which is dependent on PARTITION
   from consideration, making it not replaceable.  */

static inline void
kill_expr (temp_expr_table *tab, int partition)
{
  unsigned version;

  /* Mark every active expr dependent on this var as not replaceable.
     finished_with_expr can modify the bitmap, so we can't execute over it.  */
  while (tab->kill_list[partition])
    {
      version = bitmap_first_set_bit (tab->kill_list[partition]);
      finished_with_expr (tab, version, true);
    }

  gcc_checking_assert (!tab->kill_list[partition]);
}


/* This function kills all expressions in TAB which are dependent on virtual
   partitions.  */

static inline void
kill_virtual_exprs (temp_expr_table *tab)
{
  kill_expr (tab, VIRTUAL_PARTITION (tab));
}


/* Mark the expression associated with VAR as replaceable, and enter
   the defining stmt into the partition_dependencies table TAB.  If
   MORE_REPLACING is true, accumulate the pending partition dependencies.  */

static void
mark_replaceable (temp_expr_table *tab, tree var, bool more_replacing)
{
  int version = SSA_NAME_VERSION (var);

  /* Move the dependence list to the pending listpending.  */
  if (more_replacing && tab->partition_dependencies[version])
    bitmap_ior_into (tab->new_replaceable_dependencies,
		     tab->partition_dependencies[version]);

  finished_with_expr (tab, version, !more_replacing);

  /* Set the replaceable expression.
     The bitmap for this "escapes" from this file so it's allocated
     on the default obstack.  */
  if (!tab->replaceable_expressions)
    tab->replaceable_expressions = BITMAP_ALLOC (NULL);
  bitmap_set_bit (tab->replaceable_expressions, version);
}


/* Helper function for find_ssaname_in_stores.  Called via walk_tree to
   find a SSA_NAME DATA somewhere in *TP.  */

static tree
find_ssaname (tree *tp, int *walk_subtrees, void *data)
{
  tree var = (tree) data;
  if (*tp == var)
    return var;
  else if (IS_TYPE_OR_DECL_P (*tp))
    *walk_subtrees = 0;
  return NULL_TREE;
}

/* Helper function for find_replaceable_in_bb.  Return true if SSA_NAME DATA
   is used somewhere in T, which is a store in the statement.  Called via
   walk_stmt_load_store_addr_ops.  */

static bool
find_ssaname_in_store (gimple *, tree, tree t, void *data)
{
  return walk_tree (&t, find_ssaname, data, NULL) != NULL_TREE;
}

/* This function processes basic block BB, and looks for variables which can
   be replaced by their expressions.  Results are stored in the table TAB.  */

static void
find_replaceable_in_bb (temp_expr_table *tab, basic_block bb)
{
  gimple_stmt_iterator bsi;
  gimple *stmt;
  tree def, use, fndecl;
  int partition;
  var_map map = tab->map;
  ssa_op_iter iter;
  bool stmt_replaceable;
  int cur_call_cnt = 0;
  int cur_reg_vars_cnt = 0;

  for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
    {
      stmt = gsi_stmt (bsi);

      if (is_gimple_debug (stmt))
	continue;

      stmt_replaceable = ter_is_replaceable_p (stmt);

      /* Determine if this stmt finishes an existing expression.  */
      FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
	{
	  unsigned ver = SSA_NAME_VERSION (use);

	  /* If this use is a potential replacement variable, process it.  */
	  if (tab->expr_decl_uids[ver])
	    {
	      bool same_root_var = false;
	      ssa_op_iter iter2;
	      bitmap vars = tab->expr_decl_uids[ver];

	      /* See if the root variables are the same.  If they are, we
		 do not want to do the replacement to avoid problems with
		 code size, see PR tree-optimization/17549.  */
	      if (!bitmap_empty_p (vars))
		FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter2, SSA_OP_DEF)
		  {
		    if (SSA_NAME_VAR (def)
			&& bitmap_bit_p (vars, DECL_UID (SSA_NAME_VAR (def))))
		      {
			same_root_var = true;
			break;
		      }
		  }

	      /* If the stmt does a memory store and the replacement
	         is a load aliasing it avoid creating overlapping
		 assignments which we cannot expand correctly.  */
	      if (gimple_vdef (stmt))
		{
		  gimple *def_stmt = SSA_NAME_DEF_STMT (use);
		  while (is_gimple_assign (def_stmt)
			 && gimple_assign_rhs_code (def_stmt) == SSA_NAME)
		    def_stmt
		      = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt));
		  if (gimple_vuse (def_stmt)
		      && gimple_assign_single_p (def_stmt)
		      && stmt_may_clobber_ref_p (stmt,
						 gimple_assign_rhs1 (def_stmt)))
		    {
		      /* For calls, it is not a problem if USE is among
			 call's arguments or say OBJ_TYPE_REF argument,
			 all those necessarily need to be evaluated before
			 the call that may clobber the memory.  But if
			 LHS of the call refers to USE, expansion might
			 evaluate it after the call, prevent TER in that
			 case.
			 For inline asm, allow TER of loads into input
			 arguments, but disallow TER for USEs that occur
			 somewhere in outputs.  */
		      if (is_gimple_call (stmt)
			  || gimple_code (stmt) == GIMPLE_ASM)
			{
			  if (walk_stmt_load_store_ops (stmt, use, NULL,
							find_ssaname_in_store))
			    same_root_var = true;
			}
		      else
			same_root_var = true;
		    }
		}

	      /* Mark expression as replaceable unless stmt is volatile, or the
		 def variable has the same root variable as something in the
		 substitution list, or the def and use span a call such that
		 we'll expand lifetimes across a call.  We also don't want to
		 replace across these expressions that may call libcalls that
		 clobber the register involved.  See PR 70184.  Neither
		 do we want to move possibly trapping expressions across
		 a call.  See PRs 102129 and 33593.  */
	      if (gimple_has_volatile_ops (stmt) || same_root_var
		  || (tab->call_cnt[ver] != cur_call_cnt
		      && (SINGLE_SSA_USE_OPERAND (SSA_NAME_DEF_STMT (use),
						  SSA_OP_USE)
			    == NULL_USE_OPERAND_P
			  || gimple_could_trap_p (SSA_NAME_DEF_STMT (use))))
		  || tab->reg_vars_cnt[ver] != cur_reg_vars_cnt)
		finished_with_expr (tab, ver, true);
	      else
		mark_replaceable (tab, use, stmt_replaceable);
	    }
	}

      /* Next, see if this stmt kills off an active expression.  */
      FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
	{
	  partition = var_to_partition (map, def);
	  if (partition != NO_PARTITION && tab->kill_list[partition])
	    kill_expr (tab, partition);
	}

      /* Increment counter if this is a non BUILT_IN call. We allow
	 replacement over BUILT_IN calls since many will expand to inline
	 insns instead of a true call.  */
      if (is_gimple_call (stmt)
	  && !((fndecl = gimple_call_fndecl (stmt))
	       && fndecl_built_in_p (fndecl)))
	cur_call_cnt++;

      /* Increment counter if this statement sets a local
	 register variable.  */
      if (gimple_assign_single_p (stmt)
	  && (TREE_CODE (gimple_assign_lhs (stmt)) == VAR_DECL
	  && DECL_HARD_REGISTER (gimple_assign_lhs (stmt))))
	cur_reg_vars_cnt++;

      /* Now see if we are creating a new expression or not.  */
      if (stmt_replaceable)
	process_replaceable (tab, stmt, cur_call_cnt, cur_reg_vars_cnt);

      /* Free any unused dependency lists.  */
      bitmap_clear (tab->new_replaceable_dependencies);

      /* A V_{MAY,MUST}_DEF kills any expression using a virtual operand,
	 including the current stmt.  */
      if (gimple_vdef (stmt))
        kill_virtual_exprs (tab);
    }
}


/* This function is the driver routine for replacement of temporary expressions
   in the SSA->normal phase, operating on MAP.  If there are replaceable
   expressions, a table is returned which maps SSA versions to the
   expressions they should be replaced with.  A NULL_TREE indicates no
   replacement should take place.  If there are no replacements at all,
   NULL is returned by the function, otherwise an expression vector indexed
   by SSA_NAME version numbers.  */

bitmap
find_replaceable_exprs (var_map map)
{
  basic_block bb;
  temp_expr_table *table;
  bitmap ret;

  bitmap_obstack_initialize (&ter_bitmap_obstack);
  table = new_temp_expr_table (map);
  FOR_EACH_BB_FN (bb, cfun)
    {
      find_replaceable_in_bb (table, bb);
      gcc_checking_assert (bitmap_empty_p (table->partition_in_use));
    }
  ret = free_temp_expr_table (table);
  bitmap_obstack_release (&ter_bitmap_obstack);
  return ret;
}

/* Dump TER expression table EXPR to file F.  */

void
dump_replaceable_exprs (FILE *f, bitmap expr)
{
  tree var;
  unsigned x;

  fprintf (f, "\nReplacing Expressions\n");
  for (x = 0; x < num_ssa_names; x++)
    if (bitmap_bit_p (expr, x))
      {
	var = ssa_name (x);
	print_generic_expr (f, var, TDF_SLIM);
	fprintf (f, " replace with --> ");
	print_gimple_stmt (f, SSA_NAME_DEF_STMT (var), 0, TDF_SLIM);
	fprintf (f, "\n");
      }
  fprintf (f, "\n");
}


/* Dump the status of the various tables in the expression table.  This is used
   exclusively to debug TER.  F is the place to send debug info and T is the
   table being debugged.  */

DEBUG_FUNCTION void
debug_ter (FILE *f, temp_expr_table *t)
{
  unsigned x, y;
  bitmap_iterator bi;

  fprintf (f, "\nDumping current state of TER\n virtual partition = %d\n",
	   VIRTUAL_PARTITION (t));
  if (t->replaceable_expressions)
    dump_replaceable_exprs (f, t->replaceable_expressions);
  fprintf (f, "Currently tracking the following expressions:\n");

  for (x = 1; x < num_ssa_names; x++)
    if (t->expr_decl_uids[x])
      {
        print_generic_expr (f, ssa_name (x), TDF_SLIM);
        fprintf (f, " dep-parts : ");
	if (t->partition_dependencies[x]
	    && !bitmap_empty_p (t->partition_dependencies[x]))
	  {
	    EXECUTE_IF_SET_IN_BITMAP (t->partition_dependencies[x], 0, y, bi)
	      fprintf (f, "P%d ",y);
	  }
	fprintf (f, "   basedecls: ");
	EXECUTE_IF_SET_IN_BITMAP (t->expr_decl_uids[x], 0, y, bi)
	  fprintf (f, "%d ",y);
	fprintf (f, "   call_cnt : %d",t->call_cnt[x]);
	fprintf (f, "\n");
      }

  bitmap_print (f, t->partition_in_use, "Partitions in use ",
		"\npartition KILL lists:\n");

  for (x = 0; x <= num_var_partitions (t->map); x++)
    if (t->kill_list[x])
      {
        fprintf (f, "Partition %d : ", x);
	EXECUTE_IF_SET_IN_BITMAP (t->kill_list[x], 0, y, bi)
	  fprintf (f, "_%d ",y);
      }

  fprintf (f, "\n----------\n");
}
