diff mbox

Fix powerpc64-linux -mminimal-toc shrink-wrapping bootstrap failure (PR bootstrap/51872)

Message ID 20120117101651.GD18768@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Jan. 17, 2012, 10:16 a.m. UTC
Hi!

crtbegin.o is miscompiled on powerpc64-linux with -mminimal-toc (and likely
many other sources).  The problem is that when flag_pic is 0, the
shrink-wrapping code doesn't consider register r30 being set up by the
prologue, so instructions that use r30 (TOC_REGISTER) can be considered
usable even without an earlier prologue that computes it.
Unfortunately the generic code adds just a couple of selected registers
to set_up_by_prologue regset, and I don't see without a target hook a way
to add further registers to the hard regset.

So, this patch implements such a hook and uses it on rs6000 to indicate that
r30 is computed by the prologue if the prologue does that.

Bootstrapped/regtested on powerpc64-linux (with -mminimal-toc in
CFLAGS/CXXFLAGS/etc., which previously failed to bootstrap) and on
x86_64-linux and i686-linux.  Ok for trunk?

2012-01-17  Jakub Jelinek  <jakub@redhat.com>

	PR bootstrap/51872
	* hard-reg-set.h (struct hard_reg_set_container): New type.
	* target.h (struct hard_reg_set_container): Forward declare.
	* target.def (set_up_by_prologue): New target hook.
	* doc/tm.texi (TARGET_SET_UP_BY_PROLOGUE): Document it.
	* function.c (thread_prologue_and_epilogue_insns): Change
	set_up_by_prologue HARD_REG_SET into struct hard_reg_set_container.
	Call targetm.set_up_by_prologue on it.
	* config/rs6000/rs6000.c (rs6000_set_up_by_prologue): New function.
	(TARGET_SET_UP_BY_PROLOGUE): Redefine to it.


	Jakub

Comments

David Edelsohn Jan. 17, 2012, 2:46 p.m. UTC | #1
On Tue, Jan 17, 2012 at 5:16 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> crtbegin.o is miscompiled on powerpc64-linux with -mminimal-toc (and likely
> many other sources).  The problem is that when flag_pic is 0, the
> shrink-wrapping code doesn't consider register r30 being set up by the
> prologue, so instructions that use r30 (TOC_REGISTER) can be considered
> usable even without an earlier prologue that computes it.
> Unfortunately the generic code adds just a couple of selected registers
> to set_up_by_prologue regset, and I don't see without a target hook a way
> to add further registers to the hard regset.
>
> So, this patch implements such a hook and uses it on rs6000 to indicate that
> r30 is computed by the prologue if the prologue does that.
>
> Bootstrapped/regtested on powerpc64-linux (with -mminimal-toc in
> CFLAGS/CXXFLAGS/etc., which previously failed to bootstrap) and on
> x86_64-linux and i686-linux.  Ok for trunk?
>
> 2012-01-17  Jakub Jelinek  <jakub@redhat.com>
>
>        PR bootstrap/51872
>        * hard-reg-set.h (struct hard_reg_set_container): New type.
>        * target.h (struct hard_reg_set_container): Forward declare.
>        * target.def (set_up_by_prologue): New target hook.
>        * doc/tm.texi (TARGET_SET_UP_BY_PROLOGUE): Document it.
>        * function.c (thread_prologue_and_epilogue_insns): Change
>        set_up_by_prologue HARD_REG_SET into struct hard_reg_set_container.
>        Call targetm.set_up_by_prologue on it.
>        * config/rs6000/rs6000.c (rs6000_set_up_by_prologue): New function.
>        (TARGET_SET_UP_BY_PROLOGUE): Redefine to it.

The rs6000 bits are okay with me.

Thanks, David
Richard Biener Jan. 17, 2012, 2:50 p.m. UTC | #2
On Tue, 17 Jan 2012, David Edelsohn wrote:

> On Tue, Jan 17, 2012 at 5:16 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> > Hi!
> >
> > crtbegin.o is miscompiled on powerpc64-linux with -mminimal-toc (and likely
> > many other sources).  The problem is that when flag_pic is 0, the
> > shrink-wrapping code doesn't consider register r30 being set up by the
> > prologue, so instructions that use r30 (TOC_REGISTER) can be considered
> > usable even without an earlier prologue that computes it.
> > Unfortunately the generic code adds just a couple of selected registers
> > to set_up_by_prologue regset, and I don't see without a target hook a way
> > to add further registers to the hard regset.
> >
> > So, this patch implements such a hook and uses it on rs6000 to indicate that
> > r30 is computed by the prologue if the prologue does that.
> >
> > Bootstrapped/regtested on powerpc64-linux (with -mminimal-toc in
> > CFLAGS/CXXFLAGS/etc., which previously failed to bootstrap) and on
> > x86_64-linux and i686-linux.  Ok for trunk?
> >
> > 2012-01-17  Jakub Jelinek  <jakub@redhat.com>
> >
> >        PR bootstrap/51872
> >        * hard-reg-set.h (struct hard_reg_set_container): New type.
> >        * target.h (struct hard_reg_set_container): Forward declare.
> >        * target.def (set_up_by_prologue): New target hook.
> >        * doc/tm.texi (TARGET_SET_UP_BY_PROLOGUE): Document it.
> >        * function.c (thread_prologue_and_epilogue_insns): Change
> >        set_up_by_prologue HARD_REG_SET into struct hard_reg_set_container.
> >        Call targetm.set_up_by_prologue on it.
> >        * config/rs6000/rs6000.c (rs6000_set_up_by_prologue): New function.
> >        (TARGET_SET_UP_BY_PROLOGUE): Redefine to it.
> 
> The rs6000 bits are okay with me.

The middle-end bits are ok as well.

Thanks,
Richard.
diff mbox

Patch

--- 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"