diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 299eb4c0caff713dafdef36c26a46210f530ff41..613a300904bf2cf2eb63a48be03e9a7df3bbf7b4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2005-12-03  Alan Modra  <amodra@bigpond.net.au>
+
+	* config/rs6000/rs6000.c (rs6000_stack_t): Remove toc_save_p,
+	toc_save_offset, toc_size, lr_size.
+	(rs6000_stack_info): Use memset rather than bss struct copy to init.
+	Test rs6000_ra_ever_killed last in condition setting lr_save_p.
+	Adjust for removal of unused rs6000_stack_t fields.
+	(debug_stack_info): Adjust.
+	(rs6000_ra_ever_killed): Expand FIND_REG_INC_NOTE.  Test for calls
+	first, and don't bother checking for set/inc of lr on sibcalls.
+	(rs6000_emit_epilogue): Tidy code restoring stack pointer.
+
 2005-12-02  Jakub Jelinek  <jakub@redhat.com>
 
 	PR target/25199
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index c3fa81aea2e29cb41ad88b450259d1fd3d67c3c8..30007531e6fa63abc0cef30096c687fcb1e3fb53 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -77,7 +77,6 @@ typedef struct rs6000_stack {
   int lr_save_p;		/* true if the link reg needs to be saved */
   int cr_save_p;		/* true if the CR reg needs to be saved */
   unsigned int vrsave_mask;	/* mask of vec registers to save */
-  int toc_save_p;		/* true if the TOC needs to be saved */
   int push_p;			/* true if we need to allocate stack space */
   int calls_p;			/* true if the function makes any calls */
   int world_save_p;		/* true if we're saving *everything*:
@@ -90,7 +89,6 @@ typedef struct rs6000_stack {
   int cr_save_offset;		/* offset to save CR from initial SP */
   int vrsave_save_offset;	/* offset to save VRSAVE from initial SP */
   int spe_gp_save_offset;	/* offset to save spe 64-bit gprs  */
-  int toc_save_offset;		/* offset to save the TOC pointer */
   int varargs_save_offset;	/* offset to save the varargs registers */
   int ehrd_offset;		/* offset to EH return data */
   int reg_size;			/* register size (4 or 8) */
@@ -102,13 +100,11 @@ typedef struct rs6000_stack {
   int fp_size;			/* size of saved FP registers */
   int altivec_size;		/* size of saved AltiVec registers */
   int cr_size;			/* size to hold CR if not in save_size */
-  int lr_size;			/* size to hold LR if not in save_size */
   int vrsave_size;		/* size to hold VRSAVE if not in save_size */
   int altivec_padding_size;	/* size of altivec alignment padding if
 				   not in save_size */
   int spe_gp_size;		/* size of 64-bit GPR save size for SPE */
   int spe_padding_size;
-  int toc_size;			/* size to hold TOC if not in save_size */
   HOST_WIDE_INT total_size;	/* total bytes allocated for stack */
   int spe_64bit_regs_used;
 } rs6000_stack_t;
@@ -12672,15 +12668,14 @@ is_altivec_return_reg (rtx reg, void *xyes)
 static rs6000_stack_t *
 rs6000_stack_info (void)
 {
-  static rs6000_stack_t info, zero_info;
+  static rs6000_stack_t info;
   rs6000_stack_t *info_ptr = &info;
   int reg_size = TARGET_32BIT ? 4 : 8;
   int ehrd_size;
   int save_align;
   HOST_WIDE_INT non_fixed_size;
 
-  /* Zero all fields portably.  */
-  info = zero_info;
+  memset (&info, 0, sizeof (info));
 
   if (TARGET_SPE)
     {
@@ -12733,10 +12728,9 @@ rs6000_stack_info (void)
 		       || cfun->machine->ra_needs_full_frame);
 
   /* Determine if we need to save the link register.  */
-  if (rs6000_ra_ever_killed ()
-      || (DEFAULT_ABI == ABI_AIX
-	  && current_function_profile
-	  && !TARGET_PROFILE_KERNEL)
+  if ((DEFAULT_ABI == ABI_AIX
+       && current_function_profile
+       && !TARGET_PROFILE_KERNEL)
 #ifdef TARGET_RELOCATABLE
       || (TARGET_RELOCATABLE && (get_pool_size () != 0))
 #endif
@@ -12744,7 +12738,8 @@ rs6000_stack_info (void)
 	  && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
       || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
       || (DEFAULT_ABI == ABI_V4 && current_function_calls_alloca)
-      || info_ptr->calls_p)
+      || info_ptr->calls_p
+      || rs6000_ra_ever_killed ())
     {
       info_ptr->lr_save_p = 1;
       regs_ever_live[LINK_REGISTER_REGNUM] = 1;
@@ -12867,8 +12862,7 @@ rs6000_stack_info (void)
 	    - info_ptr->spe_gp_size;
 
 	  /* Adjust for SPE case.  */
-	  info_ptr->toc_save_offset
-	    = info_ptr->spe_gp_save_offset - info_ptr->toc_size;
+	  info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
 	}
       else if (TARGET_ALTIVEC_ABI)
 	{
@@ -12888,12 +12882,11 @@ rs6000_stack_info (void)
 	    - info_ptr->altivec_size;
 
 	  /* Adjust for AltiVec case.  */
-	  info_ptr->toc_save_offset
-	    = info_ptr->altivec_save_offset - info_ptr->toc_size;
+	  info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
 	}
       else
-	info_ptr->toc_save_offset  = info_ptr->cr_save_offset - info_ptr->toc_size;
-      info_ptr->ehrd_offset      = info_ptr->toc_save_offset - ehrd_size;
+	info_ptr->ehrd_offset    = info_ptr->cr_save_offset;
+      info_ptr->ehrd_offset      -= ehrd_size;
       info_ptr->lr_save_offset   = reg_size;
       break;
     }
@@ -12907,9 +12900,7 @@ rs6000_stack_info (void)
 					 + info_ptr->spe_padding_size
 					 + ehrd_size
 					 + info_ptr->cr_size
-					 + info_ptr->lr_size
-					 + info_ptr->vrsave_size
-					 + info_ptr->toc_size,
+					 + info_ptr->vrsave_size,
 					 save_align);
 
   non_fixed_size	 = (info_ptr->vars_size
@@ -12970,9 +12961,6 @@ rs6000_stack_info (void)
   if (! info_ptr->cr_save_p)
     info_ptr->cr_save_offset = 0;
 
-  if (! info_ptr->toc_save_p)
-    info_ptr->toc_save_offset = 0;
-
   return info_ptr;
 }
 
