/* Combine stack adjustments.
   Copyright (C) 1987-2022 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 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/>.  */

/* Track stack adjustments and stack memory references.  Attempt to
   reduce the number of stack adjustments by back-propagating across
   the memory references.

   This is intended primarily for use with targets that do not define
   ACCUMULATE_OUTGOING_ARGS.  It is of significantly more value to
   targets that define PREFERRED_STACK_BOUNDARY more aligned than
   STACK_BOUNDARY (e.g. x86), or if not all registers can be pushed
   (e.g. x86 fp regs) which would ordinarily have to be implemented
   as a sub/mov pair due to restrictions in calls.cc.

   Propagation stops when any of the insns that need adjusting are
   (a) no longer valid because we've exceeded their range, (b) a
   non-trivial push instruction, or (c) a call instruction.

   Restriction B is based on the assumption that push instructions
   are smaller or faster.  If a port really wants to remove all
   pushes, it should have defined ACCUMULATE_OUTGOING_ARGS.  The
   one exception that is made is for an add immediately followed
   by a push.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "df.h"
#include "insn-config.h"
#include "memmodel.h"
#include "emit-rtl.h"
#include "recog.h"
#include "cfgrtl.h"
#include "tree-pass.h"
#include "rtl-iter.h"


/* This structure records two kinds of stack references between stack
   adjusting instructions: stack references in memory addresses for
   regular insns and all stack references for debug insns.  */

struct csa_reflist
{
  HOST_WIDE_INT sp_offset;
  rtx_insn *insn;
  rtx *ref;
  struct csa_reflist *next;
};

static int stack_memref_p (rtx);
static rtx single_set_for_csa (rtx_insn *);
static void free_csa_reflist (struct csa_reflist *);
static struct csa_reflist *record_one_stack_ref (rtx_insn *, rtx *,
						 struct csa_reflist *);
static bool try_apply_stack_adjustment (rtx_insn *, struct csa_reflist *,
					HOST_WIDE_INT, HOST_WIDE_INT,
					bitmap, rtx_insn *);
static void combine_stack_adjustments_for_block (basic_block, bitmap);


/* Main entry point for stack adjustment combination.  */

static void
combine_stack_adjustments (void)
{
  basic_block bb;
  bitmap live = BITMAP_ALLOC (&reg_obstack);

  FOR_EACH_BB_FN (bb, cfun)
    combine_stack_adjustments_for_block (bb, live);

  BITMAP_FREE (live);
}

/* Recognize a MEM of the form (sp) or (plus sp const).  */

static int
stack_memref_p (rtx x)
{
  if (!MEM_P (x))
    return 0;
  x = XEXP (x, 0);

  if (x == stack_pointer_rtx)
    return 1;
  if (GET_CODE (x) == PLUS
      && XEXP (x, 0) == stack_pointer_rtx
      && CONST_INT_P (XEXP (x, 1)))
    return 1;

  return 0;
}

/* Recognize either normal single_set or the hack in i386.md for
   tying fp and sp adjustments.  */

static rtx
single_set_for_csa (rtx_insn *insn)
{
  int i;
  rtx tmp = single_set (insn);
  if (tmp)
    return tmp;

  if (!NONJUMP_INSN_P (insn)
      || GET_CODE (PATTERN (insn)) != PARALLEL)
    return NULL_RTX;

  tmp = PATTERN (insn);
  if (GET_CODE (XVECEXP (tmp, 0, 0)) != SET)
    return NULL_RTX;

  for (i = 1; i < XVECLEN (tmp, 0); ++i)
    {
      rtx this_rtx = XVECEXP (tmp, 0, i);

      /* The special case is allowing a no-op set.  */
      if (GET_CODE (this_rtx) == SET
	  && SET_SRC (this_rtx) == SET_DEST (this_rtx))
	;
      else if (GET_CODE (this_rtx) != CLOBBER
	       && GET_CODE (this_rtx) != USE)
	return NULL_RTX;
    }

  return XVECEXP (tmp, 0, 0);
}

/* Free the list of csa_reflist nodes.  */

