/* Generic sibling call optimization support
   Copyright (C) 1999, 2000, 2001, 2002, 2003
   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 "rtl.h"
#include "regs.h"
#include "function.h"
#include "hard-reg-set.h"
#include "flags.h"
#include "insn-config.h"
#include "recog.h"
#include "basic-block.h"
#include "output.h"
#include "except.h"
#include "tree.h"

/* In case alternate_exit_block contains copy from pseudo, to return value,
   record the pseudo here.  In such case the pseudo must be set to function
   return in the sibcall sequence.  */
static rtx return_value_pseudo;

static int identify_call_return_value (rtx, rtx *, rtx *);
static rtx skip_copy_to_return_value (rtx);
static rtx skip_use_of_return_value (rtx, enum rtx_code);
static rtx skip_stack_adjustment (rtx);
static rtx skip_pic_restore (rtx);
static rtx skip_jump_insn (rtx);
static int call_ends_block_p (rtx, rtx);
static int uses_addressof (rtx);
static int sequence_uses_addressof (rtx);
static void purge_reg_equiv_notes (void);
static void purge_mem_unchanging_flag (rtx);
static rtx skip_unreturned_value (rtx);

/* Examine a CALL_PLACEHOLDER pattern and determine where the call's
   return value is located.  P_HARD_RETURN receives the hard register
   that the function used; P_SOFT_RETURN receives the pseudo register
   that the sequence used.  Return nonzero if the values were located.  */

static int
identify_call_return_value (rtx cp, rtx *p_hard_return, rtx *p_soft_return)
{
  rtx insn, set, hard, soft;

  insn = XEXP (cp, 0);
  /* Search backward through the "normal" call sequence to the CALL insn.  */
  while (NEXT_INSN (insn))
    insn = NEXT_INSN (insn);
  while (GET_CODE (insn) != CALL_INSN)
    insn = PREV_INSN (insn);

  /* Assume the pattern is (set (dest) (call ...)), or that the first
     member of a parallel is.  This is the hard return register used
     by the function.  */
  if (GET_CODE (PATTERN (insn)) == SET
      && GET_CODE (SET_SRC (PATTERN (insn))) == CALL)
    hard = SET_DEST (PATTERN (insn));
  else if (GET_CODE (PATTERN (insn)) == PARALLEL
	   && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET
	   && GET_CODE (SET_SRC (XVECEXP (PATTERN (insn), 0, 0))) == CALL)
    hard = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
  else
    return 0;

  /* If we didn't get a single hard register (e.g. a parallel), give up.  */
  if (GET_CODE (hard) != REG)
    return 0;

  /* Stack adjustment done after call may appear here.  */
  insn = skip_stack_adjustment (insn);
  if (! insn)
    return 0;

  /* Restore of GP register may appear here.  */
  insn = skip_pic_restore (insn);
  if (! insn)
    return 0;

  /* If there's nothing after, there's no soft return value.  */
  insn = NEXT_INSN (insn);
  if (! insn)
    return 0;

  /* We're looking for a source of the hard return register.  */
  set = single_set (insn);
  if (! set || SET_SRC (set) != hard)
    return 0;

  soft = SET_DEST (set);
  insn = NEXT_INSN (insn);

  /* Allow this first destination to be copied to a second register,
     as might happen if the first register wasn't the particular pseudo
     we'd been expecting.  */
  if (insn
      && (set = single_set (insn)) != NULL_RTX
      && SET_SRC (set) == soft)
    {
      soft = SET_DEST (set);
      insn = NEXT_INSN (insn);
    }

  /* Don't fool with anything but pseudo registers.  */
  if (GET_CODE (soft) != REG || REGNO (soft) < FIRST_PSEUDO_REGISTER)
    return 0;

  /* This value must not be modified before the end of the sequence.  */
  if (reg_set_between_p (soft, insn, NULL_RTX))
    return 0;

  *p_hard_return = hard;
  *p_soft_return = soft;

  return 1;
}

