/* Perform optimizations on tree structure.
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005
   Free Software Foundation, Inc.
   Written by Mark Michell (mark@codesourcery.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 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, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "rtl.h"
#include "insn-config.h"
#include "input.h"
#include "integrate.h"
#include "toplev.h"
#include "varray.h"
#include "params.h"
#include "hashtab.h"
#include "target.h"
#include "debug.h"
#include "tree-inline.h"
#include "flags.h"
#include "langhooks.h"
#include "diagnostic.h"
#include "tree-dump.h"
#include "tree-gimple.h"

/* Prototypes.  */

static void update_cloned_parm (tree, tree, bool);
/* APPLE LOCAL begin structor thunks */
static int maybe_alias_body (tree fn, tree clone);
static int maybe_thunk_body (tree fn);
/* APPLE LOCAL end structor thunks */

/* CLONED_PARM is a copy of CLONE, generated for a cloned constructor
   or destructor.  Update it to ensure that the source-position for
   the cloned parameter matches that for the original, and that the
   debugging generation code will be able to find the original PARM.  */

static void
update_cloned_parm (tree parm, tree cloned_parm, bool first)
{
  DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;

  /* We may have taken its address.  */
  TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);

  /* The definition might have different constness.  */
  TREE_READONLY (cloned_parm) = TREE_READONLY (parm);

  TREE_USED (cloned_parm) = !first || TREE_USED (parm);

  /* The name may have changed from the declaration.  */
  DECL_NAME (cloned_parm) = DECL_NAME (parm);
  DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
  TREE_TYPE (cloned_parm) = TREE_TYPE (parm);

  DECL_COMPLEX_GIMPLE_REG_P (cloned_parm) = DECL_COMPLEX_GIMPLE_REG_P (parm);
}

/* APPLE LOCAL begin structor thunks */
/* FN is a constructor or destructor, and there are FUNCTION_DECLs cloned from it nearby.
   If the clone and the original funciton have identical parameter lists,
   it is a fully-degenerate (does absolutely nothing) thunk.
   Make the clone an alias for the original function label.  */
static int
maybe_alias_body (tree fn ATTRIBUTE_UNUSED, tree clone ATTRIBUTE_UNUSED)
{
  extern FILE *asm_out_file ATTRIBUTE_UNUSED;

#ifdef ASM_MAYBE_ALIAS_BODY
  ASM_MAYBE_ALIAS_BODY (asm_out_file, fn, clone);
#endif
  return 0;
}

/* FN is a constructor or destructor, and there are FUNCTION_DECLs
   cloned from it nearby.  Instead of cloning this body, leave it
   alone and create tiny one-call bodies for the cloned
   FUNCTION_DECLs.  These clones are sibcall candidates, and their
   resulting code will be very thunk-esque.  */