static void
free_csa_reflist (struct csa_reflist *reflist)
{
  struct csa_reflist *next;
  for (; reflist ; reflist = next)
    {
      next = reflist->next;
      free (reflist);
    }
}

/* Create a new csa_reflist node from the given stack reference.
   It is already known that the reference is either a MEM satisfying the
   predicate stack_memref_p or a REG representing the stack pointer.  */

static struct csa_reflist *
record_one_stack_ref (rtx_insn *insn, rtx *ref, struct csa_reflist *next_reflist)
{
  struct csa_reflist *ml;

  ml = XNEW (struct csa_reflist);

  if (REG_P (*ref) || XEXP (*ref, 0) == stack_pointer_rtx)
    ml->sp_offset = 0;
  else
    ml->sp_offset = INTVAL (XEXP (XEXP (*ref, 0), 1));

  ml->insn = insn;
  ml->ref = ref;
  ml->next = next_reflist;

  return ml;
}

/* We only know how to adjust the CFA; no other frame-related changes
   may appear in any insn to be deleted.  */

static bool
no_unhandled_cfa (rtx_insn *insn)
{
  if (!RTX_FRAME_RELATED_P (insn))
    return true;

  /* No CFA notes at all is a legacy interpretation like
     FRAME_RELATED_EXPR, and is context sensitive within
     the prologue state machine.  We can't handle that here.  */
  bool has_cfa_adjust = false;

  for (rtx link = REG_NOTES (insn); link; link = XEXP (link, 1))
    switch (REG_NOTE_KIND (link))
      {
      default:
        break;
      case REG_CFA_ADJUST_CFA:
	has_cfa_adjust = true;
	break;

      case REG_FRAME_RELATED_EXPR:
      case REG_CFA_DEF_CFA:
      case REG_CFA_OFFSET:
      case REG_CFA_REGISTER:
      case REG_CFA_EXPRESSION:
      case REG_CFA_RESTORE:
      case REG_CFA_SET_VDRAP:
      case REG_CFA_WINDOW_SAVE:
      case REG_CFA_FLUSH_QUEUE:
      case REG_CFA_TOGGLE_RA_MANGLE:
	return false;
      }

  return has_cfa_adjust;
}

/* Attempt to apply ADJUST to the stack adjusting insn INSN, as well
   as each of the memories and stack references in REFLIST.  Return true
   on success.  */

static bool
try_apply_stack_adjustment (rtx_insn *insn, struct csa_reflist *reflist,
			    HOST_WIDE_INT new_adjust, HOST_WIDE_INT delta,
			    bitmap live, rtx_insn *other_insn)
{
  struct csa_reflist *ml;
  rtx set;
  bool remove_equal = false;

  set = single_set_for_csa (insn);
  if (MEM_P (SET_DEST (set)))
    validate_change (insn, &SET_DEST (set),
		     replace_equiv_address (SET_DEST (set), stack_pointer_rtx),
		     1);
  else if (REG_P (SET_SRC (set)))
    {
      if (other_insn == NULL_RTX || live == NULL)
	return false;
      rtx other_set = single_set_for_csa (other_insn);
      if (SET_DEST (other_set) != stack_pointer_rtx
	  || GET_CODE (SET_SRC (other_set)) != PLUS
	  || XEXP (SET_SRC (other_set), 0) != stack_pointer_rtx
	  || !CONST_INT_P (XEXP (SET_SRC (other_set), 1)))
	return false;
      if (PATTERN (other_insn) != other_set)
	{
	  if (GET_CODE (PATTERN (other_insn)) != PARALLEL)
	    return false;
	  int i;
	  rtx p = PATTERN (other_insn);
	  for (i = 0; i < XVECLEN (p, 0); ++i)
	    {
	      rtx this_rtx = XVECEXP (p, 0, i);
	      if (this_rtx == other_set)
		continue;
	      if (GET_CODE (this_rtx) != CLOBBER)
		return false;
	      if (!REG_P (XEXP (this_rtx, 0))
		  || !HARD_REGISTER_P (XEXP (this_rtx, 0)))
		return false;
	      unsigned int end_regno = END_REGNO (XEXP (this_rtx, 0));
	      for (unsigned int regno = REGNO (XEXP (this_rtx, 0));
		   regno < end_regno; ++regno)
		if (bitmap_bit_p (live, regno))
		  return false;
	    }
	}
      validate_change (insn, &PATTERN (insn), copy_rtx (PATTERN (other_insn)),
		       1);
      set = single_set_for_csa (insn);
      validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (new_adjust),
		       1);
      remove_equal = true;
    }
  else
    validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (new_adjust), 1);

  for (ml = reflist; ml ; ml = ml->next)
    {
      rtx new_addr = plus_constant (Pmode, stack_pointer_rtx,
				    ml->sp_offset - delta);
      rtx new_val;

      if (MEM_P (*ml->ref))
	new_val = replace_equiv_address_nv (*ml->ref, new_addr);
      else if (GET_MODE (*ml->ref) == GET_MODE (stack_pointer_rtx))
	new_val = new_addr;
      else
	new_val = lowpart_subreg (GET_MODE (*ml->ref), new_addr,
				  GET_MODE (new_addr));
      validate_change (ml->insn, ml->ref, new_val, 1);
    }

  if (apply_change_group ())
    {
      /* Succeeded.  Update our knowledge of the stack references.  */
      for (ml = reflist; ml ; ml = ml->next)
	ml->sp_offset -= delta;

      if (remove_equal)
	remove_reg_equal_equiv_notes (insn);
      return true;
    }
  else
    return false;
}

