/* Pass computing data for optimizing stdarg functions.
   Copyright (C) 2004-2015 Free Software Foundation, Inc.
   Contributed by Jakub Jelinek <jakub@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 "hash-set.h"
#include "machmode.h"
#include "vec.h"
#include "double-int.h"
#include "input.h"
#include "alias.h"
#include "symtab.h"
#include "wide-int.h"
#include "inchash.h"
#include "tree.h"
#include "fold-const.h"
#include "hard-reg-set.h"
#include "input.h"
#include "function.h"
#include "langhooks.h"
#include "gimple-pretty-print.h"
#include "target.h"
#include "bitmap.h"
#include "predict.h"
#include "dominance.h"
#include "cfg.h"
#include "basic-block.h"
#include "tree-ssa-alias.h"
#include "internal-fn.h"
#include "gimple-expr.h"
#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
#include "stringpool.h"
#include "tree-ssanames.h"
#include "sbitmap.h"
#include "tree-pass.h"
#include "tree-stdarg.h"

/* A simple pass that attempts to optimize stdarg functions on architectures
   that need to save register arguments to stack on entry to stdarg functions.
   If the function doesn't use any va_start macros, no registers need to
   be saved.  If va_start macros are used, the va_list variables don't escape
   the function, it is only necessary to save registers that will be used
   in va_arg macros.  E.g. if va_arg is only used with integral types
   in the function, floating point registers don't need to be saved, etc.  */


/* Return true if basic block VA_ARG_BB is dominated by VA_START_BB and
   is executed at most as many times as VA_START_BB.  */

static bool
reachable_at_most_once (basic_block va_arg_bb, basic_block va_start_bb)
{
  vec<edge> stack = vNULL;
  edge e;
  edge_iterator ei;
  sbitmap visited;
  bool ret;

  if (va_arg_bb == va_start_bb)
    return true;

  if (! dominated_by_p (CDI_DOMINATORS, va_arg_bb, va_start_bb))
    return false;

  visited = sbitmap_alloc (last_basic_block_for_fn (cfun));
  bitmap_clear (visited);
  ret = true;

  FOR_EACH_EDGE (e, ei, va_arg_bb->preds)
    stack.safe_push (e);

  while (! stack.is_empty ())
    {
      basic_block src;

      e = stack.pop ();
      src = e->src;

      if (e->flags & EDGE_COMPLEX)
	{
	  ret = false;
	  break;
	}

      if (src == va_start_bb)
	continue;

      /* va_arg_bb can be executed more times than va_start_bb.  */
      if (src == va_arg_bb)
	{
	  ret = false;
	  break;
	}

      gcc_assert (src != ENTRY_BLOCK_PTR_FOR_FN (cfun));

      if (! bitmap_bit_p (visited, src->index))
	{
	  bitmap_set_bit (visited, src->index);
	  FOR_EACH_EDGE (e, ei, src->preds)
	    stack.safe_push (e);
	}
    }

  stack.release ();
  sbitmap_free (visited);
  return ret;
}


/* For statement COUNTER = RHS, if RHS is COUNTER + constant,
   return constant, otherwise return HOST_WIDE_INT_M1U.
   GPR_P is true if this is GPR counter.  */