static int
maybe_thunk_body (tree fn)
{
  tree call, clone, expr_stmt, fn_parm, fn_parm_typelist, last_arg, start;
  int parmno, vtt_parmno;

  /* APPLE LOCAL disable de-cloner */
  if (TRUE || TARGET_KEXTABI || flag_clone_structors)
    return 0;

  /* If we've already seen this structor, avoid re-processing it.  */
  if (TREE_ASM_WRITTEN (fn))
    return 1;

  /* If function accepts variable arguments, give up.  */
  last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn)));
  if ( ! VOID_TYPE_P (TREE_VALUE (last_arg)))
       return 0;

  /* If constructor expects vector (AltiVec) arguments, give up.  */
  for (fn_parm = DECL_ARGUMENTS( fn); fn_parm; fn_parm = TREE_CHAIN (fn_parm))
    if (TREE_CODE (fn_parm) == VECTOR_TYPE)
      return 0;

  /* If we don't see a clone, nothing to do.  */
  clone = TREE_CHAIN (fn);
  if (!clone || ! DECL_CLONED_FUNCTION_P (clone))
    return 0;

  /* This is only a win if there are two or more clones.  */
  if ( ! TREE_CHAIN (clone))
    return 0;

  /* Only thunk-ify non-trivial structors.  */
  if (DECL_ESTIMATED_INSNS (fn) < 5)
     return 0;

  /* If we got this far, we've decided to turn the clones into thunks.  */

  /* We're going to generate code for fn, so it is no longer "abstract."  */
  /* APPLE LOCAL begin fix -gused debug info (radar 3271957 3262497) */
  /* Leave 'abstract' bit set for unified constructs and destructors when 
     -gused is used.  */
  if (!(flag_debug_only_used_symbols
	&& DECL_DESTRUCTOR_P (fn)
	&& DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
      && !(flag_debug_only_used_symbols
	   && DECL_CONSTRUCTOR_P (fn)
	   && DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
      )
    DECL_ABSTRACT (fn) = 0;
  /* APPLE LOCAL end */

  /* Find the vtt_parm, if present.  */
  for (vtt_parmno = -1, parmno = 0, fn_parm = DECL_ARGUMENTS (fn);
       fn_parm;
       ++parmno, fn_parm = TREE_CHAIN (fn_parm))
    {
      if (DECL_ARTIFICIAL (fn_parm) && DECL_NAME (fn_parm) == vtt_parm_identifier)
	{
	  vtt_parmno = parmno;	/* Compensate for removed in_charge parameter.  */
	  break;
	}
    }

  /* We know that any clones immediately follow FN in the TYPE_METHODS
     list.  */
  for (clone = start = TREE_CHAIN (fn);
       clone && DECL_CLONED_FUNCTION_P (clone);
       clone = TREE_CHAIN (clone))
    {
      tree clone_parm, parmlist;

      /* If the clone and original parmlists are identical, turn the clone into an alias.  */
      if (maybe_alias_body (fn, clone))
	continue;

      /* If we've already generated a body for this clone, avoid duplicating it.
	 (Is it possible for a clone-list to grow after we first see it?)  */
      if (DECL_SAVED_TREE (clone) || TREE_ASM_WRITTEN (clone))
	continue;

      /* Start processing the function.  */
      push_to_top_level ();
      start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);

      /* Walk parameter lists together, creating parameter list for call to original function.  */
      for (parmno = 0,
	     parmlist = NULL,
	     fn_parm = DECL_ARGUMENTS (fn),
	     fn_parm_typelist = TYPE_ARG_TYPES (TREE_TYPE (fn)),
	     clone_parm = DECL_ARGUMENTS (clone);
	   fn_parm;
	   ++parmno,
	     fn_parm = TREE_CHAIN (fn_parm))
	{
	  if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
	    {
	      tree typed_null_pointer_node = copy_node (null_pointer_node);
	      gcc_assert (fn_parm_typelist);
	      /* Clobber actual parameter with formal parameter type.  */
	      TREE_TYPE (typed_null_pointer_node) = TREE_VALUE (fn_parm_typelist);
	      parmlist = tree_cons (NULL, typed_null_pointer_node, parmlist);
	    }
	  else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
	    {
	      tree in_charge = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
	      parmlist = tree_cons (NULL, in_charge, parmlist);
	    }
	  /* Map other parameters to their equivalents in the cloned
	     function.  */
	  else
	    {
	      gcc_assert (clone_parm);
	      DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
	      parmlist = tree_cons (NULL, clone_parm, parmlist);
	      clone_parm = TREE_CHAIN (clone_parm);
	    }
	  if (fn_parm_typelist)
	    fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
	}

      /* We built this list backwards; fix now.  */
      parmlist = nreverse (parmlist);
      mark_used (fn);
      call = build_function_call (fn, parmlist);
      expr_stmt = build_stmt (EXPR_STMT, call);
      add_stmt (expr_stmt);

      /* Now, expand this function into RTL, if appropriate.  */
      finish_function (0);
      DECL_ABSTRACT_ORIGIN (clone) = NULL;
      expand_body (clone);
      pop_from_top_level ();
    }
  return 1;
}
/* APPLE LOCAL end structor thunks */

/* FN is a function that has a complete body.  Clone the body as
   necessary.  Returns nonzero if there's no longer any need to
   process the main body.  */