/* For non-debug insns, record all stack memory references in INSN
   and return true if there were no other (unrecorded) references to the
   stack pointer.  For debug insns, record all stack references regardless
   of context and unconditionally return true.  */

static bool
record_stack_refs (rtx_insn *insn, struct csa_reflist **reflist)
{
  subrtx_ptr_iterator::array_type array;
  FOR_EACH_SUBRTX_PTR (iter, array, &PATTERN (insn), NONCONST)
    {
      rtx *loc = *iter;
      rtx x = *loc;
      switch (GET_CODE (x))
	{
	case MEM:
	  if (!reg_mentioned_p (stack_pointer_rtx, x))
	    iter.skip_subrtxes ();
	  /* We are not able to handle correctly all possible memrefs
	     containing stack pointer, so this check is necessary.  */
	  else if (stack_memref_p (x))
	    {
	      *reflist = record_one_stack_ref (insn, loc, *reflist);
	      iter.skip_subrtxes ();
	    }
	  /* Try harder for DEBUG_INSNs, handle e.g.
	     (mem (mem (sp + 16) + 4).  */
	  else if (!DEBUG_INSN_P (insn))
	    return false;
	  break;

	case REG:
	  /* ??? We want be able to handle non-memory stack pointer
	     references later.  For now just discard all insns referring to
	     stack pointer outside mem expressions.  We would probably
	     want to teach validate_replace to simplify expressions first.

	     We can't just compare with STACK_POINTER_RTX because the
	     reference to the stack pointer might be in some other mode.
	     In particular, an explicit clobber in an asm statement will
	     result in a QImode clobber.

	     In DEBUG_INSNs, we want to replace all occurrences, otherwise
	     they will cause -fcompare-debug failures.  */
	  if (REGNO (x) == STACK_POINTER_REGNUM)
	    {
	      if (!DEBUG_INSN_P (insn))
		return false;
	      *reflist = record_one_stack_ref (insn, loc, *reflist);
	    }
	  break;

	default:
	  break;
	}
    }
  return true;
}

/* If INSN has a REG_ARGS_SIZE note, move it to LAST.
   AFTER is true iff LAST follows INSN in the instruction stream.  */

static void
maybe_move_args_size_note (rtx_insn *last, rtx_insn *insn, bool after)
{
  rtx note, last_note;

  note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
  if (note == NULL)
    return;

  last_note = find_reg_note (last, REG_ARGS_SIZE, NULL_RTX);
  if (last_note)
    {
      /* The ARGS_SIZE notes are *not* cumulative.  They represent an
	 absolute value, and the "most recent" note wins.  */
      if (!after)
        XEXP (last_note, 0) = XEXP (note, 0);
    }
  else
    add_reg_note (last, REG_ARGS_SIZE, XEXP (note, 0));
}

