--- gcc/hard-reg-set.h.jj	2011-11-28 17:58:04.000000000 +0100
+++ gcc/hard-reg-set.h	2012-01-16 17:27:35.837610779 +0100
@@ -54,6 +54,14 @@ typedef HARD_REG_ELT_TYPE HARD_REG_SET[H
 
 #endif
 
+/* HARD_REG_SET wrapped into a structure, to make it possible to
+   use HARD_REG_SET even in APIs that should not include
+   hard-reg-set.h.  */
+struct hard_reg_set_container
+{
+  HARD_REG_SET set;
+};
+
 /* HARD_CONST is used to cast a constant to the appropriate type
    for use with a HARD_REG_SET.  */
 
--- gcc/target.h.jj	2011-06-17 11:02:19.000000000 +0200
+++ gcc/target.h	2012-01-16 17:28:13.348394331 +0100
@@ -92,6 +92,7 @@ extern bool target_default_pointer_addre
 
 struct stdarg_info;
 struct spec_info_def;
+struct hard_reg_set_container;
 
 /* The struct used by the secondary_reload target hook.  */
 typedef struct secondary_reload_info
--- gcc/target.def.jj	2011-12-27 11:39:49.000000000 +0100
+++ gcc/target.def	2012-01-16 19:51:00.171464193 +0100
@@ -2644,6 +2644,14 @@ DEFHOOK
  void, (bitmap regs),
  hook_void_bitmap)
 