static unsigned HOST_WIDE_INT
va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
		      bool gpr_p)
{
  tree lhs, orig_lhs;
  gimple stmt;
  unsigned HOST_WIDE_INT ret = 0, val, counter_val;
  unsigned int max_size;

  if (si->offsets == NULL)
    {
      unsigned int i;

      si->offsets = XNEWVEC (int, num_ssa_names);
      for (i = 0; i < num_ssa_names; ++i)
	si->offsets[i] = -1;
    }

  counter_val = gpr_p ? cfun->va_list_gpr_size : cfun->va_list_fpr_size;
  max_size = gpr_p ? VA_LIST_MAX_GPR_SIZE : VA_LIST_MAX_FPR_SIZE;
  orig_lhs = lhs = rhs;
  while (lhs)
    {
      enum tree_code rhs_code;
      tree rhs1;

      if (si->offsets[SSA_NAME_VERSION (lhs)] != -1)
	{
	  if (counter_val >= max_size)
	    {
	      ret = max_size;
	      break;
	    }

	  ret -= counter_val - si->offsets[SSA_NAME_VERSION (lhs)];
	  break;
	}

      stmt = SSA_NAME_DEF_STMT (lhs);

      if (!is_gimple_assign (stmt) || gimple_assign_lhs (stmt) != lhs)
	return HOST_WIDE_INT_M1U;

      rhs_code = gimple_assign_rhs_code (stmt);
      rhs1 = gimple_assign_rhs1 (stmt);
      if ((get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS
	   || gimple_assign_cast_p (stmt))
	  && TREE_CODE (rhs1) == SSA_NAME)
	{
	  lhs = rhs1;
	  continue;
	}

      if ((rhs_code == POINTER_PLUS_EXPR
	   || rhs_code == PLUS_EXPR)
	  && TREE_CODE (rhs1) == SSA_NAME
	  && tree_fits_uhwi_p (gimple_assign_rhs2 (stmt)))
	{
	  ret += tree_to_uhwi (gimple_assign_rhs2 (stmt));
	  lhs = rhs1;
	  continue;
	}

      if (rhs_code == ADDR_EXPR 
	  && TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
	  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0)) == SSA_NAME
	  && tree_fits_uhwi_p (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1)))
	{
	  ret += tree_to_uhwi (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1));
	  lhs = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
	  continue;
	}

      if (get_gimple_rhs_class (rhs_code) != GIMPLE_SINGLE_RHS)
	return HOST_WIDE_INT_M1U;

      rhs = gimple_assign_rhs1 (stmt);
      if (TREE_CODE (counter) != TREE_CODE (rhs))
	return HOST_WIDE_INT_M1U;

      if (TREE_CODE (counter) == COMPONENT_REF)
	{
	  if (get_base_address (counter) != get_base_address (rhs)
	      || TREE_CODE (TREE_OPERAND (rhs, 1)) != FIELD_DECL
	      || TREE_OPERAND (counter, 1) != TREE_OPERAND (rhs, 1))
	    return HOST_WIDE_INT_M1U;
	}
      else if (counter != rhs)
	return HOST_WIDE_INT_M1U;

      lhs = NULL;
    }

  lhs = orig_lhs;
  val = ret + counter_val;
  while (lhs)
    {
      enum tree_code rhs_code;
      tree rhs1;

      if (si->offsets[SSA_NAME_VERSION (lhs)] != -1)
	break;

      if (val >= max_size)
	si->offsets[SSA_NAME_VERSION (lhs)] = max_size;
      else
	si->offsets[SSA_NAME_VERSION (lhs)] = val;

      stmt = SSA_NAME_DEF_STMT (lhs);

      rhs_code = gimple_assign_rhs_code (stmt);
      rhs1 = gimple_assign_rhs1 (stmt);
      if ((get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS
	   || gimple_assign_cast_p (stmt))
	  && TREE_CODE (rhs1) == SSA_NAME)
	{
	  lhs = rhs1;
	  continue;
	}

      if ((rhs_code == POINTER_PLUS_EXPR
	   || rhs_code == PLUS_EXPR)
	  && TREE_CODE (rhs1) == SSA_NAME
	  && tree_fits_uhwi_p (gimple_assign_rhs2 (stmt)))
	{
	  val -= tree_to_uhwi (gimple_assign_rhs2 (stmt));
	  lhs = rhs1;
	  continue;
	}

      if (rhs_code == ADDR_EXPR 
	  && TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
	  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0)) == SSA_NAME
	  && tree_fits_uhwi_p (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1)))
	{
	  val -= tree_to_uhwi (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1));
	  lhs = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
	  continue;
	}

      lhs = NULL;
    }

  return ret;
}


/* Called by walk_tree to look for references to va_list variables.  */