/* Merge any REG_CFA_ADJUST_CFA note from SRC into DST.
   AFTER is true iff DST follows SRC in the instruction stream.  */

static void
maybe_merge_cfa_adjust (rtx_insn *dst, rtx_insn *src, bool after)
{
  rtx snote = NULL, dnote = NULL;
  rtx sexp, dexp;
  rtx exp1, exp2;

  if (RTX_FRAME_RELATED_P (src))
    snote = find_reg_note (src, REG_CFA_ADJUST_CFA, NULL_RTX);
  if (snote == NULL)
    return;
  sexp = XEXP (snote, 0);

  if (RTX_FRAME_RELATED_P (dst))
    dnote = find_reg_note (dst, REG_CFA_ADJUST_CFA, NULL_RTX);
  if (dnote == NULL)
    {
      add_reg_note (dst, REG_CFA_ADJUST_CFA, sexp);
      return;
    }
  dexp = XEXP (dnote, 0);

  gcc_assert (GET_CODE (sexp) == SET);
  gcc_assert (GET_CODE (dexp) == SET);

  if (after)
    exp1 = dexp, exp2 = sexp;
  else
    exp1 = sexp, exp2 = dexp;

  SET_SRC (exp1) = simplify_replace_rtx (SET_SRC (exp1), SET_DEST (exp2),
					 SET_SRC (exp2));
  XEXP (dnote, 0) = exp1;
}

/* Return the next (or previous) active insn within BB.  */

static rtx_insn *
prev_active_insn_bb (basic_block bb, rtx_insn *insn)
{
  for (insn = PREV_INSN (insn);
       insn != PREV_INSN (BB_HEAD (bb));
       insn = PREV_INSN (insn))
    if (active_insn_p (insn))
      return insn;
  return NULL;
}

static rtx_insn *
next_active_insn_bb (basic_block bb, rtx_insn *insn)
{
  for (insn = NEXT_INSN (insn);
       insn != NEXT_INSN (BB_END (bb));
       insn = NEXT_INSN (insn))
    if (active_insn_p (insn))
      return insn;
  return NULL;
}

/* If INSN has a REG_ARGS_SIZE note, if possible move it to PREV.  Otherwise
   search for a nearby candidate within BB where we can stick the note.  */

static void
force_move_args_size_note (basic_block bb, rtx_insn *prev, rtx_insn *insn)
{
  rtx note;
  rtx_insn *test, *next_candidate, *prev_candidate;

  /* If PREV exists, tail-call to the logic in the other function.  */
  if (prev)
    {
      maybe_move_args_size_note (prev, insn, false);
      return;
    }

  /* First, make sure there's anything that needs doing.  */
  note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
  if (note == NULL)
    return;

  /* We need to find a spot between the previous and next exception points
     where we can place the note and "properly" deallocate the arguments.  */
  next_candidate = prev_candidate = NULL;

  /* It is often the case that we have insns in the order:
	call
	add sp (previous deallocation)
	sub sp (align for next arglist)
	push arg
     and the add/sub cancel.  Therefore we begin by searching forward.  */

  test = insn;
  while ((test = next_active_insn_bb (bb, test)) != NULL)
    {
      /* Found an existing note: nothing to do.  */
      if (find_reg_note (test, REG_ARGS_SIZE, NULL_RTX))
        return;
      /* Found something that affects unwinding.  Stop searching.  */
      if (CALL_P (test) || !insn_nothrow_p (test))
	break;
      if (next_candidate == NULL)
	next_candidate = test;
    }

  test = insn;
  while ((test = prev_active_insn_bb (bb, test)) != NULL)
    {
      rtx tnote;
      /* Found a place that seems logical to adjust the stack.  */
      tnote = find_reg_note (test, REG_ARGS_SIZE, NULL_RTX);
      if (tnote)
	{
	  XEXP (tnote, 0) = XEXP (note, 0);
	  return;
	}
      if (prev_candidate == NULL)
	prev_candidate = test;
      /* Found something that affects unwinding.  Stop searching.  */
      if (CALL_P (test) || !insn_nothrow_p (test))
	break;
    }

  if (prev_candidate)
    test = prev_candidate;
  else if (next_candidate)
    test = next_candidate;
  else
    {
      /* ??? We *must* have a place, lest we ICE on the lost adjustment.
	 Options are: dummy clobber insn, nop, or prevent the removal of
	 the sp += 0 insn.  */
      /* TODO: Find another way to indicate to the dwarf2 code that we
	 have not in fact lost an adjustment.  */
      test = emit_insn_before (gen_rtx_CLOBBER (VOIDmode, const0_rtx), insn);
    }
  add_reg_note (test, REG_ARGS_SIZE, XEXP (note, 0));
}