bool
maybe_clone_body (tree fn)
{
  tree clone;
  bool first = true;

  /* We only clone constructors and destructors.  */
  if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
      && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
    return 0;

  /* Emit the DWARF1 abstract instance.  */
  (*debug_hooks->deferred_inline_function) (fn);

  /* We know that any clones immediately follow FN in the TYPE_METHODS
     list.  */
  push_to_top_level ();
  FOR_EACH_CLONE (clone, fn)
    {
      tree parm;
      tree clone_parm;
      /* APPLE LOCAL structor thunks */
      /* Delete some local variables.  */

      /* Update CLONE's source position information to match FN's.  */
      DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
      DECL_INLINE (clone) = DECL_INLINE (fn);
      DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
      DECL_COMDAT (clone) = DECL_COMDAT (fn);
      DECL_WEAK (clone) = DECL_WEAK (fn);
      DECL_ONE_ONLY (clone) = DECL_ONE_ONLY (fn);
      DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn);
      DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
      DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
      DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
      DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
      TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
      DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
      DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);

      /* Adjust the parameter names and locations.  */
      parm = DECL_ARGUMENTS (fn);
      clone_parm = DECL_ARGUMENTS (clone);
      /* Update the `this' parameter, which is always first.  */
      update_cloned_parm (parm, clone_parm, first);
      parm = TREE_CHAIN (parm);
      clone_parm = TREE_CHAIN (clone_parm);
      if (DECL_HAS_IN_CHARGE_PARM_P (fn))
	parm = TREE_CHAIN (parm);
      if (DECL_HAS_VTT_PARM_P (fn))
	parm = TREE_CHAIN (parm);
      if (DECL_HAS_VTT_PARM_P (clone))
	clone_parm = TREE_CHAIN (clone_parm);
      for (; parm;
	   parm = TREE_CHAIN (parm), clone_parm = TREE_CHAIN (clone_parm))
	/* Update this parameter.  */
	update_cloned_parm (parm, clone_parm, first);
      /* APPLE LOCAL structor thunks */
    }

  /* APPLE LOCAL begin structor thunks */
  /* If we decide to turn clones into thunks, they will branch to fn.
     Must have original function available to call.  */
  if (maybe_thunk_body (fn))
    return 0;
  /* APPLE LOCAL end structor thunks */

  /* APPLE LOCAL begin structor thunks */
  /* We know that any clones immediately follow FN in the TYPE_METHODS
     list.  */
  for (clone = TREE_CHAIN (fn);
       clone && DECL_CLONED_FUNCTION_P (clone);
       clone = TREE_CHAIN (clone))
    {
      tree parm;
      tree clone_parm;
      int parmno;
      splay_tree decl_map;
   /* APPLE LOCAL end structor thunks */

      /* Start processing the function.  */
      start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);

      /* Remap the parameters.  */
      decl_map = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
      for (parmno = 0,
	     parm = DECL_ARGUMENTS (fn),
	     clone_parm = DECL_ARGUMENTS (clone);
	   parm;
	   ++parmno,
	     parm = TREE_CHAIN (parm))
	{
	  /* Map the in-charge parameter to an appropriate constant.  */
	  if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
	    {
	      tree in_charge;
	      in_charge = in_charge_arg_for_name (DECL_NAME (clone));
	      splay_tree_insert (decl_map,
				 (splay_tree_key) parm,
				 (splay_tree_value) in_charge);
	    }
	  else if (DECL_ARTIFICIAL (parm)
		   && DECL_NAME (parm) == vtt_parm_identifier)
	    {
	      /* For a subobject constructor or destructor, the next
		 argument is the VTT parameter.  Remap the VTT_PARM
		 from the CLONE to this parameter.  */
	      if (DECL_HAS_VTT_PARM_P (clone))
		{
		  DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
		  splay_tree_insert (decl_map,
				     (splay_tree_key) parm,
				     (splay_tree_value) clone_parm);
		  clone_parm = TREE_CHAIN (clone_parm);
		}
	      /* Otherwise, map the VTT parameter to `NULL'.  */
	      else
		{
		  splay_tree_insert (decl_map,
				     (splay_tree_key) parm,
				     (splay_tree_value) null_pointer_node);
		}
	    }
	  /* Map other parameters to their equivalents in the cloned
	     function.  */
	  else
	    {
	      splay_tree_insert (decl_map,
				 (splay_tree_key) parm,
				 (splay_tree_value) clone_parm);
	      clone_parm = TREE_CHAIN (clone_parm);
	    }
	}

      if (targetm.cxx.cdtor_returns_this ())
	{
	  parm = DECL_RESULT (fn);
	  clone_parm = DECL_RESULT (clone);
	  splay_tree_insert (decl_map, (splay_tree_key) parm,
			     (splay_tree_value) clone_parm);
	}
      /* Clone the body.  */
      clone_body (clone, fn, decl_map);

      /* Clean up.  */
      splay_tree_delete (decl_map);

      /* The clone can throw iff the original function can throw.  */
      cp_function_chain->can_throw = !TREE_NOTHROW (fn);

      /* Now, expand this function into RTL, if appropriate.  */
      finish_function (0);
      BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
      expand_or_defer_fn (clone);
      first = false;
    }
  pop_from_top_level ();

  /* We don't need to process the original function any further.  */
  return 1;
}