static tree
find_va_list_reference (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
			void *data)
{
  bitmap va_list_vars = (bitmap) ((struct walk_stmt_info *) data)->info;
  tree var = *tp;

  if (TREE_CODE (var) == SSA_NAME)
    {
      if (bitmap_bit_p (va_list_vars, SSA_NAME_VERSION (var)))
	return var;
    }
  else if (TREE_CODE (var) == VAR_DECL)
    {
      if (bitmap_bit_p (va_list_vars, DECL_UID (var) + num_ssa_names))
	return var;
    }

  return NULL_TREE;
}


/* Helper function of va_list_counter_struct_op.  Compute
   cfun->va_list_{g,f}pr_size.  AP is a va_list GPR/FPR counter,
   if WRITE_P is true, seen in AP = VAR, otherwise seen in VAR = AP
   statement.  GPR_P is true if AP is a GPR counter, false if it is
   a FPR counter.  */

static void
va_list_counter_op (struct stdarg_info *si, tree ap, tree var, bool gpr_p,
		    bool write_p)
{
  unsigned HOST_WIDE_INT increment;

  if (si->compute_sizes < 0)
    {
      si->compute_sizes = 0;
      if (si->va_start_count == 1
	  && reachable_at_most_once (si->bb, si->va_start_bb))
	si->compute_sizes = 1;

      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "bb%d will %sbe executed at most once for each va_start "
		 "in bb%d\n", si->bb->index, si->compute_sizes ? "" : "not ",
		 si->va_start_bb->index);
    }

  if (write_p
      && si->compute_sizes
      && (increment = va_list_counter_bump (si, ap, var, gpr_p)) + 1 > 1)
    {
      if (gpr_p && cfun->va_list_gpr_size + increment < VA_LIST_MAX_GPR_SIZE)
	{
	  cfun->va_list_gpr_size += increment;
	  return;
	}

      if (!gpr_p && cfun->va_list_fpr_size + increment < VA_LIST_MAX_FPR_SIZE)
	{
	  cfun->va_list_fpr_size += increment;
	  return;
	}
    }

  if (write_p || !si->compute_sizes)
    {
      if (gpr_p)
	cfun->va_list_gpr_size = VA_LIST_MAX_GPR_SIZE;
      else
	cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;
    }
}


/* If AP is a va_list GPR/FPR counter, compute cfun->va_list_{g,f}pr_size.
   If WRITE_P is true, AP has been seen in AP = VAR assignment, if WRITE_P
   is false, AP has been seen in VAR = AP assignment.
   Return true if the AP = VAR (resp. VAR = AP) statement is a recognized
   va_arg operation that doesn't cause the va_list variable to escape
   current function.  */

static bool
va_list_counter_struct_op (struct stdarg_info *si, tree ap, tree var,
			   bool write_p)
{
  tree base;

  if (TREE_CODE (ap) != COMPONENT_REF
      || TREE_CODE (TREE_OPERAND (ap, 1)) != FIELD_DECL)
    return false;

  if (TREE_CODE (var) != SSA_NAME
      || bitmap_bit_p (si->va_list_vars, SSA_NAME_VERSION (var)))
    return false;

  base = get_base_address (ap);
  if (TREE_CODE (base) != VAR_DECL
      || !bitmap_bit_p (si->va_list_vars, DECL_UID (base) + num_ssa_names))
    return false;

  if (TREE_OPERAND (ap, 1) == va_list_gpr_counter_field)
    va_list_counter_op (si, ap, var, true, write_p);
  else if (TREE_OPERAND (ap, 1) == va_list_fpr_counter_field)
    va_list_counter_op (si, ap, var, false, write_p);

  return true;
}


/* Check for TEM = AP.  Return true if found and the caller shouldn't
   search for va_list references in the statement.  */