/* Subroutine of combine_stack_adjustments, called for each basic block.  */

static void
combine_stack_adjustments_for_block (basic_block bb, bitmap live)
{
  HOST_WIDE_INT last_sp_adjust = 0;
  rtx_insn *last_sp_set = NULL;
  rtx_insn *last2_sp_set = NULL;
  bitmap last_sp_live = NULL;
  struct csa_reflist *reflist = NULL;
  bitmap copy = NULL;
  rtx_insn *insn, *next;
  rtx set;
  bool end_of_block = false;

  bitmap_copy (live, DF_LR_IN (bb));
  df_simulate_initialize_forwards (bb, live);

  for (insn = BB_HEAD (bb); !end_of_block ; insn = next)
    {
      end_of_block = insn == BB_END (bb);
      next = NEXT_INSN (insn);

      if (! INSN_P (insn))
	continue;

      set = single_set_for_csa (insn);
      if (set && find_reg_note (insn, REG_STACK_CHECK, NULL_RTX))
	set = NULL_RTX;
      if (set)
	{
	  rtx dest = SET_DEST (set);
	  rtx src = SET_SRC (set);
	  HOST_WIDE_INT this_adjust = 0;

	  /* Find constant additions to the stack pointer.  */
	  if (dest == stack_pointer_rtx
	      && GET_CODE (src) == PLUS
	      && XEXP (src, 0) == stack_pointer_rtx
	      && CONST_INT_P (XEXP (src, 1)))
	    this_adjust = INTVAL (XEXP (src, 1));
	  /* Or such additions turned by postreload into a store of
	     equivalent register.  */
	  else if (dest == stack_pointer_rtx
		   && REG_P (src)
		   && REGNO (src) != STACK_POINTER_REGNUM)
	    if (rtx equal = find_reg_note (insn, REG_EQUAL, NULL_RTX))
	      if (GET_CODE (XEXP (equal, 0)) == PLUS
		  && XEXP (XEXP (equal, 0), 0) == stack_pointer_rtx
		  && CONST_INT_P (XEXP (XEXP (equal, 0), 1)))
		this_adjust = INTVAL (XEXP (XEXP (equal, 0), 1));

	  if (this_adjust)
	    {
	      /* If we've not seen an adjustment previously, record
		 it now and continue.  */
	      if (! last_sp_set)
		{
		  last_sp_set = insn;
		  last_sp_adjust = this_adjust;
		  if (REG_P (src))
		    {
		      if (copy == NULL)
			copy = BITMAP_ALLOC (&reg_obstack);
		      last_sp_live = copy;
		      bitmap_copy (last_sp_live, live);
		    }
		  else
		    last_sp_live = NULL;
		  df_simulate_one_insn_forwards (bb, insn, live);
		  continue;
		}

	      /* If not all recorded refs can be adjusted, or the
		 adjustment is now too large for a constant addition,
		 we cannot merge the two stack adjustments.

		 Also we need to be careful to not move stack pointer
		 such that we create stack accesses outside the allocated
		 area.  We can combine an allocation into the first insn,
		 or a deallocation into the second insn.  We cannot
		 combine an allocation followed by a deallocation.

		 The only somewhat frequent occurrence of the later is when
		 a function allocates a stack frame but does not use it.
		 For this case, we would need to analyze rtl stream to be
		 sure that allocated area is really unused.  This means not
		 only checking the memory references, but also all registers
		 or global memory references possibly containing a stack
		 frame address.

		 Perhaps the best way to address this problem is to teach
		 gcc not to allocate stack for objects never used.  */

	      /* Combine an allocation into the first instruction.  */
	      if (STACK_GROWS_DOWNWARD ? this_adjust <= 0 : this_adjust >= 0)
		{
		  if (no_unhandled_cfa (insn)
		      && try_apply_stack_adjustment (last_sp_set, reflist,
						     last_sp_adjust
						     + this_adjust,
						     this_adjust,
						     last_sp_live,
						     insn))
		    {
		      /* It worked!  */
		      maybe_move_args_size_note (last_sp_set, insn, false);
		      maybe_merge_cfa_adjust (last_sp_set, insn, false);
		      delete_insn (insn);
		      last_sp_adjust += this_adjust;
		      last_sp_live = NULL;
		      continue;
		    }
		}

	      /* Otherwise we have a deallocation.  Do not combine with
		 a previous allocation.  Combine into the second insn.  */
	      else if (STACK_GROWS_DOWNWARD
		       ? last_sp_adjust >= 0 : last_sp_adjust <= 0)
		{
		  if (no_unhandled_cfa (last_sp_set)
		      && !REG_P (src)
		      && try_apply_stack_adjustment (insn, reflist,
						     last_sp_adjust
						     + this_adjust,
						     -last_sp_adjust,
						     NULL, NULL))
		    {
		      /* It worked!  */
		      maybe_move_args_size_note (insn, last_sp_set, true);
		      maybe_merge_cfa_adjust (insn, last_sp_set, true);
		      delete_insn (last_sp_set);
		      last_sp_set = insn;
		      last_sp_adjust += this_adjust;
		      last_sp_live = NULL;
		      free_csa_reflist (reflist);
		      reflist = NULL;
		      df_simulate_one_insn_forwards (bb, insn, live);
		      continue;
		    }
		}

	      /* Combination failed.  Restart processing from here.  If
		 deallocation+allocation conspired to cancel, we can
		 delete the old deallocation insn.  */
	      if (last_sp_set)
		{
		  if (last_sp_adjust == 0 && no_unhandled_cfa (last_sp_set))
		    {
		      maybe_move_args_size_note (insn, last_sp_set, true);
		      maybe_merge_cfa_adjust (insn, last_sp_set, true);
		      delete_insn (last_sp_set);
		    }
		  else
		    last2_sp_set = last_sp_set;
		}
	      free_csa_reflist (reflist);
	      reflist = NULL;
	      last_sp_set = insn;
	      last_sp_adjust = this_adjust;
	      if (REG_P (src))
		{
		  if (copy == NULL)
		    copy = BITMAP_ALLOC (&reg_obstack);
		  last_sp_live = copy;
		  bitmap_copy (last_sp_live, live);
		}
	      else
		last_sp_live = NULL;
	      df_simulate_one_insn_forwards (bb, insn, live);
	      continue;
	    }

	  /* Find a store with pre-(dec|inc)rement or pre-modify of exactly
	     the previous adjustment and turn it into a simple store.  This
	     is equivalent to anticipating the stack adjustment so this must
	     be an allocation.  */
	  if (MEM_P (dest)
	      && ((STACK_GROWS_DOWNWARD
		   ? (GET_CODE (XEXP (dest, 0)) == PRE_DEC
		      && known_eq (last_sp_adjust,
				   GET_MODE_SIZE (GET_MODE (dest))))
		   : (GET_CODE (XEXP (dest, 0)) == PRE_INC
		      && known_eq (-last_sp_adjust,
				   GET_MODE_SIZE (GET_MODE (dest)))))
		  || ((STACK_GROWS_DOWNWARD
		       ? last_sp_adjust >= 0 : last_sp_adjust <= 0)
		      && GET_CODE (XEXP (dest, 0)) == PRE_MODIFY
		      && GET_CODE (XEXP (XEXP (dest, 0), 1)) == PLUS
		      && XEXP (XEXP (XEXP (dest, 0), 1), 0)
			 == stack_pointer_rtx
		      && GET_CODE (XEXP (XEXP (XEXP (dest, 0), 1), 1))
		         == CONST_INT
		      && INTVAL (XEXP (XEXP (XEXP (dest, 0), 1), 1))
		         == -last_sp_adjust))
	      && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx
	      && !reg_mentioned_p (stack_pointer_rtx, src)
	      && memory_address_p (GET_MODE (dest), stack_pointer_rtx)
	      && try_apply_stack_adjustment (insn, reflist, 0,
					     -last_sp_adjust,
					     NULL, NULL))
	    {
	      if (last2_sp_set)
		maybe_move_args_size_note (last2_sp_set, last_sp_set, false);
	      else
	        maybe_move_args_size_note (insn, last_sp_set, true);
	      delete_insn (last_sp_set);
	      free_csa_reflist (reflist);
	      reflist = NULL;
	      last_sp_set = NULL;
	      last_sp_adjust = 0;
	      last_sp_live = NULL;
	      df_simulate_one_insn_forwards (bb, insn, live);
	      continue;
	    }
	}

      if (!CALL_P (insn) && last_sp_set && record_stack_refs (insn, &reflist))
	{
	  df_simulate_one_insn_forwards (bb, insn, live);
	  continue;
	}

      /* Otherwise, we were not able to process the instruction.
	 Do not continue collecting data across such a one.  */
      if (last_sp_set
	  && (CALL_P (insn)
	      || reg_mentioned_p (stack_pointer_rtx, PATTERN (insn))))
	{
	  if (last_sp_set && last_sp_adjust == 0)
	    {
	      force_move_args_size_note (bb, last2_sp_set, last_sp_set);
	      delete_insn (last_sp_set);
	    }
	  free_csa_reflist (reflist);
	  reflist = NULL;
	  last2_sp_set = NULL;
	  last_sp_set = NULL;
	  last_sp_adjust = 0;
	  last_sp_live = NULL;
	}

      df_simulate_one_insn_forwards (bb, insn, live);
    }

  if (last_sp_set && last_sp_adjust == 0)
    {
      force_move_args_size_note (bb, last2_sp_set, last_sp_set);
      delete_insn (last_sp_set);
    }

  if (reflist)
    free_csa_reflist (reflist);
  if (copy)
    BITMAP_FREE (copy);
}

