View | Details | Return to bug 49864 | Differences between
and this patch

Collapse All | Expand All

(-)a/gcc/cfgcleanup.c (-5 / +14 lines)
Lines 1081-1091 old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2) Link Here
1081
  /* ??? Do not allow cross-jumping between different stack levels.  */
1081
  /* ??? Do not allow cross-jumping between different stack levels.  */
1082
  p1 = find_reg_note (i1, REG_ARGS_SIZE, NULL);
1082
  p1 = find_reg_note (i1, REG_ARGS_SIZE, NULL);
1083
  p2 = find_reg_note (i2, REG_ARGS_SIZE, NULL);
1083
  p2 = find_reg_note (i2, REG_ARGS_SIZE, NULL);
1084
  if (p1)
1084
  if (p1 && p2)
1085
    p1 = XEXP (p1, 0);
1085
    {
1086
  if (p2)
1086
      p1 = XEXP (p1, 0);
1087
    p2 = XEXP (p2, 0);
1087
      p2 = XEXP (p2, 0);
1088
  if (!rtx_equal_p (p1, p2))
1088
      if (!rtx_equal_p (p1, p2))
1089
        return dir_none;
1090
1091
      /* ??? Worse, this adjustment had better be constant lest we
1092
         have differing incoming stack levels.  */
1093
      if (!frame_pointer_needed
1094
          && find_args_size_adjust (i1) == HOST_WIDE_INT_MIN)
1095
	return dir_none;
1096
    }
1097
  else if (p1 || p2)
1089
    return dir_none;
1098
    return dir_none;
1090
1099
1091
  p1 = PATTERN (i1);
1100
  p1 = PATTERN (i1);
(-)a/gcc/expr.c (-110 / +119 lines)
Lines 3548-3553 mem_autoinc_base (rtx mem) Link Here
3548
   verified, via immediate operand or auto-inc.  If the adjustment
3548
   verified, via immediate operand or auto-inc.  If the adjustment
3549
   cannot be trivially extracted, the return value is INT_MIN.  */
3549
   cannot be trivially extracted, the return value is INT_MIN.  */
3550
3550
3551
HOST_WIDE_INT
3552
find_args_size_adjust (rtx insn)
3553
{
3554
  rtx dest, set, pat;
3555
  int i;
3556
3557
  pat = PATTERN (insn);
3558
  set = NULL;
3559
3560
  /* Look for a call_pop pattern.  */
3561
  if (CALL_P (insn))
3562
    {
3563
      /* We have to allow non-call_pop patterns for the case
3564
	 of emit_single_push_insn of a TLS address.  */
3565
      if (GET_CODE (pat) != PARALLEL)
3566
	return 0;
3567
3568
      /* All call_pop have a stack pointer adjust in the parallel.
3569
	 The call itself is always first, and the stack adjust is
3570
	 usually last, so search from the end.  */
3571
      for (i = XVECLEN (pat, 0) - 1; i > 0; --i)
3572
	{
3573
	  set = XVECEXP (pat, 0, i);
3574
	  if (GET_CODE (set) != SET)
3575
	    continue;
3576
	  dest = SET_DEST (set);
3577
	  if (dest == stack_pointer_rtx)
3578
	    break;
3579
	}
3580
      /* We'd better have found the stack pointer adjust.  */
3581
      if (i == 0)
3582
	return 0;
3583
      /* Fall through to process the extracted SET and DEST
3584
	 as if it was a standalone insn.  */
3585
    }
3586
  else if (GET_CODE (pat) == SET)
3587
    set = pat;
3588
  else if ((set = single_set (insn)) != NULL)
3589
    ;
3590
  else if (GET_CODE (pat) == PARALLEL)
3591
    {
3592
      /* ??? Some older ports use a parallel with a stack adjust
3593
	 and a store for a PUSH_ROUNDING pattern, rather than a
3594
	 PRE/POST_MODIFY rtx.  Don't force them to update yet...  */
3595
      /* ??? See h8300 and m68k, pushqi1.  */
3596
      for (i = XVECLEN (pat, 0) - 1; i >= 0; --i)
3597
	{
3598
	  set = XVECEXP (pat, 0, i);
3599
	  if (GET_CODE (set) != SET)
3600
	    continue;
3601
	  dest = SET_DEST (set);
3602
	  if (dest == stack_pointer_rtx)
3603
	    break;
3604
3605
	  /* We do not expect an auto-inc of the sp in the parallel.  */
3606
	  gcc_checking_assert (mem_autoinc_base (dest) != stack_pointer_rtx);
3607
	  gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
3608
			       != stack_pointer_rtx);
3609
	}
3610
      if (i < 0)
3611
	return 0;
3612
    }
3613
  else
3614
    return 0;
3615
3616
  dest = SET_DEST (set);