static bool
va_list_ptr_read (struct stdarg_info *si, tree ap, tree tem)
{
  if (TREE_CODE (ap) != VAR_DECL
      || !bitmap_bit_p (si->va_list_vars, DECL_UID (ap) + num_ssa_names))
    return false;

  if (TREE_CODE (tem) != SSA_NAME
      || bitmap_bit_p (si->va_list_vars, SSA_NAME_VERSION (tem)))
    return false;

  if (si->compute_sizes < 0)
    {
      si->compute_sizes = 0;
      if (si->va_start_count == 1
	  && reachable_at_most_once (si->bb, si->va_start_bb))
	si->compute_sizes = 1;

      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "bb%d will %sbe executed at most once for each va_start "
		 "in bb%d\n", si->bb->index, si->compute_sizes ? "" : "not ",
		 si->va_start_bb->index);
    }

  /* For void * or char * va_list types, there is just one counter.
     If va_arg is used in a loop, we don't know how many registers need
     saving.  */
  if (! si->compute_sizes)
    return false;

  if (va_list_counter_bump (si, ap, tem, true) == HOST_WIDE_INT_M1U)
    return false;

  /* Note the temporary, as we need to track whether it doesn't escape
     the current function.  */
  bitmap_set_bit (si->va_list_escape_vars, SSA_NAME_VERSION (tem));

  return true;
}


/* Check for:
     tem1 = AP;
     TEM2 = tem1 + CST;
     AP = TEM2;
   sequence and update cfun->va_list_gpr_size.  Return true if found.  */

static bool
va_list_ptr_write (struct stdarg_info *si, tree ap, tree tem2)
{
  unsigned HOST_WIDE_INT increment;

  if (TREE_CODE (ap) != VAR_DECL
      || !bitmap_bit_p (si->va_list_vars, DECL_UID (ap) + num_ssa_names))
    return false;

  if (TREE_CODE (tem2) != SSA_NAME
      || bitmap_bit_p (si->va_list_vars, SSA_NAME_VERSION (tem2)))
    return false;

  if (si->compute_sizes <= 0)
    return false;

  increment = va_list_counter_bump (si, ap, tem2, true);
  if (increment + 1 <= 1)
    return false;

  if (cfun->va_list_gpr_size + increment < VA_LIST_MAX_GPR_SIZE)
    cfun->va_list_gpr_size += increment;
  else
    cfun->va_list_gpr_size = VA_LIST_MAX_GPR_SIZE;

  return true;
}


/* If RHS is X, (some type *) X or X + CST for X a temporary variable
   containing value of some va_list variable plus optionally some constant,
   either set si->va_list_escapes or add LHS to si->va_list_escape_vars,
   depending whether LHS is a function local temporary.  */

static void
check_va_list_escapes (struct stdarg_info *si, tree lhs, tree rhs)
{
  if (! POINTER_TYPE_P (TREE_TYPE (rhs)))
    return;

  if (TREE_CODE (rhs) == SSA_NAME)
    {
      if (! bitmap_bit_p (si->va_list_escape_vars, SSA_NAME_VERSION (rhs)))
	return;
    }
  else if (TREE_CODE (rhs) == ADDR_EXPR
	   && TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF
	   && TREE_CODE (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0)) == SSA_NAME)
    {
      tree ptr = TREE_OPERAND (TREE_OPERAND (rhs, 0), 0);
      if (! bitmap_bit_p (si->va_list_escape_vars, SSA_NAME_VERSION (ptr)))
	return;
    }
  else
    return;

  if (TREE_CODE (lhs) != SSA_NAME)
    {
      si->va_list_escapes = true;
      return;
    }

  if (si->compute_sizes < 0)
    {
      si->compute_sizes = 0;
      if (si->va_start_count == 1
	  && reachable_at_most_once (si->bb, si->va_start_bb))
	si->compute_sizes = 1;

      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "bb%d will %sbe executed at most once for each va_start "
		 "in bb%d\n", si->bb->index, si->compute_sizes ? "" : "not ",
		 si->va_start_bb->index);
    }

  /* For void * or char * va_list types, there is just one counter.
     If va_arg is used in a loop, we don't know how many registers need
     saving.  */
  if (! si->compute_sizes)
    {
      si->va_list_escapes = true;
      return;
    }

  if (va_list_counter_bump (si, si->va_start_ap, lhs, true)
      == HOST_WIDE_INT_M1U)
    {
      si->va_list_escapes = true;
      return;
    }

  bitmap_set_bit (si->va_list_escape_vars, SSA_NAME_VERSION (lhs));
}