@@ -13068,9 +13056,6 @@ debug_stack_info (rs6000_stack_t *info)
   if (info->cr_save_p)
     fprintf (stderr, "\tcr_save_p           = %5d\n", info->cr_save_p);
 
-  if (info->toc_save_p)
-    fprintf (stderr, "\ttoc_save_p          = %5d\n", info->toc_save_p);
-
   if (info->vrsave_mask)
     fprintf (stderr, "\tvrsave_mask         = 0x%x\n", info->vrsave_mask);
 
@@ -13104,9 +13089,6 @@ debug_stack_info (rs6000_stack_t *info)
   if (info->cr_save_offset)
     fprintf (stderr, "\tcr_save_offset      = %5d\n", info->cr_save_offset);
 
-  if (info->toc_save_offset)
-    fprintf (stderr, "\ttoc_save_offset     = %5d\n", info->toc_save_offset);
-
   if (info->varargs_save_offset)
     fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
 
@@ -13147,15 +13129,9 @@ debug_stack_info (rs6000_stack_t *info)
     fprintf (stderr, "\tspe_padding_size    = %5d\n",
 	     info->spe_padding_size);
 
-  if (info->lr_size)
-    fprintf (stderr, "\tlr_size             = %5d\n", info->lr_size);
-
   if (info->cr_size)
     fprintf (stderr, "\tcr_size             = %5d\n", info->cr_size);
 
-  if (info->toc_size)
-    fprintf (stderr, "\ttoc_size            = %5d\n", info->toc_size);
-
   if (info->save_size)
     fprintf (stderr, "\tsave_size           = %5d\n", info->save_size);
 
@@ -13278,10 +13254,12 @@ rs6000_ra_ever_killed (void)
     {
       if (INSN_P (insn))
 	{
-	  if (FIND_REG_INC_NOTE (insn, reg))
-	    return 1;
-	  else if (GET_CODE (insn) == CALL_INSN
-		   && !SIBLING_CALL_P (insn))
+	  if (CALL_P (insn))
+	    {
+	      if (!SIBLING_CALL_P (insn))
+		return 1;
+	    }
+	  else if (find_regno_note (insn, REG_INC, LINK_REGISTER_REGNUM))
 	    return 1;
 	  else if (set_of (reg, insn) != NULL_RTX
 		   && !prologue_epilogue_contains (insn))
@@ -14713,7 +14691,6 @@ rs6000_emit_epilogue (int sibcall)
 
       emit_move_insn (frame_reg_rtx,
 		      gen_rtx_MEM (Pmode, sp_reg_rtx));
-
     }
   else if (info->push_p)
     {
@@ -14947,30 +14924,20 @@ rs6000_emit_epilogue (int sibcall)
     }
 
   /* If this is V.4, unwind the stack pointer after all of the loads
-     have been done.  We need to emit a block here so that sched
-     doesn't decide to move the sp change before the register restores
-     (which may not have any obvious dependency on the stack).  This
-     doesn't hurt performance, because there is no scheduling that can
-     be done after this point.  */
-  if (DEFAULT_ABI == ABI_V4
-      || current_function_calls_eh_return)
-    {
-      if (frame_reg_rtx != sp_reg_rtx)
-	rs6000_emit_stack_tie ();
-
-      if (use_backchain_to_restore_sp)
-	{
-	  emit_move_insn (sp_reg_rtx, frame_reg_rtx);
-	}
-      else if (sp_offset != 0)
-	{
-	  emit_insn (TARGET_32BIT
-		     ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
-				   GEN_INT (sp_offset))
-		     : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
-				   GEN_INT (sp_offset)));
-	}
-    }
+     have been done.  */
+  if (frame_reg_rtx != sp_reg_rtx)
+    {
+      /* This blockage is needed so that sched doesn't decide to move
+	 the sp change before the register restores.  */
+      rs6000_emit_stack_tie ();
+      emit_move_insn (sp_reg_rtx, frame_reg_rtx);
+    }
+  else if (sp_offset != 0)
+    emit_insn (TARGET_32BIT
+	       ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
+			     GEN_INT (sp_offset))
+	       : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
+			     GEN_INT (sp_offset)));
 
   if (current_function_calls_eh_return)
     {