3617
3618
  /* Look for direct modifications of the stack pointer.  */
3619
  if (REG_P (dest) && REGNO (dest) == STACK_POINTER_REGNUM)
3620
    {
3621
      /* Look for a trivial adjustment, otherwise assume nothing.  */
3622
      /* Note that the SPU restore_stack_block pattern refers to
3623
	 the stack pointer in V4SImode.  Consider that non-trivial.  */
3624
      if (SCALAR_INT_MODE_P (GET_MODE (dest))
3625
	  && GET_CODE (SET_SRC (set)) == PLUS
3626
	  && XEXP (SET_SRC (set), 0) == stack_pointer_rtx
3627
	  && CONST_INT_P (XEXP (SET_SRC (set), 1)))
3628
	return INTVAL (XEXP (SET_SRC (set), 1));
3629
      /* ??? Reload can generate no-op moves, which will be cleaned
3630
	 up later.  Recognize it and continue searching.  */
3631
      else if (rtx_equal_p (dest, SET_SRC (set)))
3632
	return 0;
3633
      else
3634
	return HOST_WIDE_INT_MIN;
3635
    }
3636
  /* Otherwise only think about autoinc patterns.  */
3637
  else if (mem_autoinc_base (dest) == stack_pointer_rtx)
3638
    {
3639
      rtx addr = XEXP (dest, 0);
3640
      switch (GET_CODE (addr))
3641
	{
3642
	case PRE_INC:
3643
	case POST_INC:
3644
	  return GET_MODE_SIZE (GET_MODE (dest));
3645
	case PRE_DEC:
3646
	case POST_DEC:
3647
	  return -GET_MODE_SIZE (GET_MODE (dest));
3648
	case PRE_MODIFY:
3649
	case POST_MODIFY:
3650
	  addr = XEXP (addr, 1);
3651
	  gcc_assert (GET_CODE (addr) == PLUS);
3652
	  gcc_assert (XEXP (addr, 0) == stack_pointer_rtx);
3653
	  gcc_assert (CONST_INT_P (XEXP (addr, 1)));
3654
	  return INTVAL (XEXP (addr, 1));
3655
	default:
3656
	  gcc_unreachable ();
3657
	}
3658
    }
3659
  else
3660
    return 0;