/* Check all uses of temporaries from si->va_list_escape_vars bitmap.
   Return true if va_list might be escaping.  */

static bool
check_all_va_list_escapes (struct stdarg_info *si)
{
  basic_block bb;

  FOR_EACH_BB_FN (bb, cfun)
    {
      for (gphi_iterator i = gsi_start_phis (bb); !gsi_end_p (i);
	   gsi_next (&i))
	{
	  tree lhs;
	  use_operand_p uop;
	  ssa_op_iter soi;
	  gphi *phi = i.phi ();

	  lhs = PHI_RESULT (phi);
	  if (virtual_operand_p (lhs)
	      || bitmap_bit_p (si->va_list_escape_vars,
			       SSA_NAME_VERSION (lhs)))
	    continue;

	  FOR_EACH_PHI_ARG (uop, phi, soi, SSA_OP_USE)
	    {
	      tree rhs = USE_FROM_PTR (uop);
	      if (TREE_CODE (rhs) == SSA_NAME
		  && bitmap_bit_p (si->va_list_escape_vars,
				SSA_NAME_VERSION (rhs)))
		{
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    {
		      fputs ("va_list escapes in ", dump_file);
		      print_gimple_stmt (dump_file, phi, 0, dump_flags);
		      fputc ('\n', dump_file);
		    }
		  return true;
		}
	    }
	}

      for (gimple_stmt_iterator i = gsi_start_bb (bb); !gsi_end_p (i);
	   gsi_next (&i))
	{
	  gimple stmt = gsi_stmt (i);
	  tree use;
	  ssa_op_iter iter;

	  if (is_gimple_debug (stmt))
	    continue;

	  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_USES)
	    {
	      if (! bitmap_bit_p (si->va_list_escape_vars,
				  SSA_NAME_VERSION (use)))
		continue;

	      if (is_gimple_assign (stmt))
		{
		  tree rhs = gimple_assign_rhs1 (stmt);
		  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);

		  /* x = *ap_temp;  */
		  if (rhs_code == MEM_REF
		      && TREE_OPERAND (rhs, 0) == use
		      && TYPE_SIZE_UNIT (TREE_TYPE (rhs))
		      && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (rhs)))
		      && si->offsets[SSA_NAME_VERSION (use)] != -1)
		    {
		      unsigned HOST_WIDE_INT gpr_size;
		      tree access_size = TYPE_SIZE_UNIT (TREE_TYPE (rhs));

		      gpr_size = si->offsets[SSA_NAME_VERSION (use)]
			  	 + tree_to_shwi (TREE_OPERAND (rhs, 1))
				 + tree_to_uhwi (access_size);
		      if (gpr_size >= VA_LIST_MAX_GPR_SIZE)
			cfun->va_list_gpr_size = VA_LIST_MAX_GPR_SIZE;
		      else if (gpr_size > cfun->va_list_gpr_size)
			cfun->va_list_gpr_size = gpr_size;
		      continue;
		    }

		  /* va_arg sequences may contain
		     other_ap_temp = ap_temp;
		     other_ap_temp = ap_temp + constant;
		     other_ap_temp = (some_type *) ap_temp;
		     ap = ap_temp;
		     statements.  */
		  if (rhs == use
		      && ((rhs_code == POINTER_PLUS_EXPR
			   && (TREE_CODE (gimple_assign_rhs2 (stmt))
			       == INTEGER_CST))
			  || gimple_assign_cast_p (stmt)
			  || (get_gimple_rhs_class (rhs_code)
			      == GIMPLE_SINGLE_RHS)))
		    {
		      tree lhs = gimple_assign_lhs (stmt);

		      if (TREE_CODE (lhs) == SSA_NAME
			  && bitmap_bit_p (si->va_list_escape_vars,
					   SSA_NAME_VERSION (lhs)))
			continue;

		      if (TREE_CODE (lhs) == VAR_DECL
			  && bitmap_bit_p (si->va_list_vars,
					   DECL_UID (lhs) + num_ssa_names))
			continue;
		    }
		  else if (rhs_code == ADDR_EXPR
			   && TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF
			   && TREE_OPERAND (TREE_OPERAND (rhs, 0), 0) == use)
		    {
		      tree lhs = gimple_assign_lhs (stmt);

		      if (bitmap_bit_p (si->va_list_escape_vars,
					SSA_NAME_VERSION (lhs)))
			continue;
		    }
		}

	      if (dump_file && (dump_flags & TDF_DETAILS))
		{
		  fputs ("va_list escapes in ", dump_file);
		  print_gimple_stmt (dump_file, stmt, 0, dump_flags);
		  fputc ('\n', dump_file);
		}
	      return true;
	    }
	}
    }

  return false;
}


