This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix for PR/6552


This affects only Ada:

2003-11-14  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* function.c (struct epi_info): New field const_equiv.
	(update_epilogue_consts): New function.
	(keep_stack_depressed): Clear new field and verify scratch register
	doesn't have it set.
	Call new function via note_stores.
	(handle_epilogue_set): Allow setting SP equiv reg in different mode.
	Allow PLUS where second operand is register known set to constant.
	(emit_equiv_load): Write load using proper mode if source different.
	* config/mips/mips.md (return_internal): Put (return) first.

*** function.c	12 Nov 2003 02:10:12 -0000	1.466
--- function.c	14 Nov 2003 17:21:56 -0000
*************** struct epi_info
*** 7297,7303 ****
--- 7297,7306 ----
  				   should be set to once we no longer need
  				   its value.  */
+   rtx const_equiv[FIRST_PSEUDO_REGISTER]; /* Any known constant equivalences
+ 					     for registers.  */
  };
  
  static void handle_epilogue_set (rtx, struct epi_info *);
+ static void update_epilogue_consts PARAMS ((rtx, rtx, void *));
  static void emit_equiv_load (struct epi_info *);
  
*************** keep_stack_depressed (rtx insns)
*** 7312,7317 ****
    rtx insn, next;
  
!   /* If the epilogue is just a single instruction, it ust be OK as is.  */
! 
    if (NEXT_INSN (insns) == NULL_RTX)
      return insns;
--- 7315,7319 ----
    rtx insn, next;
  
!   /* If the epilogue is just a single instruction, it must be OK as is.  */
    if (NEXT_INSN (insns) == NULL_RTX)
      return insns;
*************** keep_stack_depressed (rtx insns)
*** 7325,7328 ****
--- 7327,7333 ----
    info.equiv_reg_src = 0;
  
+   for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
+     info.const_equiv[j] = 0;
+ 
    insn = insns;
    next = NULL_RTX;
*************** keep_stack_depressed (rtx insns)
*** 7416,7420 ****
  					   regno + HARD_REGNO_NREGS (regno,
  								     Pmode),
! 					   info.equiv_reg_src, NULL))
  		  break;
  
--- 7421,7426 ----
  					   regno + HARD_REGNO_NREGS (regno,
  								     Pmode),
! 					   info.equiv_reg_src, NULL)
! 		    && info.const_equiv[regno] == 0)
  		  break;
  
*************** keep_stack_depressed (rtx insns)
*** 7472,7475 ****
--- 7478,7483 ----
        info.sp_offset = info.new_sp_offset;
  
+       /* Now update any constants this insn sets.  */
+       note_stores (PATTERN (insn), update_epilogue_consts, &info);
        insn = next;
      }