/* If the first real insn after ORIG_INSN copies to this function's
   return value from RETVAL, then return the insn which performs the
   copy.  Otherwise return ORIG_INSN.  */

static rtx
skip_copy_to_return_value (rtx orig_insn)
{
  rtx insn, set = NULL_RTX;
  rtx hardret, softret;

  /* If there is no return value, we have nothing to do.  */
  if (! identify_call_return_value (PATTERN (orig_insn), &hardret, &softret))
    return orig_insn;

  insn = next_nonnote_insn (orig_insn);
  if (! insn)
    return orig_insn;

  set = single_set (insn);
  if (! set)
    return orig_insn;

  if (return_value_pseudo)
    {
      if (SET_DEST (set) == return_value_pseudo
	  && SET_SRC (set) == softret)
	return insn;
      return orig_insn;
    }

  /* The destination must be the same as the called function's return
     value to ensure that any return value is put in the same place by the
     current function and the function we're calling.

     Further, the source must be the same as the pseudo into which the
     called function's return value was copied.  Otherwise we're returning
     some other value.  */

#ifndef OUTGOING_REGNO
#define OUTGOING_REGNO(N) (N)
#endif

  if (SET_DEST (set) == current_function_return_rtx
      && REG_P (SET_DEST (set))
      && OUTGOING_REGNO (REGNO (SET_DEST (set))) == REGNO (hardret)
      && SET_SRC (set) == softret)
    return insn;

  /* Recognize the situation when the called function's return value
     is copied in two steps: first into an intermediate pseudo, then
     the into the calling functions return value register.  */

  if (REG_P (SET_DEST (set))
      && SET_SRC (set) == softret)
    {
      rtx x = SET_DEST (set);

      insn = next_nonnote_insn (insn);
      if (! insn)
	return orig_insn;

      set = single_set (insn);
      if (! set)
	return orig_insn;

      if (SET_DEST (set) == current_function_return_rtx
	  && REG_P (SET_DEST (set))
	  && OUTGOING_REGNO (REGNO (SET_DEST (set))) == REGNO (hardret)
	  && SET_SRC (set) == x)
	return insn;
    }

  /* It did not look like a copy of the return value, so return the
     same insn we were passed.  */
  return orig_insn;
}

/* If the first real insn after ORIG_INSN is a CODE of this function's return
   value, return insn.  Otherwise return ORIG_INSN.  */

static rtx
skip_use_of_return_value (rtx orig_insn, enum rtx_code code)
{
  rtx insn;

  insn = next_nonnote_insn (orig_insn);

  if (insn
      && GET_CODE (insn) == INSN
      && GET_CODE (PATTERN (insn)) == code
      && (XEXP (PATTERN (insn), 0) == current_function_return_rtx
	  || XEXP (PATTERN (insn), 0) == const0_rtx))
    return insn;

  return orig_insn;
}

/* In case function does not return value,  we get clobber of pseudo followed
   by set to hard return value.  */
static rtx
skip_unreturned_value (rtx orig_insn)
{
  rtx insn = next_nonnote_insn (orig_insn);

  /* Skip possible clobber of pseudo return register.  */
  if (insn
      && GET_CODE (insn) == INSN
      && GET_CODE (PATTERN (insn)) == CLOBBER
      && REG_P (XEXP (PATTERN (insn), 0))
      && (REGNO (XEXP (PATTERN (insn), 0)) >= FIRST_PSEUDO_REGISTER))
    {
      rtx set_insn = next_nonnote_insn (insn);
      rtx set;
      if (!set_insn)
	return insn;
      set = single_set (set_insn);
      if (!set
	  || SET_SRC (set) != XEXP (PATTERN (insn), 0)
	  || SET_DEST (set) != current_function_return_rtx)
	return insn;
      return set_insn;
    }
  return orig_insn;
}

/* If the first real insn after ORIG_INSN adjusts the stack pointer
   by a constant, return the insn with the stack pointer adjustment.
   Otherwise return ORIG_INSN.  */