namespace {

const pass_data pass_data_stdarg =
{
  GIMPLE_PASS, /* type */
  "stdarg", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  ( PROP_cfg | PROP_ssa ), /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_stdarg : public gimple_opt_pass
{
public:
  pass_stdarg (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_stdarg, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *fun)
    {
      return (flag_stdarg_opt
#ifdef ACCEL_COMPILER
	      /* Disable for GCC5 in the offloading compilers, as
		 va_list and gpr/fpr counter fields are not merged.
		 In GCC6 when stdarg is lowered late this shouldn't be
		 an issue.  */
	      && !in_lto_p
#endif
	      /* This optimization is only for stdarg functions.  */
	      && fun->stdarg != 0);
    }

  virtual unsigned int execute (function *);

}; // class pass_stdarg

unsigned int
pass_stdarg::execute (function *fun)
{
  basic_block bb;
  bool va_list_escapes = false;
  bool va_list_simple_ptr;
  struct stdarg_info si;
  struct walk_stmt_info wi;
  const char *funcname = NULL;
  tree cfun_va_list;

  fun->va_list_gpr_size = 0;
  fun->va_list_fpr_size = 0;
  memset (&si, 0, sizeof (si));
  si.va_list_vars = BITMAP_ALLOC (NULL);
  si.va_list_escape_vars = BITMAP_ALLOC (NULL);

  if (dump_file)
    funcname = lang_hooks.decl_printable_name (current_function_decl, 2);

  cfun_va_list = targetm.fn_abi_va_list (fun->decl);
  va_list_simple_ptr = POINTER_TYPE_P (cfun_va_list)
		       && (TREE_TYPE (cfun_va_list) == void_type_node
			   || TREE_TYPE (cfun_va_list) == char_type_node);
  gcc_assert (is_gimple_reg_type (cfun_va_list) == va_list_simple_ptr);

  FOR_EACH_BB_FN (bb, fun)
    {
      gimple_stmt_iterator i;

      for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
	{
	  gimple stmt = gsi_stmt (i);
	  tree callee, ap;

	  if (!is_gimple_call (stmt))
	    continue;

	  callee = gimple_call_fndecl (stmt);
	  if (!callee
	      || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
	    continue;

	  switch (DECL_FUNCTION_CODE (callee))
	    {
	    case BUILT_IN_VA_START:
	      break;
	      /* If old style builtins are used, don't optimize anything.  */
	    case BUILT_IN_SAVEREGS:
	    case BUILT_IN_NEXT_ARG:
	      va_list_escapes = true;
	      continue;
	    default:
	      continue;
	    }

	  si.va_start_count++;
	  ap = gimple_call_arg (stmt, 0);

	  if (TREE_CODE (ap) != ADDR_EXPR)
	    {
	      va_list_escapes = true;
	      break;
	    }
	  ap = TREE_OPERAND (ap, 0);
	  if (TREE_CODE (ap) == ARRAY_REF)
	    {
	      if (! integer_zerop (TREE_OPERAND (ap, 1)))
	        {
	          va_list_escapes = true;
	          break;
		}
	      ap = TREE_OPERAND (ap, 0);
	    }
	  if (TYPE_MAIN_VARIANT (TREE_TYPE (ap))
	      != TYPE_MAIN_VARIANT (targetm.fn_abi_va_list (fun->decl))
	      || TREE_CODE (ap) != VAR_DECL)
	    {
	      va_list_escapes = true;
	      break;
	    }

	  if (is_global_var (ap))
	    {
	      va_list_escapes = true;
	      break;
	    }

	  bitmap_set_bit (si.va_list_vars, DECL_UID (ap) + num_ssa_names);

	  /* VA_START_BB and VA_START_AP will be only used if there is just
	     one va_start in the function.  */
	  si.va_start_bb = bb;
	  si.va_start_ap = ap;
	}

      if (va_list_escapes)
	break;
    }

  /* If there were no va_start uses in the function, there is no need to
     save anything.  */
  if (si.va_start_count == 0)
    goto finish;

  /* If some va_list arguments weren't local, we can't optimize.  */
  if (va_list_escapes)
    goto finish;

  /* For void * or char * va_list, something useful can be done only
     if there is just one va_start.  */
  if (va_list_simple_ptr && si.va_start_count > 1)
    {
      va_list_escapes = true;
      goto finish;
    }

  /* For struct * va_list, if the backend didn't tell us what the counter fields
     are, there is nothing more we can do.  */
  if (!va_list_simple_ptr
      && va_list_gpr_counter_field == NULL_TREE
      && va_list_fpr_counter_field == NULL_TREE)
    {
      va_list_escapes = true;
      goto finish;
    }

  /* For void * or char * va_list there is just one counter
     (va_list itself).  Use VA_LIST_GPR_SIZE for it.  */
  if (va_list_simple_ptr)
    fun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;

  calculate_dominance_info (CDI_DOMINATORS);
  memset (&wi, 0, sizeof (wi));
  wi.info = si.va_list_vars;

  FOR_EACH_BB_FN (bb, fun)
    {
      si.compute_sizes = -1;
      si.bb = bb;

      /* For va_list_simple_ptr, we have to check PHI nodes too.  We treat
	 them as assignments for the purpose of escape analysis.  This is
	 not needed for non-simple va_list because virtual phis don't perform
	 any real data movement.  Also, check PHI nodes for taking address of
	 the va_list vars.  */
      tree lhs, rhs;
      use_operand_p uop;
      ssa_op_iter soi;

      for (gphi_iterator i = gsi_start_phis (bb); !gsi_end_p (i);
	   gsi_next (&i))
	{
	  gphi *phi = i.phi ();
	  lhs = PHI_RESULT (phi);

	  if (virtual_operand_p (lhs))
	    continue;

	  if (va_list_simple_ptr)
	    {
	      FOR_EACH_PHI_ARG (uop, phi, soi, SSA_OP_USE)
		{
		  rhs = USE_FROM_PTR (uop);
		  if (va_list_ptr_read (&si, rhs, lhs))
		    continue;
		  else if (va_list_ptr_write (&si, lhs, rhs))
		    continue;
		  else
		    check_va_list_escapes (&si, lhs, rhs);

		  if (si.va_list_escapes)
		    {
		      if (dump_file && (dump_flags & TDF_DETAILS))
			{
			  fputs ("va_list escapes in ", dump_file);
			  print_gimple_stmt (dump_file, phi, 0, dump_flags);
			  fputc ('\n', dump_file);
			}
		      va_list_escapes = true;
		    }
		}
	    }

	  for (unsigned j = 0; !va_list_escapes
			       && j < gimple_phi_num_args (phi); ++j)
	    if ((!va_list_simple_ptr
		 || TREE_CODE (gimple_phi_arg_def (phi, j)) != SSA_NAME)
		&& walk_tree (gimple_phi_arg_def_ptr (phi, j),
			      find_va_list_reference, &wi, NULL))
	      {
		if (dump_file && (dump_flags & TDF_DETAILS))
		  {
		    fputs ("va_list escapes in ", dump_file);
		    print_gimple_stmt (dump_file, phi, 0, dump_flags);
		    fputc ('\n', dump_file);
		  }
		va_list_escapes = true;
	      }
	}

      for (gimple_stmt_iterator i = gsi_start_bb (bb);
	   !gsi_end_p (i) && !va_list_escapes;
	   gsi_next (&i))
	{
	  gimple stmt = gsi_stmt (i);

	  /* Don't look at __builtin_va_{start,end}, they are ok.  */
	  if (is_gimple_call (stmt))
	    {
	      tree callee = gimple_call_fndecl (stmt);

	      if (callee
		  && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
		  && (DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_START
		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_END))
		continue;
	    }

	  if (is_gimple_assign (stmt))
	    {
	      lhs = gimple_assign_lhs (stmt);
	      rhs = gimple_assign_rhs1 (stmt);

	      if (va_list_simple_ptr)
		{
		  if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
		      == GIMPLE_SINGLE_RHS)
		    {
		      /* Check for ap ={v} {}.  */
		      if (TREE_CLOBBER_P (rhs))
			continue;

		      /* Check for tem = ap.  */
		      else if (va_list_ptr_read (&si, rhs, lhs))
			continue;

		      /* Check for the last insn in:
			 tem1 = ap;
			 tem2 = tem1 + CST;
			 ap = tem2;
			 sequence.  */
		      else if (va_list_ptr_write (&si, lhs, rhs))
			continue;
		    }

		  if ((gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
		       && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST)
		      || CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
		      || (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
			  == GIMPLE_SINGLE_RHS))
		    check_va_list_escapes (&si, lhs, rhs);
		}
	      else
		{
		  if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
		      == GIMPLE_SINGLE_RHS)
		    {
		      /* Check for ap ={v} {}.  */
		      if (TREE_CLOBBER_P (rhs))
			continue;

		      /* Check for ap[0].field = temp.  */
		      else if (va_list_counter_struct_op (&si, lhs, rhs, true))
			continue;

		      /* Check for temp = ap[0].field.  */
		      else if (va_list_counter_struct_op (&si, rhs, lhs,
							  false))
			continue;
		    }

		  /* Do any architecture specific checking.  */
		  if (targetm.stdarg_optimize_hook
		      && targetm.stdarg_optimize_hook (&si, stmt))
		    continue;
		}
	    }
	  else if (is_gimple_debug (stmt))
	    continue;

	  /* All other uses of va_list are either va_copy (that is not handled
	     in this optimization), taking address of va_list variable or
	     passing va_list to other functions (in that case va_list might
	     escape the function and therefore va_start needs to set it up
	     fully), or some unexpected use of va_list.  None of these should
	     happen in a gimplified VA_ARG_EXPR.  */
	  if (si.va_list_escapes
	      || walk_gimple_op (stmt, find_va_list_reference, &wi))
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		{
		  fputs ("va_list escapes in ", dump_file);
		  print_gimple_stmt (dump_file, stmt, 0, dump_flags);
		  fputc ('\n', dump_file);
		}
	      va_list_escapes = true;
	    }
	}

      if (va_list_escapes)
	break;
    }

