/* Routines for performing Temporary Expression Replacement (TER) in SSA trees.
   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 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 "tm.h"
#include "tree.h"
#include "diagnostic.h"
#include "bitmap.h"
#include "tree-flow.h"
#include "tree-dump.h"
#include "tree-ssa-live.h"
#include "flags.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 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 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.  */

typedef struct temp_expr_table_d 
{
  var_map map;
  bitmap *partition_dependencies;	/* Partitions expr is dependent on.  */
  gimple *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.  */
} *temp_expr_table_p;

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

#ifdef ENABLE_CHECKING
extern void debug_ter (FILE *, temp_expr_table_p);
#endif


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

static temp_expr_table_p
new_temp_expr_table (var_map map)
{
  temp_expr_table_p t;
  unsigned x;

  t = XNEW (struct temp_expr_table_d);
  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 (NULL);

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

  t->replaceable_expressions = NULL;
  t->num_in_part = XCNEWVEC (int, num_var_partitions (map));
  for (x = 1; x < num_ssa_names; x++)
    {
      int p;
      tree name = ssa_name (x);
      if (!name)
        continue;
      p = var_to_partition (map, name);
      if (p != NO_PARTITION)
        t->num_in_part[p]++;
    }

  return t;
}


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

static gimple *
free_temp_expr_table (temp_expr_table_p t)
{
  gimple *ret = NULL;

#ifdef ENABLE_CHECKING
  unsigned x;
  for (x = 0; x <= num_var_partitions (t->map); x++)
    gcc_assert (!t->kill_list[x]);
  for (x = 0; x < num_ssa_names + 1; x++)
    {
      gcc_assert (t->expr_decl_uids[x] == NULL);
      gcc_assert (t->partition_dependencies[x] == NULL);
    }
#endif

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

  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_p tab, int version)
{
  if (!tab->replaceable_expressions)
    return false;
  return tab->replaceable_expressions[version] != NULL;
}


/* 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_p tab, int version, int p)
{
  if (!tab->partition_dependencies[version])
    tab->partition_dependencies[version] = BITMAP_ALLOC (NULL);

  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_p tab, int p, int ver)
{
  if (!tab->kill_list[p])
    {
      tab->kill_list[p] = BITMAP_ALLOC (NULL);
      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_p tab, int p, int version)
{
#ifdef ENABLE_CHECKING
  gcc_assert (tab->kill_list[p]);
#endif
  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_p 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 (NULL);
	  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);
#ifdef ENABLE_CHECKING
      gcc_assert (i != NO_PARTITION);
      gcc_assert (tab->num_in_part[i] != 0);
#endif
      /* 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);
	}
    }
}


/* Return TRUE if expression STMT is suitable for replacement.  */

static inline bool
is_replaceable_p (gimple stmt)
{
  use_operand_p use_p;
  tree def;
  gimple use_stmt;
  location_t locus1, locus2;
  tree block1, block2;

  /* Only consider modify stmts.  */
  if (!is_gimple_assign (stmt))
    return false;

  /* If the statement may throw an exception, it cannot be replaced.  */
  if (stmt_could_throw_p (stmt))
    return false;

  /* Punt if there is more than 1 def.  */
  def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
  if (!def)
    return false;

  /* Only consider definitions which have a single use.  */
  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 = gimple_block (stmt);

  if (gimple_code (use_stmt) == GIMPLE_PHI)
    {
      locus2 = 0;
      block2 = NULL_TREE;
    }
  else
    {
      locus2 = gimple_location (use_stmt);
      block2 = gimple_block (use_stmt);
    }

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

  /* Used in this block, but at the TOP of the block, not the end.  */
  if (gimple_code (use_stmt) == GIMPLE_PHI)
    return false;

  /* There must be no VDEFs.  */
  if (!(ZERO_SSA_OPERANDS (stmt, SSA_OP_VDEF)))
    return false;

  /* Without alias info we can't move around loads.  */
  if (gimple_references_memory_p (stmt) && !optimize)
    return false;

  /* Float expressions must go through memory if float-store is on.  */
  if (flag_float_store 
      && FLOAT_TYPE_P (gimple_expr_type (stmt)))
    return false;

  /* An assignment with a register variable on the RHS is not
     replaceable.  */
  if (gimple_assign_rhs_code (stmt) == VAR_DECL
      && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt)))
    return false;

  /* No function calls can be replaced.  */
  if (is_gimple_call (stmt))
    return false;

  /* Leave any stmt with volatile operands alone as well.  */
  if (gimple_has_volatile_ops (stmt))
    return false;

  return true;
}


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


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

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

#ifdef ENABLE_CHECKING
  gcc_assert (is_replaceable_p (stmt));
#endif

  def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
  version = SSA_NAME_VERSION (def);
  basevar = SSA_NAME_VAR (def);
  def_vars = BITMAP_ALLOC (NULL);

  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
	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 (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE))
    {
      make_dependent_on_partition (tab, version, VIRTUAL_PARTITION (tab));
      add_to_partition_kill_list (tab, VIRTUAL_PARTITION (tab), version);
    }
}


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

#ifdef ENABLE_CHECKING
  gcc_assert (!tab->kill_list[partition]);
#endif
}


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

static inline void
kill_virtual_exprs (temp_expr_table_p 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_p 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.  */
  if (!tab->replaceable_expressions)
    tab->replaceable_expressions = XCNEWVEC (gimple, num_ssa_names + 1);
  tab->replaceable_expressions[version] = SSA_NAME_DEF_STMT (var);
}


/* 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_p tab, basic_block bb)
{
  gimple_stmt_iterator bsi;
  gimple stmt;
  tree def, use;
  int partition;
  var_map map = tab->map;
  ssa_op_iter iter;
  bool stmt_replaceable;

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

      stmt_replaceable = 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 (bitmap_bit_p (vars, DECL_UID (SSA_NAME_VAR (def))))
		      {
			same_root_var = true;
			break;
		      }
		  }

	      /* Mark expression as replaceable unless stmt is volatile or the 
		 def variable has the same root variable as something in the 
		 substitution list.  */
	      if (gimple_has_volatile_ops (stmt) || same_root_var)
		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);
	}

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

      /* 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 (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
        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.  */

extern gimple *
find_replaceable_exprs (var_map map)
{
  basic_block bb;
  temp_expr_table_p table;
  gimple *ret;

  table = new_temp_expr_table (map);
  FOR_EACH_BB (bb)
    {
      find_replaceable_in_bb (table, bb);
#ifdef ENABLE_CHECKING
      gcc_assert (bitmap_empty_p (table->partition_in_use));
#endif
    }

  ret = free_temp_expr_table (table);
  return ret;
} 

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

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

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


#ifdef ENABLE_CHECKING
/* 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.  */

void
debug_ter (FILE *f, temp_expr_table_p 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 (stderr, 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 (stderr, "   basedecls: ");
	EXECUTE_IF_SET_IN_BITMAP (t->expr_decl_uids[x], 0, y, bi)
	  fprintf (f, "%d ",y);
	fprintf (stderr, "\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");
}
#endif