*************** handle_epilogue_set (rtx set, struct epi
*** 7495,7503 ****
  	abort ();
  
!       if (GET_CODE (SET_SRC (set)) == PLUS
! 	  && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
  	{
  	  p->new_sp_equiv_reg = XEXP (SET_SRC (set), 0);
! 	  p->new_sp_offset = INTVAL (XEXP (SET_SRC (set), 1));
  	}
        else
--- 7503,7518 ----
  	abort ();
  
!       if (GET_CODE (SET_SRC (set)) == PLUS)
  	{
  	  p->new_sp_equiv_reg = XEXP (SET_SRC (set), 0);
! 	  if (GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
! 	    p->new_sp_offset = INTVAL (XEXP (SET_SRC (set), 1));
! 	  else if (GET_CODE (XEXP (SET_SRC (set), 1)) == REG
! 		   && REGNO (XEXP (SET_SRC (set), 1)) < FIRST_PSEUDO_REGISTER
! 		   && p->const_equiv[REGNO (XEXP (SET_SRC (set), 1))] != 0)
! 	    p->new_sp_offset
! 	      = INTVAL (p->const_equiv[REGNO (XEXP (SET_SRC (set), 1))]);
! 	  else
! 	    abort ();
  	}
        else
*************** handle_epilogue_set (rtx set, struct epi
*** 7522,7530 ****
       to allow for the case where we are setting the register set in
       the previous part of a PARALLEL inside a single insn.  But use the
!      old offset for any updates within this insn.  */
    else if (p->new_sp_equiv_reg != 0 && reg_set_p (p->new_sp_equiv_reg, set))
      {
!       if (!rtx_equal_p (p->new_sp_equiv_reg, SET_DEST (set))
! 	  || p->equiv_reg_src != 0)
  	abort ();
        else
--- 7537,7550 ----
       to allow for the case where we are setting the register set in
       the previous part of a PARALLEL inside a single insn.  But use the
!      old offset for any updates within this insn.  We must allow for the case
!      where the register is being set in a different (usually wider) mode than
!      Pmode).  */
    else if (p->new_sp_equiv_reg != 0 && reg_set_p (p->new_sp_equiv_reg, set))
      {
!       if (p->equiv_reg_src != 0
! 	  || GET_CODE (p->new_sp_equiv_reg) != REG
! 	  || GET_CODE (SET_DEST (set)) != REG
! 	  || GET_MODE_BITSIZE (GET_MODE (SET_DEST (set))) > BITS_PER_WORD
! 	  || REGNO (p->new_sp_equiv_reg) != REGNO (SET_DEST (set)))
  	abort ();
        else
*************** handle_epilogue_set (rtx set, struct epi
*** 7549,7552 ****
--- 7569,7588 ----
  }
  
+ /* Update the tracking information for registers set to constants.  */
+ 
+ static void
+ update_epilogue_consts (rtx dest, rtx x, void *data)
+ {
+   struct epi_info *p = (struct epi_info *) data;
+ 
+   if (GET_CODE (dest) != REG || REGNO (dest) >= FIRST_PSEUDO_REGISTER)
+     return;
+   else if (GET_CODE (x) == CLOBBER || ! rtx_equal_p (dest, SET_DEST (x))
+ 	   || GET_CODE (SET_SRC (x)) != CONST_INT)
+     p->const_equiv[REGNO (dest)] = 0;
+   else
+     p->const_equiv[REGNO (dest)] = SET_SRC (x);
+ }
+ 
  /* Emit an insn to do the load shown in p->equiv_reg_src, if needed.  */
  
*************** emit_equiv_load (struct epi_info *p)
*** 7555,7561 ****
  {
    if (p->equiv_reg_src != 0)
!     emit_move_insn (p->sp_equiv_reg, p->equiv_reg_src);
  
!   p->equiv_reg_src = 0;
  }
  #endif
--- 7591,7604 ----
  {
    if (p->equiv_reg_src != 0)
!     {
!       rtx dest = p->sp_equiv_reg;
! 
!       if (GET_MODE (p->equiv_reg_src) != GET_MODE (dest))
! 	dest = gen_rtx_REG (GET_MODE (p->equiv_reg_src),
! 			    REGNO (p->sp_equiv_reg));
  
!       emit_move_insn (dest, p->equiv_reg_src);
!       p->equiv_reg_src = 0;
!     }
  }
  #endif
*** config/mips/mips.md	7 Nov 2003 08:14:32 -0000	1.208
--- config/mips/mips.md	14 Nov 2003 17:25:40 -0000
*************** ld\t%2,%1-%S1(%2)\;daddu\t%2,%2,$31\;%*j
*** 8250,8255 ****
  
  (define_insn "return_internal"
!   [(use (match_operand 0 "pmode_register_operand" ""))
!    (return)]
    ""
    "%*j\t%0%/"
--- 8250,8255 ----
  
  (define_insn "return_internal"
!   [(return)
!    (use (match_operand 0 "pmode_register_operand" ""))]
    ""
    "%*j\t%0%/"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]