static rtx
skip_stack_adjustment (rtx orig_insn)
{
  rtx insn, set = NULL_RTX;

  insn = next_nonnote_insn (orig_insn);

  if (insn)
    set = single_set (insn);

  if (insn
      && set
      && GET_CODE (SET_SRC (set)) == PLUS
      && XEXP (SET_SRC (set), 0) == stack_pointer_rtx
      && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT
      && SET_DEST (set) == stack_pointer_rtx)
    return insn;

  return orig_insn;
}

/* If the first real insn after ORIG_INSN sets the pic register,
   return it.  Otherwise return ORIG_INSN.  */

static rtx
skip_pic_restore (rtx orig_insn)
{
  rtx insn, set = NULL_RTX;

  insn = next_nonnote_insn (orig_insn);

  if (insn)
    set = single_set (insn);

  if (insn && set && SET_DEST (set) == pic_offset_table_rtx)
    return insn;

  return orig_insn;
}

/* If the first real insn after ORIG_INSN is a jump, return the JUMP_INSN.
   Otherwise return ORIG_INSN.  */

static rtx
skip_jump_insn (rtx orig_insn)
{
  rtx insn;

  insn = next_nonnote_insn (orig_insn);

  if (insn
      && GET_CODE (insn) == JUMP_INSN
      && any_uncondjump_p (insn))
    return insn;

  return orig_insn;
}

/* Using the above functions, see if INSN, skipping any of the above,
   goes all the way to END, the end of a basic block.  Return 1 if so.  */

static int
call_ends_block_p (rtx insn, rtx end)
{
  rtx new_insn;

  /* END might be a note, so get the last nonnote insn of the block.  */
  if (NOTE_P (end))
    end = prev_nonnote_insn (end);

  /* If the call was the end of the block, then we're OK.  */
  if (insn == end)
    return 1;

  /* Skip over copying from the call's return value pseudo into
     this function's hard return register and if that's the end
     of the block, we're OK.  */
  new_insn = skip_copy_to_return_value (insn);

  /* In case we return value in pseudo, we must set the pseudo to
     return value of called function, otherwise we are returning
     something else.  */
  if (return_value_pseudo && insn == new_insn)
    return 0;
  insn = new_insn;

  if (insn == end)
    return 1;

  /* Skip any stack adjustment.  */
  insn = skip_stack_adjustment (insn);
  if (insn == end)
    return 1;

  /* Skip over a CLOBBER of the return value as a hard reg.  */
  insn = skip_use_of_return_value (insn, CLOBBER);
  if (insn == end)
    return 1;

  /* Skip over a CLOBBER of the return value as a hard reg.  */
  insn = skip_unreturned_value (insn);
  if (insn == end)
    return 1;

  /* Skip over a USE of the return value (as a hard reg).  */
  insn = skip_use_of_return_value (insn, USE);
  if (insn == end)
    return 1;

  /* Skip over a JUMP_INSN at the end of the block.  If that doesn't end the
     block, the original CALL_INSN didn't.  */
  insn = skip_jump_insn (insn);
  return insn == end;
}

/* Scan the rtx X for ADDRESSOF expressions or
   current_function_internal_arg_pointer registers.
   Return nonzero if an ADDRESSOF or current_function_internal_arg_pointer
   is found outside of some MEM expression, else return zero.  */

static int
uses_addressof (rtx x)
{
  RTX_CODE code;
  int i, j;
  const char *fmt;

  if (x == NULL_RTX)
    return 0;

  code = GET_CODE (x);

  if (code == ADDRESSOF || x == current_function_internal_arg_pointer)
    return 1;

  if (code == MEM)
    return 0;

  /* Scan all subexpressions.  */
  fmt = GET_RTX_FORMAT (code);
  for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
    {
      if (*fmt == 'e')
	{
	  if (uses_addressof (XEXP (x, i)))
	    return 1;
	}
      else if (*fmt == 'E')
	{
	  for (j = 0; j < XVECLEN (x, i); j++)
	    if (uses_addressof (XVECEXP (x, i, j)))
	      return 1;
	}
    }
  return 0;
}