  if (! va_list_escapes
      && va_list_simple_ptr
      && ! bitmap_empty_p (si.va_list_escape_vars)
      && check_all_va_list_escapes (&si))
    va_list_escapes = true;

finish:
  if (va_list_escapes)
    {
      fun->va_list_gpr_size = VA_LIST_MAX_GPR_SIZE;
      fun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;
    }
  BITMAP_FREE (si.va_list_vars);
  BITMAP_FREE (si.va_list_escape_vars);
  free (si.offsets);
  if (dump_file)
    {
      fprintf (dump_file, "%s: va_list escapes %d, needs to save ",
	       funcname, (int) va_list_escapes);
      if (fun->va_list_gpr_size >= VA_LIST_MAX_GPR_SIZE)
	fputs ("all", dump_file);
      else
	fprintf (dump_file, "%d", cfun->va_list_gpr_size);
      fputs (" GPR units and ", dump_file);
      if (fun->va_list_fpr_size >= VA_LIST_MAX_FPR_SIZE)
	fputs ("all", dump_file);
      else
	fprintf (dump_file, "%d", cfun->va_list_fpr_size);
      fputs (" FPR units.\n", dump_file);
    }
  return 0;
}

} // anon namespace

gimple_opt_pass *
make_pass_stdarg (gcc::context *ctxt)
{
  return new pass_stdarg (ctxt);
}