static unsigned int
rest_of_handle_stack_adjustments (void)
{
  df_note_add_problem ();
  df_analyze ();
  combine_stack_adjustments ();
  return 0;
}

namespace {

const pass_data pass_data_stack_adjustments =
{
  RTL_PASS, /* type */
  "csa", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_COMBINE_STACK_ADJUST, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_df_finish, /* todo_flags_finish */
};

class pass_stack_adjustments : public rtl_opt_pass
{
public:
  pass_stack_adjustments (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_stack_adjustments, ctxt)
  {}

  /* opt_pass methods: */
  bool gate (function *) final override;
  unsigned int execute (function *) final override
    {
      return rest_of_handle_stack_adjustments ();
    }

}; // class pass_stack_adjustments

bool
pass_stack_adjustments::gate (function *)
{
  /* This is kind of a heuristic.  We need to run combine_stack_adjustments
     even for machines with possibly nonzero TARGET_RETURN_POPS_ARGS
     and ACCUMULATE_OUTGOING_ARGS.  We expect that only ports having
     push instructions will have popping returns.  */
#ifndef PUSH_ROUNDING
  if (ACCUMULATE_OUTGOING_ARGS)
    return false;
#endif
  return flag_combine_stack_adjustments;
}

} // anon namespace

rtl_opt_pass *
make_pass_stack_adjustments (gcc::context *ctxt)
{
  return new pass_stack_adjustments (ctxt);
}