/* Scan the sequence of insns in SEQ to see if any have an ADDRESSOF
   rtl expression or current_function_internal_arg_pointer occurrences
   not enclosed within a MEM.  If an ADDRESSOF expression or
   current_function_internal_arg_pointer is found, return nonzero, otherwise
   return zero.

   This function handles CALL_PLACEHOLDERs which contain multiple sequences
   of insns.  */

static int
sequence_uses_addressof (rtx seq)
{
  rtx insn;

  for (insn = seq; insn; insn = NEXT_INSN (insn))
    if (INSN_P (insn))
      {
	/* If this is a CALL_PLACEHOLDER, then recursively call ourselves
	   with each nonempty sequence attached to the CALL_PLACEHOLDER.  */
	if (GET_CODE (insn) == CALL_INSN
	    && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
	  {
	    if (XEXP (PATTERN (insn), 0) != NULL_RTX
		&& sequence_uses_addressof (XEXP (PATTERN (insn), 0)))
	      return 1;
	    if (XEXP (PATTERN (insn), 1) != NULL_RTX
		&& sequence_uses_addressof (XEXP (PATTERN (insn), 1)))
	      return 1;
	    if (XEXP (PATTERN (insn), 2) != NULL_RTX
		&& sequence_uses_addressof (XEXP (PATTERN (insn), 2)))
	      return 1;
	  }
	else if (uses_addressof (PATTERN (insn))
		 || (REG_NOTES (insn) && uses_addressof (REG_NOTES (insn))))
	  return 1;
      }
  return 0;
}

/* Remove all REG_EQUIV notes found in the insn chain.  */

static void
purge_reg_equiv_notes (void)
{
  rtx insn;

  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    {
      while (1)
	{
	  rtx note = find_reg_note (insn, REG_EQUIV, 0);
	  if (note)
	    {
	      /* Remove the note and keep looking at the notes for
		 this insn.  */
	      remove_note (insn, note);
	      continue;
	    }
	  break;
	}
    }
}

/* Clear RTX_UNCHANGING_P flag of incoming argument MEMs.  */

static void
purge_mem_unchanging_flag (rtx x)
{
  RTX_CODE code;
  int i, j;
  const char *fmt;

  if (x == NULL_RTX)
    return;

  code = GET_CODE (x);

  if (code == MEM)
    {
      if (RTX_UNCHANGING_P (x)
	  && (XEXP (x, 0) == current_function_internal_arg_pointer
	      || (GET_CODE (XEXP (x, 0)) == PLUS
		  && XEXP (XEXP (x, 0), 0) ==
		     current_function_internal_arg_pointer
		  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)))
	RTX_UNCHANGING_P (x) = 0;
      return;
    }

  /* Scan all subexpressions.  */
  fmt = GET_RTX_FORMAT (code);
  for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
    {
      if (*fmt == 'e')
	purge_mem_unchanging_flag (XEXP (x, i));
      else if (*fmt == 'E')
	for (j = 0; j < XVECLEN (x, i); j++)
	  purge_mem_unchanging_flag (XVECEXP (x, i, j));
    }
}

/* Replace the CALL_PLACEHOLDER with one of its children.  INSN should be
   the CALL_PLACEHOLDER insn; USE tells which child to use.  */

void
replace_call_placeholder (rtx insn, sibcall_use_t use)
{
  if (use == sibcall_use_tail_recursion)
    emit_insn_before (XEXP (PATTERN (insn), 2), insn);
  else if (use == sibcall_use_sibcall)
    emit_insn_before (XEXP (PATTERN (insn), 1), insn);
  else if (use == sibcall_use_normal)
    emit_insn_before (XEXP (PATTERN (insn), 0), insn);
  else
    abort ();

  /* Turn off LABEL_PRESERVE_P for the tail recursion label if it
     exists.  We only had to set it long enough to keep the jump
     pass above from deleting it as unused.  */
  if (XEXP (PATTERN (insn), 3))
    LABEL_PRESERVE_P (XEXP (PATTERN (insn), 3)) = 0;

  /* "Delete" the placeholder insn.  */
  remove_insn (insn);
}

/* Given a (possibly empty) set of potential sibling or tail recursion call
   sites, determine if optimization is possible.

   Potential sibling or tail recursion calls are marked with CALL_PLACEHOLDER
   insns.  The CALL_PLACEHOLDER insn holds chains of insns to implement a
   normal call, sibling call or tail recursive call.

   Replace the CALL_PLACEHOLDER with an appropriate insn chain.  */

void
optimize_sibling_and_tail_recursive_calls (void)
{
  rtx insn, insns;
  basic_block alternate_exit = EXIT_BLOCK_PTR;
  bool no_sibcalls_this_function = false;
  bool successful_replacement = false;
  bool replaced_call_placeholder = false;
  edge e;

  insns = get_insns ();

  cleanup_cfg (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP);

  /* If there are no basic blocks, then there is nothing to do.  */
  if (n_basic_blocks == 0)
    return;

  /* If we are using sjlj exceptions, we may need to add a call to
     _Unwind_SjLj_Unregister at exit of the function.  Which means
     that we cannot do any sibcall transformations.  */
  if (USING_SJLJ_EXCEPTIONS && current_function_has_exception_handlers ())
    no_sibcalls_this_function = true;

  return_value_pseudo = NULL_RTX;

  /* Find the exit block.

     It is possible that we have blocks which can reach the exit block
     directly.  However, most of the time a block will jump (or fall into)
     N_BASIC_BLOCKS - 1, which in turn falls into the exit block.  */
  for (e = EXIT_BLOCK_PTR->pred;
       e && alternate_exit == EXIT_BLOCK_PTR;
       e = e->pred_next)
    {
      rtx insn;

      if (e->dest != EXIT_BLOCK_PTR || e->succ_next != NULL)
	continue;

      /* Walk forwards through the last normal block and see if it
	 does nothing except fall into the exit block.  */
      for (insn = BB_HEAD (EXIT_BLOCK_PTR->prev_bb);
	   insn;
	   insn = NEXT_INSN (insn))
	{
	  rtx set;
	  /* This should only happen once, at the start of this block.  */
	  if (GET_CODE (insn) == CODE_LABEL)
	    continue;

	  if (GET_CODE (insn) == NOTE)
	    continue;

	  if (GET_CODE (insn) == INSN
	      && GET_CODE (PATTERN (insn)) == USE)
	    continue;

	  /* Exit block also may contain copy from pseudo containing
	     return value to hard register.  */
	  if (GET_CODE (insn) == INSN
	      && (set = single_set (insn))
	      && SET_DEST (set) == current_function_return_rtx
	      && REG_P (SET_SRC (set))
	      && !return_value_pseudo)
	    {
	      return_value_pseudo = SET_SRC (set);
	      continue;
	    }

	  break;
	}

      /* If INSN is zero, then the search walked all the way through the
	 block without hitting anything interesting.  This block is a
	 valid alternate exit block.  */
      if (insn == NULL)
	alternate_exit = e->src;
      else
	return_value_pseudo = NULL;
    }

  /* If the function uses ADDRESSOF, we can't (easily) determine
     at this point if the value will end up on the stack.  */
  no_sibcalls_this_function |= sequence_uses_addressof (insns);

  /* Walk the insn chain and find any CALL_PLACEHOLDER insns.  We need to
     select one of the insn sequences attached to each CALL_PLACEHOLDER.

     The different sequences represent different ways to implement the call,
     ie, tail recursion, sibling call or normal call.

     Since we do not create nested CALL_PLACEHOLDERs, the scan
     continues with the insn that was after a replaced CALL_PLACEHOLDER;
     we don't rescan the replacement insns.  */
  for (insn = insns; insn; insn = NEXT_INSN (insn))
    {
      if (GET_CODE (insn) == CALL_INSN
	  && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
	{
	  int sibcall = (XEXP (PATTERN (insn), 1) != NULL_RTX);
	  int tailrecursion = (XEXP (PATTERN (insn), 2) != NULL_RTX);
	  basic_block call_block = BLOCK_FOR_INSN (insn);

	  /* alloca (until we have stack slot life analysis) inhibits
	     sibling call optimizations, but not tail recursion.
	     Similarly if we use varargs or stdarg since they implicitly
	     may take the address of an argument.  */
	  if (current_function_calls_alloca || current_function_stdarg)
	    sibcall = 0;

	  /* See if there are any reasons we can't perform either sibling or
	     tail call optimizations.  We must be careful with stack slots
	     which are live at potential optimization sites.  */
	  if (no_sibcalls_this_function
	      /* ??? Overly conservative.  */
	      || frame_offset
	      /* Any function that calls setjmp might have longjmp called from
		 any called function.  ??? We really should represent this
		 properly in the CFG so that this needn't be special cased.  */
	      || current_function_calls_setjmp
	      /* Can't if more than one successor or single successor is not
		 exit block.  These two tests prevent tail call optimization
		 in the presence of active exception handlers.  */
	      || call_block->succ == NULL
	      || call_block->succ->succ_next != NULL
	      || (call_block->succ->dest != EXIT_BLOCK_PTR
		  && call_block->succ->dest != alternate_exit)
	      /* If this call doesn't end the block, there are operations at
		 the end of the block which we must execute after returning.  */
	      || ! call_ends_block_p (insn, BB_END (call_block)))
	    sibcall = 0, tailrecursion = 0;

	  /* Select a set of insns to implement the call and emit them.
	     Tail recursion is the most efficient, so select it over
	     a tail/sibling call.  */

	  if (sibcall || tailrecursion)
	    successful_replacement = true;
	  replaced_call_placeholder = true;

	  replace_call_placeholder (insn,
				    tailrecursion != 0
				      ? sibcall_use_tail_recursion
				      : sibcall != 0
					 ? sibcall_use_sibcall
					 : sibcall_use_normal);
	}
    }

  if (successful_replacement)
    {
      rtx insn;
      tree arg;

      /* A sibling call sequence invalidates any REG_EQUIV notes made for
	 this function's incoming arguments.

	 At the start of RTL generation we know the only REG_EQUIV notes
	 in the rtl chain are those for incoming arguments, so we can safely
	 flush any REG_EQUIV note.

	 This is (slight) overkill.  We could keep track of the highest
	 argument we clobber and be more selective in removing notes, but it
	 does not seem to be worth the effort.  */
      purge_reg_equiv_notes ();

      /* A sibling call sequence also may invalidate RTX_UNCHANGING_P
	 flag of some incoming arguments MEM RTLs, because it can write into
	 those slots.  We clear all those bits now.

	 This is (slight) overkill, we could keep track of which arguments
	 we actually write into.  */
      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
	{
	  if (INSN_P (insn))
	    purge_mem_unchanging_flag (PATTERN (insn));
	}

      /* Similarly, invalidate RTX_UNCHANGING_P for any incoming
	 arguments passed in registers.  */
      for (arg = DECL_ARGUMENTS (current_function_decl);
	   arg;
	   arg = TREE_CHAIN (arg))
	{
	  if (REG_P (DECL_RTL (arg)))
	    RTX_UNCHANGING_P (DECL_RTL (arg)) = false;
	}
    }

  /* There may have been NOTE_INSN_BLOCK_{BEGIN,END} notes in the
     CALL_PLACEHOLDER alternatives that we didn't emit.  Rebuild the
     lexical block tree to correspond to the notes that still exist.  */
  if (replaced_call_placeholder)
    reorder_blocks ();

  /* This information will be invalid after inline expansion.  Kill it now.  */
  free_basic_block_vars (0);
  free_EXPR_LIST_list (&tail_recursion_label_list);
}