+/* Fill in additional registers set up by prologue into a regset.  */
+DEFHOOK
+(set_up_by_prologue,
+ "This hook should add additional registers that are computed by the prologue\
+ to the hard regset for shrink-wrapping optimization purposes.",
+ void, (struct hard_reg_set_container *),
+ NULL)
+
 /* Determine the type of unwind info to emit for debugging.  */
 DEFHOOK
 (debug_unwind_info,
--- gcc/doc/tm.texi.jj	2011-12-27 11:39:47.000000000 +0100
+++ gcc/doc/tm.texi	2012-01-16 19:51:59.000000000 +0100
@@ -4959,6 +4959,10 @@ TARGET_STRUCT_VALUE_RTX, FRAME_POINTER_R
 FRAME_POINTER_REGNUM, ARG_POINTER_REGNUM, and the PIC_OFFSET_TABLE_REGNUM.
 @end deftypefn
 
+@deftypefn {Target Hook} void TARGET_SET_UP_BY_PROLOGUE (struct hard_reg_set_container *@var{})
+This hook should add additional registers that are computed by the prologue to the hard regset for shrink-wrapping optimization purposes.
+@end deftypefn
+
 @node Stack Smashing Protection
 @subsection Stack smashing protection
 @cindex stack smashing protection
--- gcc/doc/tm.texi.in.jj	2011-12-27 11:39:47.000000000 +0100
+++ gcc/doc/tm.texi.in	2012-01-16 19:51:38.531284609 +0100
@@ -4906,6 +4906,8 @@ TARGET_STRUCT_VALUE_RTX, FRAME_POINTER_R
 FRAME_POINTER_REGNUM, ARG_POINTER_REGNUM, and the PIC_OFFSET_TABLE_REGNUM.
 @end deftypefn
 
+@hook TARGET_SET_UP_BY_PROLOGUE
+
 @node Stack Smashing Protection
 @subsection Stack smashing protection
 @cindex stack smashing protection
--- gcc/function.c.jj	2012-01-13 21:47:35.000000000 +0100
+++ gcc/function.c	2012-01-16 17:42:49.485331902 +0100
@@ -5899,7 +5899,7 @@ thread_prologue_and_epilogue_insns (void
       && nonempty_prologue && !crtl->calls_eh_return)
     {
       HARD_REG_SET prologue_clobbered, prologue_used, live_on_edge;
-      HARD_REG_SET set_up_by_prologue;
+      struct hard_reg_set_container set_up_by_prologue;
       rtx p_insn;
       VEC(basic_block, heap) *vec;
       basic_block bb;
@@ -5939,18 +5939,22 @@ thread_prologue_and_epilogue_insns (void
 
       vec = VEC_alloc (basic_block, heap, n_basic_blocks);
 
-      CLEAR_HARD_REG_SET (set_up_by_prologue);
-      add_to_hard_reg_set (&set_up_by_prologue, Pmode, STACK_POINTER_REGNUM);
-      add_to_hard_reg_set (&set_up_by_prologue, Pmode, ARG_POINTER_REGNUM);
+      CLEAR_HARD_REG_SET (set_up_by_prologue.set);
+      add_to_hard_reg_set (&set_up_by_prologue.set, Pmode,
+			   STACK_POINTER_REGNUM);
+      add_to_hard_reg_set (&set_up_by_prologue.set, Pmode, ARG_POINTER_REGNUM);
       if (frame_pointer_needed)
-	add_to_hard_reg_set (&set_up_by_prologue, Pmode,
+	add_to_hard_reg_set (&set_up_by_prologue.set, Pmode,
 			     HARD_FRAME_POINTER_REGNUM);
       if (pic_offset_table_rtx)
-	add_to_hard_reg_set (&set_up_by_prologue, Pmode,
+	add_to_hard_reg_set (&set_up_by_prologue.set, Pmode,
 			     PIC_OFFSET_TABLE_REGNUM);
       if (stack_realign_drap && crtl->drap_reg)
-	add_to_hard_reg_set (&set_up_by_prologue, GET_MODE (crtl->drap_reg),
+	add_to_hard_reg_set (&set_up_by_prologue.set,
+			     GET_MODE (crtl->drap_reg),
 			     REGNO (crtl->drap_reg));
+      if (targetm.set_up_by_prologue)
+	targetm.set_up_by_prologue (&set_up_by_prologue);
 
       /* We don't use a different max size depending on
 	 optimize_bb_for_speed_p because increasing shrink-wrapping
@@ -5968,7 +5972,7 @@ thread_prologue_and_epilogue_insns (void
 	    if (NONDEBUG_INSN_P (insn))
 	      {
 		if (requires_stack_frame_p (insn, prologue_used,
-					    set_up_by_prologue))
+					    set_up_by_prologue.set))
 		  {
 		    if (bb == entry_edge->dest)
 		      goto fail_shrinkwrap;
--- gcc/config/rs6000/rs6000.c.jj	2012-01-13 21:47:35.000000000 +0100
+++ gcc/config/rs6000/rs6000.c	2012-01-16 18:01:04.615010096 +0100
@@ -1227,6 +1227,7 @@ static bool rs6000_cannot_force_const_me
 static bool rs6000_legitimate_constant_p (enum machine_mode, rtx);
 static bool rs6000_save_toc_in_prologue_p (void);
 static void rs6000_code_end (void) ATTRIBUTE_UNUSED;
+static void rs6000_set_up_by_prologue (struct hard_reg_set_container *);
 
 /* Hash table stuff for keeping track of TOC entries.  */
 
@@ -1392,6 +1393,9 @@ static const struct attribute_spec rs600
 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
 #endif
 
+#undef TARGET_SET_UP_BY_PROLOGUE
+#define TARGET_SET_UP_BY_PROLOGUE rs6000_set_up_by_prologue
+
 #undef TARGET_HAVE_TLS
 #define TARGET_HAVE_TLS HAVE_AS_TLS
 
@@ -27903,6 +27907,19 @@ rs6000_code_end (void)
   current_function_decl = NULL;
 }
 
+/* Add r30 to hard reg set if the prologue sets it up and it is not
+   pic_offset_table_rtx.  */
+
+static void
+rs6000_set_up_by_prologue (struct hard_reg_set_container *set)
+{
+  if (!TARGET_SINGLE_PIC_BASE
+      && TARGET_TOC
+      && TARGET_MINIMAL_TOC
+      && get_pool_size () != 0)
+    add_to_hard_reg_set (&set->set, Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
+}
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-rs6000.h"