3661
}
3662
3551
int
3663
int
3552
fixup_args_size_notes (rtx prev, rtx last, int end_args_size)
3664
fixup_args_size_notes (rtx prev, rtx last, int end_args_size)
3553
{
3665
{
Lines 3557-3678 fixup_args_size_notes (rtx prev, rtx last, int end_args_size) Link Here
3557
3669
3558
  for (insn = last; insn != prev; insn = PREV_INSN (insn))
3670
  for (insn = last; insn != prev; insn = PREV_INSN (insn))
3559
    {
3671
    {
3560
      rtx dest, set, pat;
3672
      HOST_WIDE_INT this_delta;
3561
      HOST_WIDE_INT this_delta = 0;
3562
      int i;
3563
3673
3564
      if (!NONDEBUG_INSN_P (insn))
3674
      if (!NONDEBUG_INSN_P (insn))
3565
	continue;
3675
	continue;
3566
      pat = PATTERN (insn);
3567
      set = NULL;
3568
3569
      /* Look for a call_pop pattern.  */
3570
      if (CALL_P (insn))
3571
	{
3572
          /* We have to allow non-call_pop patterns for the case
3573
	     of emit_single_push_insn of a TLS address.  */
3574
	  if (GET_CODE (pat) != PARALLEL)
3575
	    continue;
3576
3676
3577
	  /* All call_pop have a stack pointer adjust in the parallel.
3677
      this_delta = find_args_size_adjust (insn);
3578
	     The call itself is always first, and the stack adjust is
3678
      if (this_delta == 0)
3579
	     usually last, so search from the end.  */
3580
	  for (i = XVECLEN (pat, 0) - 1; i > 0; --i)
3581
	    {
3582
	      set = XVECEXP (pat, 0, i);
3583
	      if (GET_CODE (set) != SET)
3584
		continue;
3585
	      dest = SET_DEST (set);
3586
	      if (dest == stack_pointer_rtx)
3587
		break;
3588
	    }
3589
	  /* We'd better have found the stack pointer adjust.  */
3590
	  if (i == 0)
3591
	    continue;
3592
	  /* Fall through to process the extracted SET and DEST
3593
	     as if it was a standalone insn.  */
3594
	}
3595
      else if (GET_CODE (pat) == SET)
3596
	set = pat;
3597
      else if ((set = single_set (insn)) != NULL)
3598
	;
3599
      else if (GET_CODE (pat) == PARALLEL)
3600
	{
3601
	  /* ??? Some older ports use a parallel with a stack adjust
3602
	     and a store for a PUSH_ROUNDING pattern, rather than a
3603
	     PRE/POST_MODIFY rtx.  Don't force them to update yet...  */
3604
	  /* ??? See h8300 and m68k, pushqi1.  */
3605
	  for (i = XVECLEN (pat, 0) - 1; i >= 0; --i)
3606
	    {
3607
	      set = XVECEXP (pat, 0, i);
3608
	      if (GET_CODE (set) != SET)
3609
		continue;
3610
	      dest = SET_DEST (set);
3611
	      if (dest == stack_pointer_rtx)
3612
		break;
3613
3614
	      /* We do not expect an auto-inc of the sp in the parallel.  */
3615
	      gcc_checking_assert (mem_autoinc_base (dest)
3616
				   != stack_pointer_rtx);
3617
	      gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
3618
				   != stack_pointer_rtx);
3619
	    }
3620
	  if (i < 0)
3621
	    continue;
3622
	}
3623
      else
3624
	continue;
3625
      dest = SET_DEST (set);
3626
3627
      /* Look for direct modifications of the stack pointer.  */
3628
      if (REG_P (dest) && REGNO (dest) == STACK_POINTER_REGNUM)
3629
	{
3630
	  gcc_assert (!saw_unknown);
3631
	  /* Look for a trivial adjustment, otherwise assume nothing.  */
3632
	  /* Note that the SPU restore_stack_block pattern refers to
3633
	     the stack pointer in V4SImode.  Consider that non-trivial.  */
3634
	  if (SCALAR_INT_MODE_P (GET_MODE (dest))
3635
	      && GET_CODE (SET_SRC (set)) == PLUS
3636
	      && XEXP (SET_SRC (set), 0) == stack_pointer_rtx
3637
	      && CONST_INT_P (XEXP (SET_SRC (set), 1)))
3638
	    this_delta = INTVAL (XEXP (SET_SRC (set), 1));
3639
	  /* ??? Reload can generate no-op moves, which will be cleaned
3640
	     up later.  Recognize it and continue searching.  */
3641
	  else if (rtx_equal_p (dest, SET_SRC (set)))
3642
	    this_delta = 0;
3643
	  else
3644
	    saw_unknown = true;
3645
	}
3646
      /* Otherwise only think about autoinc patterns.  */
3647
      else if (mem_autoinc_base (dest) == stack_pointer_rtx)
3648
	{
3649
	  rtx addr = XEXP (dest, 0);
3650
	  gcc_assert (!saw_unknown);
3651
	  switch (GET_CODE (addr))
3652
	    {
3653
	    case PRE_INC:
3654
	    case POST_INC:
3655
	      this_delta = GET_MODE_SIZE (GET_MODE (dest));
3656
	      break;
3657
	    case PRE_DEC:
3658
	    case POST_DEC:
3659
	      this_delta = -GET_MODE_SIZE (GET_MODE (dest));
3660
	      break;
3661
	    case PRE_MODIFY:
3662
	    case POST_MODIFY:
3663
	      addr = XEXP (addr, 1);
3664
	      gcc_assert (GET_CODE (addr) == PLUS);
3665
	      gcc_assert (XEXP (addr, 0) == stack_pointer_rtx);
3666
	      gcc_assert (CONST_INT_P (XEXP (addr, 1)));
3667
	      this_delta = INTVAL (XEXP (addr, 1));
3668
	      break;
3669
	    default:
3670
	      gcc_unreachable ();
3671
	    }
3672
	}
3673
      else
3674
	continue;
3679
	continue;
3675
3680
3681
      gcc_assert (!saw_unknown);
3682
      if (this_delta == HOST_WIDE_INT_MIN)
3683
	saw_unknown = true;
3684
3676
      add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (args_size));
3685
      add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (args_size));
3677
#ifdef STACK_GROWS_DOWNWARD
3686
#ifdef STACK_GROWS_DOWNWARD
3678
      this_delta = -this_delta;
3687
      this_delta = -this_delta;
(-)a/gcc/rtl.h (+1 lines)
Lines 2508-2513 extern void emit_jump (rtx); Link Here
2508
/* In expr.c */
2508
/* In expr.c */
2509
extern rtx move_by_pieces (rtx, rtx, unsigned HOST_WIDE_INT,
2509
extern rtx move_by_pieces (rtx, rtx, unsigned HOST_WIDE_INT,
2510
			   unsigned int, int);
2510
			   unsigned int, int);
2511
extern HOST_WIDE_INT find_args_size_adjust (rtx);
2511
extern int fixup_args_size_notes (rtx, rtx, int);
2512
extern int fixup_args_size_notes (rtx, rtx, int);
2512
2513
2513
/* In cfgrtl.c */
2514
/* In cfgrtl.c */

Return to bug 49864